A ver si consigo dar una explicación "no académica", sin enredarme demasiado con la filosofía POO.
Las clases lo que hacen es representar "entidades" y/o conceptos del mundo real: Una persona, un coche, un hotel, una clase de alumnos, un avión, el motor de un avión, un simple tornillo del motor de un avión, un punto espacial dentro de una figura geométrica, una ecuación matemática, el texto de un libro, etc...
Para modelar estas entidades/conceptos podemos usar clases concretas, es decir, una clase que representa por completo todo lo que necesitamos modelar de una entidad.
Supón una granja de animales y queremos representar cada animal de la granja.
Tendríamos la clase
Vaca con los atributos (y sus correspondientes métodos):
Clase
Cabra
Clase
Oveja
Clase
Gallina
Clase
Caballo
Y lo mismo con todos los animales que puedan haber en una granja.
Bien, si te fijas, todos ellos tienen una serie de atributos comunes. Entonces, si vamos a tener que representar a yo que se, 50 tipos de animales distintos, pues es absurdo escribir 50 veces el código para representar los mismos atributos, además de sus métodos getter/setter.
Aquí nos interesa modelar esos atributos/métodos que son comunes en una sola clase, y hacer que el resto hereden de esta clase.
Como todas estas entidades son animales, pues haremos una clase
Animal con dichos atributos/métodos:
Y ya luego, cada clase heredará de
Animal y aportará sus atributos propios:
Vale, hasta aquí lo que hemos hecho es explicar la herencia entre clases y lo provechosa que es.
Siguiendo con la filosofía POO, ahora nos tenemos que preguntar si queremos o no, que en nuestra aplicación se puedan instanciar objetos de la clase
Animal
En las bases de datos de nuestra granja, vamos a querer trabajar directamente con
objetos Vacas, Gallinas, Ovejas,... es decir, con entidades
concretas
Sin embargo,
no vamos a querer trabajar con
objetos de clase
Animal. No nos sirve tener simplemente un "animal", sin saber si es un Caballo, una Vaca o un Ratón...
Con un simple "animal", no se en que array guardarlo ni que propiedad exclusiva tiene: ¿da leche?¿da lana?¿puede tirar de un arado?
¿Entiendes por donde voy?
Un Caballo o una Vaca, son entidades
concretas, y las puedo clasificar y operar con sus cualidades exclusivas.
Pero un Animal, es una entidad
abstracta, no la puedo clasificar y no tiene definida ninguna cualidad exclusiva con la que operar.
Esa es la diferencia entre abstracta y concreta. Una clase abstracta es como un "boceto", tiene lo primordial para representar una entidad/concepto, pero no lo suficiente para terminar de
concretar ese concepto.
Por eso, en nuestro código, la clase Animal la vamos a declarar como abstracta:
Esto sirve para que si otra persona va a utilizar nuestro código, enseguida sabrá que la clase
Animal no está pensada para trabajar con ella directamente, sino que es una entidad
abstracta de la que van a heredar otras clases
concretas.
Es más, ahora en el código, nuestro lenguaje de programación no nos va a permitir crear objetos de esa clase Animal
Mas ejemplos:
Una empresa donde sus empleados son: Contable, Informatico, Comercial, JefeSeccion, Secretario, Tesorero,...
Todas esas son entidades concretas, que nacen de una entidad abstracta:
Empleado
Un taller de reparación de vehículos trabaja con : Motocicleta, Turismo, Furgon, Camion, AutoBus,...
Son las entidades concretas, que nacen de la entidad abstracta:
Vehículo.
Un programa que dibuja figuras geométricas es capaz de representar en pantalla: Círculo, Triangulo, Rectángulo, Pentágono, Hexágono, Cubo, Prisma, Cilindro, Cono, Esfera,....
Son entidades concretas modeladas a partir de una entidad abstracta:
FiguraGeometrica
Así que como puedes ver, es muy habitual encontrar situaciones donde para representar muchas entidades concretas, podemos ahorrarnos trabajo si las creamos a partir de una entidad abstracta que modele todos los atributos comunes compartidos por esos conceptos concretos.
Espero que tanto escribir, haya servido para aclarar algo.
Un saludo.