¿Qué es una clase abstracta y por qué es importante en el diseño de software?
Una clase abstracta es una herramienta poderosa en programación orientada a objetos que nos permite definir métodos comunes para un conjunto de clases sin implementarlos. Por ejemplo, en nuestra clase Film, al declararla como abstracta y definir un método abstracto view, establecemos una estructura que todas las clases derivadas deben seguir. Esto lleva a un diseño más limpio y facilita el mantenimiento.
Las clases abstractas no se pueden instanciar directamente.
Se utilizan para definir una interfaz que otras clases pueden implementar.
Fomentan el uso de polimorfismo, permitiendo que los métodos se comporten de maneras diferentes según su implementación en subclases.
El uso de clases abstractas nos ayuda a crear un código más organizado y a reducir la redundancia, permitiendo a las subclases heredar propiedades comunes y a la vez ofrecer sus propias implementaciones específicas.
¿Cómo podemos implementar polimorfismo en clases?
El polimorfismo, una de las piedras angulares de la programación orientada a objetos, nos permite usar un mismo método en diferentes clases y obtener resultados específicos según el tipo de objeto. En el contexto de clases abstractas, el polimorfismo se implementa mediante la herencia y la sobrescritura de métodos.
Ejemplo de implementación de polimorfismo
Imaginemos que tenemos una clase abstracta Film y dos subclases, Movie y Chapter. Definimos el método view en Film y lo implementamos según sea pertinente en Movie y Chapter.
Aquí, cada vez que llamamos al método view, se ejecuta la versión correspondiente a la clase específica del objeto usado. Este es el poder del polimorfismo en clases, permitiendo tratar a los objetos de manera genérica pero obtener comportamientos específicos.
¿Qué ventajas ofrece el polimorfismo en series y capítulos?
El polimorfismo se vuelve particularmente útil cuando queremos extender funcionalidades sin alterar el código existente. Por ejemplo, al trabajar con capítulos en una serie, podemos implementar un método que revise automáticamente si todos los capítulos han sido vistos para marcar la serie completa como vista.
Implementación de una funcionalidad inteligente
En la clase Chapter, podemos utilizar un conteo para verificar cuántos capítulos han sido vistos y, una vez alcanzado el total, marcar la serie como vista.
publicclassChapterextendsMovie{privateint chapterViewItCounter =0;@Overridepublicvoidview(){super.view(); chapterViewItCounter++;if(chapterViewItCounter ==getTotalChapters()){markSeriesAsViewed();}}privateintgetTotalChapters(){// Retorna el número total de capítulos en la serie.}privatevoidmarkSeriesAsViewed(){// Lógica para marcar la serie como vista.System.out.println("Serie marcada como vista.");}}
Esta estrategia permite mantener el control del flujo del programa, asegurando que ciertas acciones se disparen automáticamente al cumplirse condiciones específicas, lo cual es una de las fuerzas del diseño orientado a objetos.
¿Cómo podemos optimizar el código usando abstracción y polimorfismo?
La clave para optimizar código es minimizar la redundancia y maximizar la reutilización. La abstracción y el polimorfismo ayudan precisamente a eso.
Reducción de Redundancia de Código: Implementamos funciones generales en clases abstractas o padres para evitar duplicaciones. Las subclases pueden heredar o sobrescribir según sea necesario.
Incremento de Reutilización: Podemos pasar objetos de diferentes tipos a través del mismo código, aprovechando la misma interfaz (por ejemplo, métodos abstractos).
Facilidad de Mantenimiento: Al tener un código más estructurado y con menos duplicados, cualquier cambio afecta a menos partes del programa, facilitando el mantenimiento y expansión.
Refactorización como ejemplo
Al mover métodos comunes a una clase abstracta o base y usar polimorfismo, reducimos la necesidad de implementar lógica repetida, como se hizo en la definición del método view tanto en Book como en Series. Animamos a los estudiantes a aplicar estos principios de abstracción y polimorfismo en sus propios proyectos, para que disfruten de un código más eficiente y organizado.
Algunos vemos el video mientras editamos nuestro proyecto y hace falta que Anncode mencione que se deben borrar los objetos (aunque si dice que no se necesitan creo que para los menos avanzados si sería necesario mencionarlo ) pequeñita observación :P
Por lo demás, excelente!
**IMPORTANTE: ** En caso que no les funcione la marcada en Visto de las Series, no se preocupen, en el próximo capitulo lo corrigen en el inicio... es llamar al método view() de la clase serie, y en el poner en vista la serie con el método setViewed(true).
Venia del curso anterior pero no habíamos creado la clase AmazonUtil, según veo en la estructura de archivos esta creada dentro de un paquete, para los que vienen del curso pasado tendremos que revisar el código y compararlo con los que esta manejando la profe para poder correr el código correctamente
Hay algo que no me está cuadrando, y es que la profesora dice que la variable film que hace referencia al objeto Movie tendrá todos los métodos de dicha clase.
Pero eso no sucede realmente, la variable film no tiene acceso a todos los métodos de Movie, solo los de Film.
tienes razón, aunque el objeto si es de la clase Movie, lo comprobé con el metodo getClass(). Pero solo tiene alcanze de las propiedades y metodos de la clase film.
Bueno e llegado hasta aca porque ella en el curso de java se o hace esta aplicacion hace una de citas meidcas no se si tiene que actualizarce o que lo baje de github pero igual para alguien nuevo que esta siguiendo esto es muy mal este tipo de enseñanza
Hola!!
Al parecer es un curso muy viejo (hace 5 años) por tanto, no se ve el de citas médicas que se trabajó en el curso anterior de 2019. Por ahora solo estoy siguiendo el curso para aprender de otros temas y formas de programar. Saludos!
Buenas tardes, después de realizar los cambios me sale el siguiente error
Exception in thread “main” java.lang.NullPointerException
at com.jhontd.amazonviewernew.Main.showChapters(Main.java:152)
at com.jhontd.amazonviewernew.Main.showSeies(Main.java:138)
at com.jhontd.amazonviewernew.Main.showMenu(Main.java:49)
at com.jhontd.amazonviewernew.Main.main(Main.java:18)
C:\Users\Usuario\AppData\Local\NetBeans\Cache\8.1\executor-snippets\run.xml:53: Java returned: 1
BUILD FAILED (total time: 40 seconds)
Sólo ocurre cuando elijo una serie, las demás opciones funcionan bien, según entiendo el error significa que un parámetro requerido está llegando null y no podría llegar así, alguien me podría indicar cómo solucionarlo? he verificado varias fuentes en internet y no logro hacer que deje de salir, agradezco la información que me puedan dar
Como se lee el error shoChapters para showSeies es nulo, revisa que la información de capítulos para ese caso sí tenga dato, corre la app en debug y está atento a que valor es el que se solicita en ese punto (en la línea 152)
Estoy en el minuto 12:37 queriendo hacer correr el programa, e seguido el curso apartir del basico y hay muchos cambios que no se hicieron en el curso basico, piden que solo clone el repo, que simon ahi lo puedo encontrar completo pero se saltaron muuuuuuuuchas cosas en la construccion que si nos estan poniendo en el repositorio y la neta es desesperante 😦
Es posible que los cambios que no veas, hayan sido los retos propuestos por Anna y no los hayas completado. Aún así puedes bajarlo tal y como lo tiene ella.
Por alguna razón tras implementar los cambios, no me da ningun error pero tras marcar todos los chapters de 1 serie como vistos la serie no se marca como vista xD, intenté copiar el código y ni aun asi _T
Al crear un objeto de la clase Film con las características de un Chapter me dí cuenta que dicho objeto no tiene acceso a los Getters y Setters de Chapter. ¿Eso quiere decir que tengo que declarar los Getters y Setters en la clase abstracta? #seMeOcurrióEnElBaño
Se supone que las clases abstractas jamas deben ser inicializadas, solamente las clases que extienden de estas. Ten en cuenta que es la clase hija la que adquiere las características de la clase padre por lo que es la hija la que puede acceder a los métodos y atributos de la clase padre mas no al revés.
Si la intensión es crear instancias de una clase abstracta procura que las clases hijas solo contengan el método, o los métodos requieren ser sobre-escritos, el resto de procesos y lógica debe estar en la clase abstracta... todo depende de la forma en que pretendas usar la clase.
Estoy revisando el código y antes de empezar a implementar los métodos abstractos se deben realizar los siguientes cambios con respecto a la última versión del proyecto de Java SE Básico o sino saldrán errores al ejecutar el método view() de Chapter.java
Chapter.java
privateSerie serie;publicChapter(String title,String genre,String creator, int duration, short year, int seasonNumber,Serie serie){super(title, genre, creator, duration, year);this.seasonNumber= seasonNumber;this.serie= serie;}publicSeriegetSerie(){return serie;}publicvoidsetSerie(Serie serie){this.serie= serie;}publicstaticArrayList<Chapter>makeChaptersList(Serie serie){ArrayList<Chapter> chapters =newArrayList<>();for(int i =1; i <=5; i++){ chapters.add(newChapter("Chapter "+ i,"Genre "+ i,"Creator "+ i,45+ i,(short)(2017+ i), i, serie));}return chapters;}
Serie.java
publicstaticArrayList<Serie>makeSeriesList(){ArrayList<Serie> series =newArrayList<>();for(int i =1; i <=5; i++){Serie serie =newSerie("Serie "+ i,"Genre "+ i,"Creator "+ i,1200+ i,5+ i); serie.setChapters(Chapter.makeChaptersList(serie)); series.add(serie);}return series;}
Mi implementacion de los métodos view() fue un poco diferente ya que preferí hacer las respectivas implementaciones en la clase respectiva. Concretamente hice la validacion de la cantidad de capitulos vistos en la clase Serie pues considero que es el lugar adecuado dentro de la lógica con la que esta estructurada la aplicacion.
Clase Serie
@Overridepublicvoidview(){setViewed(true);startToSee(newDate());for(int i =0; i <100; i++){System.out.println("...You are seeing the "+getTitle()+"...");}Utils.timeDelay(2);stopToSee(newDate());System.out.println("\n::YOU JUST SAW::"+toString());}
En la clase Chapter no hice ningún cambio pues el comportamiento del metodo view() es exactamente el mismo que en la clase Movie.