Curso de Java SE Orientado a Objetos

¡Prueba la suscripción de Platzi!

Entender la Programación orientada a objetos

001. Programación orientada a objetos en Java

Paradigma de programación: Teoría que suministra la base y modelo para resolver problemas con nuestro código.

Programación Orientada a Objetos: (POO) nos ayuda a analizar y entender todos estos problemas para resolverlos de la forma más sostenible en el futuro. Java surgió con este paradigma y es uno de los lenguajes que define en gran manera el rumbo que sigue la POO.

Elementos:

  • Clases

  • Propiedades

  • Métodos

  • Objetos

Pilares:

  • Encapsulamiento

  • Abstracción

  • Herencia

  • Polimorfismo

UML: Unified Modeling Language, usado en la POO para una representación visual.

  • Tipos de diagramas: clases, casos de uso, objetos, actividades, iteración, estados e implementación.

  • A lo largo del curso de usará para diagramar clases, casos de uso y objetos.

Pasos para analizar un problema:

  • Observar

  • Graficar (haciendo uso del UML)

  • Programar

002. ¿Qué es un Objeto

  • Los Objetos tienen propiedades y comportamientos

  • Son físicos (User) o conceptuales (Session)

  • Las Propiedades o Atributos (se expresa en sustantivos), usado para identificar un objeto. Ejemplo: nombre, tamaño, color, forma, estado.

  • Los Comportamientos (se expresa en verbo o sustantivo y verbo) son operaciones, acciones, funcionalidades del objetos. Ejemplo: login(), logout(), makeReport().

003. Abstracción ¿Qué es una Clase?

Clase:

  • Modelo sobre el cual el objeto es construido.

  • Las clases permiten generar más objetos.

  • Usado para separar código y modularizarlo.

  • Cada clase debe tener identidad, estado (con sus atributos) y comportamiento (con sus métodos y operaciones)

Abstracción:

  • Analizar objetos de forma independiente para abstraer su composición (entender sus propiedades y comportamientos) y generar un molde.

  • Permitirá reutilizar código.

Graficar:

Nombre Clase

Identidad

Atributo 1

Atributo 2

Estados

Atributo 3

...

Atributo n

Operación 1

Operación 2

Comportamientos

Operación 3

...

Operación n

Por ejemplo:

El ejemplo de clase más típico en Internet:

Nombre de la clase: Person
Atributos: Name, Age
Operaciones: walk()

Person

Name

Age

walk()

Nota: El nombre de la clase será único y escrito en formato UpperCamelCase.

004. Modularidad

Modularidad:

  • Consiste en dividir nuestro programa en diferentes módulos de forma que puedan unirse o separarse sin romperse entre ellos o perder alguna funcionalidad.

  • Tiene 2 niveles, uno básico que veremos en este curso y otro que se verá en programación funcional (PF).

  • Nivel POO: permite subdividir un sistema en varios componentes.

  • Nivel PF: permite subdividir un sistema en sistemas más pequeños.

  • La POO se compone de la modularidad, teniendo como resultado la resolución rápida a los problemas.

  • La modularidad permitirá:

    • Reutilizar código

    • Evitar colapsos

    • Que nuestro código Ser mantenible

    • Aumenta la legibilidad

    • Ser legible.

    • Resolución rápida de problemas.

Nota: Cada módulo es un archivo y cada archivo es una clase. En la POO, un programa se dividirá en diferentes partes o módulos (clases) y cada clase será almacenada en un archivo. Las clases permitirán la modularidad.

La modularidad se aplica en diferentes entornos por ejemplo:

  • Backend: POO

  • Frontend: Componentes(Angular, ReacJs, VieJs)

  • Diseño: UI/UX(Atomic-design)

Definir Clases y sus componentes

005. Creando nuestra primera Clase

Nuestro proyecto en este curso es construir un sistema que nos permita listar y agendar nuestras citas médicas, por lo que debemos crear algunas clases para cada integrante del sistema: doctores, pacientes, entre otras.

  1. Open IntelliJ IDEA

  2. Create + new project

  3. Select Project SDK: (java version 1.8)

  4. Project name: MyMedicalAppointments

  5. Add to src New -> Java Class -> Name: Main

public class Main {
    public static void main(String[] args) {

    }
}
  1. Add to src New -> Java Class -> Name: Doctor

// Clases:
public class Doctor {
    // Atributos
    int id;
    String name;
    String speciality;
    // Comportamientos (métodos)
    public void showName(){
        // Instrucciones...
        System.out.println(name);
    }
}

Declarar un Objeto:

// Tipo de Objeto ---- Nombre del Objeto
Doctor myDoctor;
// Otro objeto del mismo tipo Doctor:
Doctor anotherDoctor;

Instanciar un Objeto:

// Nombre del Objeto ---- Clase base para crear algún tipo de objetos
myDoctor = new Doctor();
// Otro objeto
anotherDoctor = new Doctor();

Declarar e instanciar un objeto en la misma línea:

// Declarar el objeto ---- Instanciar el objeto
Doctor myDoctor = new Doctor();
  1. Declara e instancia Doctor en clase Main

src/Main.java

public class Main {
    public static void main(String[] args) {
        Doctor myDoctor = new Doctor();
        myDoctor.name = "Anahí Salgado";
        myDoctor.showName();
    }
}

Run Main.main() -> output

Anahí Salgado

006. Método constructor

Método contructor:

  • Es el primer método que se ejecuta por defecto cuando creamos una clase

  • Crea nuevas instancias de una clase

  • Tiene el mismo nombre de la clase que inicializa

  • Usa la palabra clave new para invocarlo

  • Puede tener 0 o + argumentos

  • No regresa un valor

El compilador de Java crea un método constructor en caso de que no definamos uno, pero de todas formas es muy buena idea programarlo nosotros, ya que nos permite definir y/o configurar el comportamiento de nuestros objetos usando argumentos.

public class Doctor {
    // Atributos...

    // Método Constructor:
    Doctor(/* parámetros */) {
        // Instrucciones que se ejecutan al crear/instanciar
        // un nuevo objeto con la clase Doctor...
    }
}
Doctor myDoctor = new Doctor(/* parámetros */);
//Método constructor

El método constructor no debe regresar ningún valor (no necesitamos un return). Más adelante estudiaremos un poco más a fondo cómo funcionan la sobrecarga de métodos y sobrecarga de constructores.

src/Doctor.java

public class Doctor {
    // Atributos
    int id;
    String name;
    String speciality;
    // Constructor
    Doctor() {
        System.out.println("Construyendo el objeto Doctor");
    }
    // Comportamientos
    public void showName(){
        System.out.println(name);
    }
}

Run Main.main() -> output

Construyendo el objeto Doctor
Alejandro Rodriguez

El método constructor es un método no convencional. Por ejemplo podemos tener dos opciones de construir el objeto.

src/Doctor.java

public class Doctor {
    // Atributos
    int id;
    String name;
    String speciality;
    // Constructor
    Doctor() {
        System.out.println("Construyendo el objeto Doctor");
    }
    Doctor(String name) {
        System.out.println("El nombre del doctor asignado es: " + name);
    }
    // Comportamientos
    public void showName(){
        System.out.println(name);
    }
}

src/Main.java

public class Main {
    public static void main(String[] args) {
        Doctor myDoctor = new Doctor("Anahí Salgado");
        myDoctor.name = "Alejandro Rodriguez";
        myDoctor.showName();
    }
}

Run Main.main() -> output

El nombre del doctor asignado es: Anahí Salgado
Alejandro Rodriguez

007. Static Variables y Métodos Estáticos

  • Clase: Es el molde de abstracción de un objeto (atributos y métodos)

  • Objeto: Donde se puede definir datos a los atributos y llamar a los métodos.

Elementos estaticos (métodos y variables):

Los métodos y variables estáticos nos ayudan a ejecutar o conseguir algún código desde clases no han sido instanciadas, ya que sus valores se guardan en la memoria de nuestro programa, no en diferentes objetos instanciados a través de una clase

  • Los métodos estáticos y variables estáticas se definen por la palabra reservada static.

  • Se pueden usar en toda la clase.

  • Para acceder a ellos es mediante el nombre de la clase Math.random();

  • Se invoca en una clase que no tiene instancias de la clase.

Se puede acceder a los métodos de una clase de 2 formas:

  1. A partir de la instancia del objeto myDoctor.showName();

  2. A partir del nombre de la clase Math.random();

Ejemplo:

Math.sqrt(25); // Método estático
Math.PI; // Variable estática

Para ser llamados por el nombre de la clase el método tiene que ser definido como método estático.

Ejemplo

public class Calculador {
    public static final double PI = 3.1415926;
    public static int suma(int a, int b){
        return a + b;
    }
}
Calculadora.suma(5,2);
Calculadora.PI;

El scope y el nivel de acceso es global

public class ClaseC {
    public static valor = 0;
}
public class ClaseA {
    ClaseC.valor = ClaseC.valor + 1;
}
public class ClaseB {
    System.out.println(ClaseC.valor); // 1
}

Las variables estáticas mantienen su valor durante todo el ciclo de vida de nuestro programa, por lo tanto, podemos alterar los valores de una variable estática desde una clase y consumir su valor alterado desde otra sin necesidad de conectar ambas clases.

Usar elementos estáticos con la sintaxis import

También podemos importar los métodos estáticos de una clase para usarlos sin necesidad de escribir el nombre de la clase:

import static com.anncode.operaciones.Calculadora.*;
import static java.lang.Math.*;
public class Main {
    public static void main(String[] args) {
        System.out.println(suma(3,5));
        System.out.println(PI);
    }
}

Con * indico que importo todos los mienbros de una clase

008. Creando elementos estáticos

En muchos casos nuestro código necesita ejecutar métodos que no necesariamente deben pertenecer a un objeto o instancia en concreto, ya que pueden ser muy generales (así como Math.Random) o los valores que almacenamos deben ser los mismos, sin importar si los consumimos desde una o más clases.

En todos estos casos vale la pena usar variables y métodos estáticos.

src/Doctor.java

public class Doctor {
    // Atributos
    static int id = 0; //Autoincrement
    // Constructor
    Doctor() {
        id++; //Autoincrement
        System.out.println("Construyendo el objeto Doctor");
    }
    // Comportamientos
    public void showId(){
        System.out.println("ID Doctor: " + id);
    }
}

src/Main.java

public class Main {
    public static void main(String[] args) {
        Doctor myDoctor = new Doctor();
        myDoctor.showId();
        System.out.println(Doctor.id);

        Doctor myDoctorAnn =  new Doctor();
        myDoctor.showId();
        System.out.println(Doctor.id);
    }
}

Cada vez que creemos un nuevo Doctor va incrementando el id

Run Main.main() -> output

Construyendo el objeto Doctor
ID Doctor: 1
1
Construyendo el objeto Doctor
ID Doctor: 2
2

El scope permite modificar el valor externamente

src/Main.java

public class Main {
    public static void main(String[] args) {
        Doctor myDoctor = new Doctor();
        myDoctor.showId();
        System.out.println(Doctor.id);

        Doctor.id++;

        Doctor myDoctorAnn =  new Doctor();
        myDoctor.showId();
        System.out.println(Doctor.id);
    }
}

Run Main.main() -> output

Construyendo el objeto Doctor
ID Doctor: 1
1
Construyendo el objeto Doctor
ID Doctor: 3
3

Si el atributo id fuese no estático.

src/Doctor.java

public class Doctor {
    // Atributos
    int id = 0; //Autoincrement
    // Constructor
    Doctor() {
        id++; //Autoincrement
        System.out.println("Construyendo el objeto Doctor");
    }
    // Comportamientos
    public void showId(){
        System.out.println("ID Doctor: " + id);
    }
}

src/Main.java

public class Main {
    public static void main(String[] args) {
        Doctor myDoctor = new Doctor();
        myDoctor.showId();

        Doctor myDoctorAnn =  new Doctor();
        myDoctor.showId();
    }
}

Run Main.main() -> output

Construyendo el objeto Doctor
ID Doctor: 1
Construyendo el objeto Doctor
ID Doctor: 1

Add class UIMenu

src/UIMenu.java

public class UIMenu {
    public static void showMenu(){
        System.out.println("Este es un menu");
        showPatientMenu();
    }
    static void showPatientMenu(){
        System.out.println("Este es un submenu");
    }
}

Si quiero llamar a un metodo dentro de la clase main tiene que ser static.

src/Main.java

public class Main {
    public static void main(String[] args) {
        UIMenu.showMenu();
    }
}

Conceptualmente no tiene sentido crear una instancia de una clase ( UIMenu ) para llamar a un menu ( showMenu() )

Usando la sintaxis de import

  1. Crear un package en src con nombre ui

  2. Mover clase UIMenu al paquete ui

  3. Refactor

src/ui/UIMenu.java

package ui;
public class UIMenu {
    public static void showMenu(){
        System.out.println("Este es un menu");
        showPatientMenu();
    }
    static void showPatientMenu(){
        System.out.println("Este es un submenu");
    }
}

src/Main.java

import static ui.UIMenu.*;
public class Main {
    public static void main(String[] args) {
        showMenu();
    }
}

Con esto la clase Main llama a showMenu como si fuera parte de ella misma.

Cuando definimos un método del tipo:

static void showMenu()

Por default es "package-private" es decir solo puede ser accedido por clases en el mismo package. Por eso al crear el package "ui" debemos agregar el modificador "public" para poder acceder a él desde la clase Main.

009. Final Variables Constantes

public class Calculador {
    public static final double PI = 3.1415926;
}
  • static : Le da un scope Global

  • final : Hace a la variable constante, su valor no va a ser asignado.

01. Variable vs. Objeto Un vistazo a la memoria

Un objeto es una referencia a un espacio en memoria. Cuando creamos objetos, Java los guarda en la memoria y nos devuelve coordenadas con las que podremos acceder a la información que almacenamos.

int i = 0;
Doctor myDoctor = new Doctor();
Doctor myDoctor2 = new Doctor();

Existen dos tipos de memoria: Stack y Heap.

La memoria Stack es mucho más rápida y nos permite almacenar nuestra información de forma "ordenada". Aquí se guardan las variables y sus valores de tipos de datos primitivos (booleanos, números, strings, entre otros).

Los objetos también usan la memoria Stack , pero no para guardar su información, sino para guardar las coordenadas a la verdadera ubicación del objeto en la memoria Heap , una memoria que nos permite guardar grandes cantidades de información, pero con un poco menos de velocidad.

Ubicación en memoria de una variable y un objeto

  • Una variable almacena su valor en la stack de la memoria

  • Un objeto almacena la dirección en memoria donde se almacenan realmente los datos (memoria heap).

Si asigno el valor de una variable primitiva a otra variable.

int a = 1;
int b = a; // b = 1

Si asigno el valor de un objeto a otro ojeto

src/Main.java

public class Main {
    public static void main(String[] args) {
        Doctor myDoctor = new Doctor();
        Doctor myDoctor2 = new Doctor();
        System.out.println(myDoctor);
        System.out.println(myDoctor2);
        System.out.println("Asignado el valor de un objeto a otro");
        myDoctor2 = myDoctor;
        System.out.println(myDoctor);
        System.out.println(myDoctor2);
    }
}

Run Main.main() -> output

Doctor@1b6d3586
Doctor@4554617c
Asignado el valor de un objeto a otro
Doctor@1b6d3586
Doctor@1b6d3586

A diferencia de una variable lo que se asigno es la dirección de memoria. Ambos objetos apuntan al mismo lugar, por ende si se modifica 1 se modificaran ambos.

011. ¡Reto!

Ahora estás listo para resolver tu primer reto que en realidad es muy sencillo de hacer.

Mira el siguiente diagrama y construye la clase Patient.

Patient name: String email:String address: String phoneNumber: String birthday: String weight: double height: double blood: String Patient(name: String, email: String)

public class Patient { 
    String name = "";
    String email = "";
    String address = "";
    String phoneNumber = ""; 
    String birthday = "" ; 
    double weight = 0.0; 
    double height = 0.0; 
    String blood = "";

    Patient(String name, String email){

    }
}

12. Sobrecarga de métodos y constructores (21585)

A veces necesitamos que dos o más métodos de una misma clase tengan el mismo nombre, pero con diferentes argumentos o distintos tipos de argumentos/valores de retorno.

Afortunadamente, Java nos permite ejecutar código y métodos diferentes dependiendo de los argumentos que reciba nuestra clase.

public class Calculadora {

    // Los dos parámetros y el valor de retorno son de tipo int
    public int suma(int a, int b){
        return a + b;
    }

    // Los dos parámetros y el valor de retorno son de tipo float
    public float suma(float a, float b) {
        return a + b;
    }

    // Un parámetro es de tipo int, mientras que el otro parámetro y el valor de retorno son de tipo float
    public float suma(int a, float b) {
        return a + b;
    }
}

En este ejemplo estamos sobrecargando el método suma

Sobrecarga de Contructores

El uso más común de la sobrecarga de métodos es la sobrecarga de constructores para instanciar objetos de formas distintas dependiendo de la cantidad de argumentos que enviamos.

public class Doctor {

    static int id = 0;
    String name;
    String speciality;

    public Doctor() {
        this.name = "Nombre por defecto";
        this.speciality = "Especialidad por defecto";
    }

    public Doctor(String name, String speciality) {
        this.name = name;
        this.speciality = speciality;
    }
}

Al instanciar un nuevo doctor se asignara los atributos que le ingresemos al constructor

public class Main {
    public static void main(String[] args) {
        //showMenu();
        Doctor  myDoctor = new Doctor("Anahí Salgado","Pediatria");
        System.out.println(myDoctor.name);
        System.out.println(myDoctor.speciality);

    }
}
Anahí Salgado
Pediatria

13. Encapsulamiento Modificadores de acceso (21586)

Hasta ahora los atributos de una instancia (ex. Patient) pueden ser accedidos y modificados desde el punto de entrada de la aplicacion Main.

public class Main {
    public static void main(String[] args) {

        Patient patient = new Patient("Alejandra","alejandrea@mail.com");

        System.out.println(patient.name);
        System.out.println(patient.email);

        patient.weight = 60.5;
        patient.height = 1.65;

        System.out.println(patient.weight);
        System.out.println(patient.height);

    }
}
Alejandra
alejandrea@mail.com
60.5
1.65

Esto produce una inconsistencia de la data.

Los Modificadores de Acceso nos ayudan a limitar desde dónde podemos leer o modificar atributos especiales de nuestras clases. Podemos definir qué variables se pueden leer/editar por fuera de las clases donde fueron creadas. Esto lo conocemos como Encapsulamiento.

Default es si no se coloca ningun modificador de acceso

014. Getters y Setters

Descripción:

Los Getters y Setters nos permiten leer y escribir (respectivamente) los valores de nuestras variables privadas desde fuera de la clase donde fueron creadas. Con los Getters obtenemos los datos de las variables y con los Setters asignamos o cambiamos su valor.

También puedes usar los atajos de tu IDE favorito para generar los métodos getters y setters de todas o algunas de tus variables.

public class Patient {
    private String name;

    public String getName() {
        return "Patient name is " + this.name;
    }

    public void setName(String newName) {
        this.name = newName;
    }
}

Comentarios:

  • Alfonso Benjamin Banda Reyna

    hay una herramienta que se llama lombok, que te genera muchos métodos como getters y setters o constructores con anotaciones para que quede mas limpio el código

  • caramirezc

    También para generar rapidamente los métodos Getters y Setters en IntelliJ IDEA basta con oprimir Alt+ins , seleccionar Getter o Setter y seleccionar los atributos privados.

    • jaime-pinto-a

      Muchas gracias por el tip

    • Brayan Mamani

      ¡Muy buen consejo!

  • juanbarcinilla

    Los getter y setters puden ser generado con el IDE.

    • bexperrr

      Y pueden ser optimizados con una libreria.

    • Brayan Mamani

      Si se puede generar desde cualquier IDE.

  • Daniel Alejandro Mejia Rojas

    Los Getters y Setters son una mala practica, ya que utilizarlos demasiado quitaria la privacidad que queremos para el usuario, ya que si queremos tener esa información en privado no se podria porque todo el mundo mediante estos métodos tendria acceso a esta misma informacion

    • Roger Davila

      Los getter y los setter te ayudan justamente a resolver ese problema. Mediante estes métodos puedes aplicar ciertas validaciones sobre la información antes de asignarla/devolverla.

    • Marco Alejandro Sandoval

      Pues no los escribes y ya.

      Los escribes para los datos que necesitan ser utilizados desde otro nivel de código.

  • Alexander Mateo

    Getters y Setters son métodos que se deben declarar públicos para mantener la consistencia de la clase y nos poder acceder a los atributos de la clase que son declarados privados.

  • Wilson Marino Pablo Mendez

    A las propiedades private solo se puede accederse por medio de métodos.

  • Juan David Castro

    Los _getters y setters son métodos públicos que nos ayudan a leer y/o modificar nuestras variables privadas._ 👍

015. Variable vs. Objeto

Descripción:

Las Variables son entidades elementales muy sencillas, pueden ser números, caracteres, booleanos, entre otras. Los Objetos son entidades complejas que pueden estar formadas por la agrupación de diferentes variables y métodos.

Los Objetos Primitivos o Clases Wrapper son variables primitivas que trabajan con algún tipo de dato y también tienen las características de los objetos.

Por ejemplo: Byte, Short, Integer, Long, Float, Double, Character, Boolean o String.

Comentarios:

  • Samuel Narciso

    creo que es el tipo de dato String, ya que este no es un tipo de dato primitivo, sino un tipo de dato object.

  • Jesús Alejandro Marrón Legorreta

    El objeto del curso pasado fue el Array

  • Luis Alfredo Valencia Rincón

    El primer objeto que se uso en el Curso anterior (Introducción a Java SE) fue el objeto "sc" de tipo Scanner

  • Eliseoleo

    Patient D:

  • Félix Alejandro Zelaya Orellana

    Genial!!

  • Diana Carolina Quintero Caro

    Person

  • juandahoyos

    Patient

  • jonthonel

    Patient

  • Ricardo Coronado

    buena clase!! apunto estaba de empezar mi investigación de heap y stack de cada cosa. a ver si ya esta masticadito en la siguiente clase

  • caramirezc

    "Los arreglos pueden almacenar tipos de datos primitivos y también objetos"

  • caramirezc

    El objeto del curso anterior fue: patient

  • Alexander Mateo

    En este caso Variable != Objeto porque Java no considera a los tipos primitivos como objetos (excepto el String), en otros lenguajes de programación como Dart o Kotlin , todo es un objeto.

  • Juan David Castro

    Los Objetos son entidades complejas formadas por la agrupación de diferentes variables y/o métodos. Los Arrays son agrupaciones de una cantidad fija de elementos de un mismo tipo de dato.

    😱 ¡Los Arrays son Objetos!

  • JavierJ

    El objeto Patient

    • Wilson Marino Pablo Mendez

      X2

    • Brayan Mamani

      X3

016. Clases Anidadas

Descripción:

Las Clases Anidadas o Clases Helper son clases dentro de otras clases que agrupamos por su lógica y/o características en común.

Podemos encontrar clases estáticas anidadas, clases internas que son locales a un método o clases internas anónimas. Las clases anidadas pueden llamar a cualquier tipo de elemento o método de nuestras clases.

Las Clases Estáticas no necesitan ser instanciadas para poder ser llamadas y ejecutadas, aunque debes recordar que solo permiten llamar a los métodos estáticos de sus clases padre.

Comentarios:

  • andresanni

    Se pierde un poco cuando argega el ArrayList encima lo hace demasiado rapido usando todos los atajos del ide que ni siquiera vemos

  • Josias Cubillos Gutierrez

    ¿Es recomendable siempre encapsular de manera private todas las variables de las clases?

    • Demian Arenas

      Sí, es una buena practica tener tus variables privadas y solamente permitir el acceso a través de Getters y Setters.

    • Brayan Mamani

      Es una buena practica de programación, el encapsulamiento.

  • Carlos Flores

    Súper clase.

  • Félix Alejandro Zelaya Orellana

    Super! habrá que practicarlo

  • Alejandro Torancio

    No entendi muy bien esta clase, vengo siguiendo en orden los cursos previos para llegar hasta aqui, pero cuando empezaste a mencionar los Arrays pero como "colecciones" me perdi. Puntualmente no entendi como funciona ese arreglo, fue muy sesgado ese punto.

    • andresazuara98

      No se si es a lo que te refieres, me parece que en el curso básico explican los arrays, donde tienes n "celdas" contiguas en la memoria, suponiendo AvailableAppointments[10], puedes agregar 10 elementos de 0 a 9, en este caso puedes verlo en lugar de un array como un ArrayList, donde por debajo funciona igual, tienes un array pero básicamente es dinámico, si te fijas no estableces una cantidad de celdas. Para agregar un elemento en un arrray seria algo así: availableAppointments[lastElement++] = newAppointment. Lo que en un ArrayList es el método Add: availableAppointments.add(newAppointment);

  • ruben catalan rivera

    esta es de las mejores clases que he visto en platzi, se explica muy a detalle la helper class y junto con aclare dudas que tenia con otros lenguajes 😄

  • jaime-pinto-a

    Excelente

  • mauricioTequita

    Muy interesante las clases anidadas.

  • Bruno Diharce

    De todas formas, si yo quiero que la clase anidada sea unicamente vista por el doctor, seria:

    private class ClaseAnidada{} Donde esta podria ser vista desde los métodos del objeto Doctor no?

  • Michelle98

    Tengo una duda, se puede en vez de una clase anidada crear una "interface" para lo de "available appointment? ya que es una acción que el objeto doctor suele hacer y según recuerdo las interfaces sirven para eso, para hacer las acciones (métodos) y solo implementarlas en la clase que se necesiten Saludos! 😃

    • Bruno Diharce

      El doctor hace acciones CON los elementos "Available Appointment", necesita de esos objetos para tener sus datos y coleccionarlos, para eso es necesario que sean clases.

  • Wilson Marino Pablo Mendez

    Para trabajar con fechas es necesario importar una librería

      import java.util.Date

017. Clases Internas y Locales a un método

Descripción:

Comentarios:

018. Enumerations

Descripción:

Los enumerations son tipos de datos muy especiales pues este, es el único en su tipo que sirve para declarar una colección de constantes, al ser así estaremos obligados a escribirlos con mayúsculas.

Usaremos enum cada vez que necesitemos representar un conjunto fijo de constantes. Por ejemplo los días de la semana.

Así podemos declarar un enumeration usando la palabra reservada enum.

public enum Day {
    SUNDAY, MONDAY, TUESDAY, WEDNESDAY,
    THURSDAY, FRIDAY, SATURDAY
}

Puedo crear referencias de enumerations de la siguiente forma:

    Day day;

    switch (day) 
        case MONDAY:
            System.out.println("Mondays are good.");
            break;
        case FRIDAY:
            System.out.println("Fridays are nice");
            break;
        case SATURDAY: case: SUNDAY:
            System.out.println("Weekends are the best");
            break;
        default:
            System.out.println("Midweek are so-so");
            break;
    }

Y puedo llamar un valor del enumeration así:

    Day.MONDAY;
    Day.FRIDAY;
    Day.SATURDAY

Los enumerations pueden tener atributos, métodos y constructores, como se muestra:

public enum Day {
    MONDAY("Lunes");
    TUESDAY("Jueves");
    FRIDAY("Viernes");
    SATURDAY("Sábado");
    SUNDAY("Domingo");

    private String spanish;
    private Day(String s) {
        spanish = s;
    }

    private String getSpanish() {
        return spanish;
    }
}

Y para utilizarlo lo podemos hacer así:

System.out.println(Day.MONDAY);

Imprimirá: MONDAY

System.out.println(Day.MONDAY.getSpanish())

Imprimirá: Lunes

Comentarios:

  • Samuel Narciso

      public class Pruebas {
          public enum Vocales{
              A("Valor A"),
              E("Valor E"),
              I("Valor I"),
              O("Valor O"),
              U("Valor U");
    
              private String ValorInterno;
    
              private Vocales(String vocal){
                  ValorInterno=vocal;
              }
              public String getValorInterno(){
                  return"Vocal: "+ValorInterno;
    
          }
    
          public static void main(String[] args) {
              System.out.println(Vocales.A.getValorInterno());
              System.out.println(Vocales.E.getValorInterno());
              Vocales vocal=Vocales.A;
          }   
      }
  • Leonel Altamirano

    Estaba analizando el enum y decidí agregarle indices a los días para probar únicamente. Me di cuenta que el constructor de esta clase es privado y al principio no entendía por qué… Pero entendí que si fuera público se podrían cambiar las constantes, que obviamente no queremos que se cambien, desde afuera y es por eso que da error si lo ponemos como público.

          publicenum Day { 
              MONDAY("Lunes",1),
              TUESDAY("Jueves",2),
              FRIDAY("Viernes",3),
              SATURDAY("Sábado",4),
              SUNDAY("Domingo",5);
    
              private String spanish;
    
              private Day(String s,int a) { //<<Constructor Privado
                  spanish = s;
              }
    
              public String getSpanish() {
                  return spanish;
              }
          }
  • Gerald Zamora

    estas constantes deverian ir separadas con " , " en vez de " ; "

      MONDAY("Lunes");
      TUESDAY("Jueves");
      FRIDAY("Viernes");
      SATURDAY("Sábado");
      SUNDAY("Domingo");

    así

      MONDAY("Lunes"),
      TUESDAY("Jueves"),
      FRIDAY("Viernes"),
      SATURDAY("Sábado"),
      SUNDAY("Domingo");
  • Félix Alejandro Zelaya Orellana

    Super!!

  • Ricardo Coronado

    Me llamó la atención esto : "al ser así estaremos obligados a escribirlos con mayúsculas.". Intenté con minúsculas y funciono de todos modos. Aunque entiendo que por convención es mejor constantes en mayúsculas.

    • Mernoa

      Supongo el "estar obligados" refiere a estar obligados por convencion no por el lenguaje, la convencion de que las constantes deben ir en mayuscula se comparte a travez de todos los lenguajes, por lo menos los que conosco (php, js, java).

    • jorge espinoza

      Es obligado por convencion. lo mas importante como programador es ser ordenado y seguir la convenciones. ya que siempre trabajas con multiples programadores y asi ellos escriben igual las cosas . y a la hora de leer sus , y ellos leer el tuyo es mas facil todo. te lo dice alguien que no le ponía atención a estas cosas. y como dice el otro comentario en casi todos los lenguajes es igual Php, js, Php, Java, c# y en uno en particular que es realmente obligatorio es python ya que casi todas esas conveciones son reglas del propio lenguaje

  • caramirezc

    aporte: el método private String getSpanish() deberia estar dentro del enumeration day, ya que el atributo spanish es privado

    • Jose Oscar Rosas Perez

      El método getSpanish, sí se encuentra dentro del enum Day, si identamos el código podremos identificar mejor cuando inicia y cuando termina el enum y cuando inician y terminan su constructor y su método, lo que yo aportaría es que:

      • Las constantes del enum las debemos separar con coma y a la ultima constante poner punto y coma.

      • Y para poder hacer uso del método getSpanish deberíamos tener el modificador de acceso de este método como publico.

        public enum Day {
            MONDAY("Lunes"),
            TUESDAY("Jueves"),
            FRIDAY("Viernes"),
            SATURDAY("Sábado"),
            SUNDAY("Domingo");

            private String spanish;

            private Day(String s) {
                spanish = s;
            }

            public String getSpanish() {
                return spanish;
            }
        }
    De esta manera podremos hacer uso de cualquier constante que este dentro del enum Day desde otra clase de esta forma:
    ```java
    public class TestEnum {
        publicstaticvoidmain(String[] args) {    
            Day dayOfWeek = Day.MONDAY;
            System.out.println("El día de la semana en español seleccionado es: " + dayOfWeek.getSpanish());
        }
    }
## Reutilizar Código

### 019. ¿Qué es la Herencia Don't repeat Yourself

#### Descripción:

**Don’t repeat yourself** \(DRY\) consiste en detectar cuando estamos repitiendo el mismo código una y otra vez para crear algún método o función que nos ayude a evitar estos repetidos.

Esta es una de las bases de la programación que siempre debemos tener en cuenta, ya que nos ayuda a reducir la dificultad de nuestro código para implementar cambios y/o mejoras en nuestra aplicación.

La **Herencia** consiste en crear nuevas clases a partir de otras clases, establecemos una relación padre e hijo entre nuestras clases. Es diferente a las clases anidadas, ya que, en vez de crear clases dentro de clases, le indicamos a nuestras _subclases_ de qué _superclase_ pueden heredar \(`extends`\) para reutilizar el código de algunos de sus métodos.

Recuerda que nuestras clases no pueden heredar de más de una clase.

```java
public class SuperClass {
    // ...
}

public class SubClass extends SuperClass {
    // ...
}

Comentarios:

  • Gerald Zamora

    Crear un molde para otros moldes y así ahorrarnos muchas lineas.

  • Félix Alejandro Zelaya Orellana

    Genial!!

  • Luis Fernando Chacha Montenegro

    DRY : Don’t repeat yourself 😃

  • Daniel Contreras

    UNA PREGUNTA. ¿QUE ES MEJOR CÓDIGO ABSTRACTO O CÓDIGO LEGIBLE, COMO BUENAS PRACTICAS?

    • danielveraec

      En realidad pienso que no son conceptos que contrapuestos. Un código con un buen nivel de abstracción debe ser mucho mas fácil de leer.

      Sin embargo, hay ocasiones que en pro de mejorar el rendimiento de una aplicación es mas conveniente mantener la complejidad; pero esto debe ser la excepción. He visto esto por ejemplo cuando se realizan tuning de consultas SQL en procesos batch.

      Lo mejor es conservar un código legible para facilitar el mantenimiento a futuro, así no agrandas la deuda técnica que tenga el sistema.

    • andresazuara98

      Es que muchas veces un código mas legible puede ser causante de código "repetitivo", al momento del desarrollo se vuelve mas fácil desarrollarlo así, pero con el tiempo, mantenimiento y escalabilidad será muy difícil

  • Juan David Castro

    Las clases y subclases son como moldecitos para crear galletitas. 🍪🍪🍪 Las superclases son como los moldes con los que creamos nuestros submoldesitos para crear las galletitas. 😮😏😼

020. Super y This

Descripción:

Super indica que una variable o método es de la clase padre, la superclase de cual heredan nuestras subclases , solo la usamos cuando aplicamos herencia.

Además, podemos llamar al constructor de la clase padre desde sus diferentes subclases usando super(); y enviando los argumentos que sean necesarios.

Por otro lado, this nos permite especificar que nuestras variables están señalando a la misma clase donde estamos trabajando, ya sea una clase normal, anidada, subclase o superclase.

public class User {
    int age = 1
    public int getAge() {
        return this.age;
    }
}
public class Doctor extends User {
    String speciality = "Dentist";
    Doctor() {
        super.getAge(); // 1
        this.getSpeciality(); // Dentist
    }
    public int getSpeciality() {
        return this.speciality;
<<<<<<< HEAD:platzi/cursos/Curso-de-Java-SE-Orientado-a-Objetos-1629.md
    }
} 
=======

      }

    }
>>>>>>> e22eb86134383f9a1fe5ced99f65dc21309a98f6:plataformas/platzi/rutas-de-aprendizaje/desarrollo-con-java/curso-de-java-se-orientado-a-objetos-1629.md

Comentarios:

  • Félix Alejandro Zelaya Orellana

    Genial!! Aprendí mucho!!

  • andresazuara98

    La razón por la cual salió el error en el super, es porque al mandar llamar al constructor de la clase padre este debe de ir siempre al inicio del constructor de la clase hijo

    • Brayan Mamani

      Buena recomendación para los que cometen esos errores.

  • operez12

    Es solo por definición, o en lugar de User no seria mejor llamar Person la clase padre?

    • mauricioTequita

      Considero que es mejor User puesto que es mas especifico y hace referencia a los usuarios del sistema.

    • danielveraec

      Podría ser cualquiera de las dos. En mi opinión debería ser el que se aproxime mas al lenguaje usado en el negocio. En este caso, para el contexto del sistema que se quiere construir veo que aplica mas User.

    • Antonio Jose Gonzalez Liñan

      Seria mucho mejor.

    • Brayan Mamani

      ¡Sería una buena opción!

  • PatoGH

    ¿La clase padre hereda los métodos de la clase anidada que esta dentro de la clase hija?

    • danielveraec

      En realidad es al revés. La clase hija es la que hereda los elementos de la clase padre.

    • Brayan Mamani

      La clase hija es que que recibe las propiedades de la clase padre.

021. Polimorfismo Sobreescritura de Métodos

Descripción:

El Polimorfismo es una característica de la programación orientada a objetos que consiste en sobrescribir algunos métodos de la clase de la cual heredan nuestras subclases para asignar comportamientos diferentes.

Además de los métodos de las superclases , también podemos redefinir el comportamiento de los métodos que "heredan" todos nuestros objetos, así como .toString, hashCode, finalize, notify, entre otros.

La sobreescritura de constructores consiste en usar los miembros heredados de una supreclase pero con argumentos diferentes.

Recuerda que no podemos sobrescribir los métodos marcados como final o static.

Comentarios:

  • Félix Alejandro Zelaya Orellana

    Super! Me costó un poco pero entendido!

  • Ricardo Coronado

    buena clase, ahora me cae el 20 de muchas cosas. excelente maestra!

  • caramirezc

    En el ejemplo, se sobrescribió el método .toString() en la clase Patient que se había sobrescrito en la clase User.

  • Juan David Castro

    Al imprimir cualquier objeto en la consola con System.out.println(object), en realidad, estamos ejecutando el método .toString() de dicho objeto, por lo que si sobreescribimos este método en nuestras clases, el resultado en la consola también cambiará automáticamente.

022. Polimorfismo Sobreescribiendo el método toString

Descripción:

Comentarios:

  • Félix Alejandro Zelaya Orellana

    Super!!!

  • CristhianFranco

    Buenisimo el curso, me sirvio muchisimo para reforzar mis bases.

  • johnkegd

    me llama la atención que no hay muchos comentarios en estos capitulos. estoy a 3 dias de que se termine mi suscripción anual y este es uno de los cursos ques eleccion para terminar y he visto muy pocos comentarios en el hilo.

    Me gustaron muchos todos tus otros cursos Anahí (y)

    • jorge espinoza

      creo que el curso es relativamente nuevo si vista el curso basico de java te puedes dar cuenta por las versiones que instala

    • Brayan Mamani

      ¡Son de los mejores cursos que tiene Platzi!

023. Interfaces

Descripción:

Las Interfaces son un tipo de referencia similar a una clase con solo constantes y definiciones de métodos, son de gran ayuda para definir los comportamientos que son redundantes y queremos reutilizar un más de una clase, incluso cuando tenemos muchas clases y no todas pertenecen a la misma "familia".

Las interfaces establecen la forma de las clases que la implementan, así como sus nombres de métodos, listas de argumentos y listas de retorno, pero NO sus bloques de código, eso es responsabilidad de cada clase.

Comentarios:

  • Félix Alejandro Zelaya Orellana

    Que genial!! Dios mio que tanto me costaba esto en la facultad jajaj

  • Gerald Zamora

    Una interfaz no tiene bloques de código; en ella se encuentra la declaración de los métodos(sin contenido) y/o constantes.

    eje:

      public interface Runnable {
          voidrun();
      }

    y la forma de implementarla en una clase es con la palabra reservada implements

  • Ignacio

    Entiendo que este curso y el anterior vinieron como actualización de un viejo curso de Java… también se prevé una actualización dentro de poco para el curso avanzado?

    • Gerald Zamora

      Bueno en la agenda de platzi no aparece, así que supongo que no será dentro de poco :’)

    • Brayan Mamani

      Es un curso esperado por muchos.

  • jaime-pinto-a

    Clase User se debería llamar Clase persona. porque de ella derivan las clases Doctor, Persona y Enfermera, la clase user, podría ser utilizada para lo que corresponde a seguridad, en el proceso login en la aplicación

  • oscargonzalezbonifacio

    Curso de UML o patrones de diseno en java me gustaria

  • Ricardo Coronado

    simplemente quiero ser el primer comentario. Todo genial hasta ahora 😃

    • FixingMind5

      Súper. ¡Qué bueno que te esté gustando! Nunca pares de aprender 😉

    • Brayan Mamani

      ¡El primer comentario, esta buena! 😃

024. Creando una interfaz para definir si una fecha es agendable

Descripción:

Composición de Interfaces en Clases : abstraer todos los métodos/comportamientos de una clase para modularizarlos (comprimirlos, encapsularlos) en una interfaz y reutilizar su código en diferentes clases.

Las interfaces se crean utilizando la palabra reservada interface y se implementan en nuestras clases con implements.

Recuerda que podemos heredar (implementar) más de una interfaz, pero no podemos hacerlo de las clases padres o superclases.

public interface ISchedulabe {
    void schedule(Date date, String Time);
}


public class AppointmentDoctor implements ISchedulable {

    @Override
    public void schedule(Date date, String Time) {
        // ...
    }
}

Comentarios:

  • Israel Yance

    ¿No era mejor crear una clase Appointment como super clase de AppointmentDoctor y AppointmentNurse?

  • Félix Alejandro Zelaya Orellana

    Super!!

  • Gerald Zamora

    Hay una manera muy sencilla de ordenar arrays implementando una interfaz llamada Comparable en este caso la implementé para que ordenara un array de Doctores de mayor a menor según la cantidad de citas que tuviera. Este es el método que tiene la interfaz Comparable por dentro y que Doctor implementa

          @Override
      publicintcompareTo(Object o) {
          int a =  ((Doctor) o).availableAppointments.size();
          int b = this.availableAppointments.size();
    
          if(b == a){
              return0;
          }elseif(b > a){
              return -1;
          }else {
              return1;
          }
      }

    Existe una clase muy util llamada Arrays que tiene un método static sort() Ejemplo de su uso:

      public classMain {
          publicstaticvoidmain(String[] args) {
    
              Doctor a = new Doctor("a","@");
              Doctor b = new Doctor("b","@");
              Doctor c = new Doctor("c","@");
    
              Doctor[] arrayDoctores = {a,b,c};
    
              a.addAvailableAppointment(new Date(),"");
    
              b.addAvailableAppointment(new Date(),"");
              b.addAvailableAppointment(new Date(),"");
    
              c.addAvailableAppointment(new Date(),"");
    
              for (Doctor e: arrayDoctores) {
                  System.out.println(e.getName());
              }
          //imprimirá
          // a ,b, c  porque este fue el orden en que se agregaron 
    
              Arrays.sort(arrayDoctores); //aquí usamos la clase Arrays
              System.out.println();
    
              for (Doctor e: arrayDoctores) {
                  System.out.println(e.getName());
              }
          //imprimirá
          //b, a, c  ya que b es el que tiene mas citas "2"; a y c al ser iguales
          //no hace el cambio de posición 
          }
      }
  • jorge espinoza

    las clases con getter and setter se conocen POJO (Plain Old Java Object)

  • JavierJ

    Composición = dar poderes a las clases, abstraer métodos acciones de una clase, comprimirlos o encapsularlos en una interfaz para posteriormente utilizarlo.

    • Gian

      "Con un gran poder viene una gran responsabilidad!". La implementacion de la intereface Obliga a crear los métodos de la misma, de cierta manera es un contrato entre la interface y la clase que la implementa, de que almenos podra hacer todo lo que hace la interface, ya el como lo haga es otra historia xD

025. Collections

Descripción:

Otras interfaces que son muy importantes en Java son los llamados Collections

Los Collections nos van a servir para trabajar con colecciones de datos, específicamente y solamente con objetos , para esto recuerda que tenemos disponibles nuestras clases Wrapper que nos ayudan a convertir datos primitivos a objetos.

Los collections se diferencian de los arrays en que su tamaño no es fijo y por el contrario es dinámico.

A continuación te muestro un diagrama de su composición:

Como podemos observar el elemento más alto es la interfaz Collection , para lo cual, partiendo de su naturalidad de interface, entendemos que tiene una serie de métodos "básicos" dónde su comportamiento será definido a medida que se vaya implementando en más elementos. De ella se desprenden principalmente las interfaces Set y List.

La interface Set tendrá las siguientes características:

Almacena objetos únicos, no repetidos. La mayoría de las veces los objetos se almacenarán en desorden. No tenemos índice.

La interface List tiene éstas características:

Puede almacenar objetos repetidos. Los objetos se almacenan en orden secuencial. Tenemos acceso al índice.

Si seguimos analizando las familias tenemos que de Set se desprenden:

Clase HashSet Interfaz SortedSet y de ella la clase TreeSet.

HashSet los elementos se guardan en desorden y gracias al mecanismo llamado hashing (obtiene un identificador del objeto) permite almacenar objetos únicos.

TreeSet almacena objetos únicos , y gracias a su estructura de árbol el acceso es sumamente *rápido.

Ahora si analizamos la familia List, de ella se desprenden:

Clase ArrayList puede tener duplicados, no está sincronizada por lo tanto es más rápida Clase Vector es sincronizada, los datos están más seguros pero es más lento. Clase LinkedList , puede contener elementos duplicados, no está sincronizada (es más rápida) al ser una estructura de datos doblemente ligada podemos añadir datos por encima de la pila o por debajo.

Sigamos con Map

Lo primero que debes saber es que tiene tres implementaciones:

HashTable LinkedHashMap HashMap SortedMap ➡️ TreeMap

La interfaz Map no hereda de la interfaz Collection porque representa una estructura de datos de Mapeo y no de colección simple de objetos. Esta estructura es más compleja, pues cada elemento deberá venir en pareja con otro dato que funcionará como la llave del elemento.

Map

Donde K es el key o clave Donde V es el value o valor

Podemos declarar un map de la siguiente forma:

Map<Integer, String> map = new HashMap<Integer, String>();
Map<Integer, String> treeMap = new TreeMap<Integer, String>();
Map<Integer, String> linkedHashMap = new LinkedHashMap<Integer, String>();

Como observas solo se puede construir el objeto con tres elementos que implementan de ella: HashMap , TreeMap y LinkedHashMap dejando fuera HashTable y SortedMap. SortedMap estará fuera pues es una interfaz y HashTable ha quedado deprecada pues tiene métodos redundantes en otras clases. Mira la funcionalidad de cada uno.

Como te conté hace un momento Map tiene implementaciones:

HashMap: Los elementos no se ordenan. No aceptan claves duplicadas ni valores nulos. LinkedHashMap: Ordena los elementos conforme se van insertando; provocando que las búsquedas sean más lentas que las demás clases. TreeMap: El Mapa lo ordena de forma "natural". Por ejemplo, si la clave son valores enteros (como luego veremos), los ordena de menos a mayor.

Para iterar alguno de estos será necesario utilizar la interface Iterator y para recorrerlo lo haremos un bucle while así como se muestra:

Para HashMap

// Imprimimos el Map con un Iterador
Iterator it = map.keySet().iterator();

while(it.hasNext()){
    Integer key = it.next();
    System.out.println("Clave: " + key + " -> Valor: " + map.get(key));
}

Para LinkedHashMap

// Imprimimos el Map con un Iterador
Iterator it = linkedHashMap.keySet().iterator();

while(it.hasNext()){
    Integer key = it.next();
    System.out.println("Clave: " + key + " -> Valor: " + linkedHashMap.get(key));
}

Para TreeMap

// Imprimimos el Map con un Iterador
Iterator it = treeMap.keySet().iterator();

while(it.hasNext()){
    Integer key = it.next();
    System.out.println("Clave: " + key + " -> Valor: " + treeMap.get(key));
}

Ahora lee esta lectura y en la sección de tutoriales cuéntanos en tus palabras cómo funciona Deque.

Comentarios:

  • Gian

    El deque(Double Ended QUEue) es una colección lineal que solo permite insertar y retirar elementos de los extremos, proporcionando las funcionalidades de los Stack(pilas) y las Queue(Colas), en otras palabras permite usar LIFO y FIFO.

    Estas Caracteristicas nos obligan a que si quisiéramos eliminar o insertar un elemento en el centro del deque tendríamos que eliminar todos los elementos posteriores o todos los elementos anteriores. Y luego reconstruirlo segun nuestra necesidad. La interface provee de métodos como removeLastOccurence y removeFirstOccurence pero dada la forma en la que funciona esta interface, dependiendo de donde este ubicado el elemento a remover necesitar hacer una mayor o menor cantidad de iteraciones sobre la colección

  • Joshua Sailema Benavides

  • andresazuara98

    No estoy muy seguro, pero en LinkedHashMap al ordenar al ir insertando no debería hacer las busquedas mas rápidas? (dice que las busquedas son mas lentas en la descripción), ya que al estar ordenado sería mas rápido buscar, lo que sería mas lento serían las inserciones, ya que al insertar cada elemento verificaría en donde debería de ir

  • Yone Moreno Jiménez

  • OLIDEN858

    La interfaz Deque la implementa LinkedList, ha sido descrito su funcionamiento anteriormente en los posteos y en el ‘artículo’ de esta clase.

  • jaime-pinto-a

    Seria bueno, algún ejemplo del uso de Deque para reforzar la lectura

  • ricindigus

    Deck o Deque, es una lista tipo cola de doble extremo, es decir permite agregar o retirar objetos por ambos lados: inicio de la cola o final de la cola.

    (permite ingresar y retirar elementos) inicio cola - [ ] - [ ] - [ ] - fin cola (permite ingresar y retirar elementos)

    La interfaz de deck permite agregar elementos , eliminar elementos y recuperar elementos (este ultimo solo recupera el valor mas no elimina el elemento de la lista). para cada uno la interfaz es especifica por que en los métodos se indica si quieres realizar la operacion por el inicio o el final de la lista.

  • Hafnio

    Los collections son uno de los conceptos mas importantes de la programacion. Saber manejarlos correctamente es lo que separa a un junior de un Senior. Me encantan este tipo de archivos que los explican tan claramente.

  • Juan Chatelet

    Los "Deque" son una estructura de datos conocida como bicolas, en las que se pueden acceder, agregar, o eliminar elementos por ambos extremos de la cola, es decir, al prinicipio o al final. Los métodos que podemos utilizar para agregar elementos son:

    • addFirst (agrega un elemento al principio)

    • addLast (agrega un elemento al final)

      Si la cola tiene una capacidad restringida, entonces usaremos los métodos offerFirst y offerLast.

      Los métodos que podemos utilizar para quitar elementos son:

    • removeFirst (quita un elemento del principio)

    • removeLast (quita un elemento del final)

      Si la cola se encuentra vacia estos dos métodos arrojaran una excepcion; también podemos usar pollFirst y pollLast,

      que en caso de que la cola se encuentre vacia retornaran null.

      Los métodos que podemos utilizar para acceder a elementos son:

    • getFirst (retorna el primer elemento)

    • getLast (retorna el ultimo elemento)

      Al igual que al remover elementos,en caso de que la cola se enecuentre vacia estos métodos arrojaran una

      excepcion; también podemos usar peekFirst y peekLast, que en caso de que la cola se encuentre vacia retornaran

      null.

      Disculpen la falta de tildes, estoy usando un teclado en ingles.

      Muy buen curso, saludos!

  • Ricardo Coronado

    de la lectura entiendo que la interface Deque se usa para tener colecciones de objetos que se pueden comportar(segun quiera el programador) como cola o pila, es decir, que los objetos se agreguen, eliminen o lean al principio o al final de la lista.

  • caramirezc

    Hola comunidad, ¿cual interfaz es mas usada Set, List o Map?

    • Jose Oscar Rosas Perez

      Hola, yo creo que la más usada es List

  • Alexander Mateo

    A veces por su facilidad de uso, yo uso las LinkedList para almacenar obejtos complejos 😃

  • Wilson Marino Pablo Mendez

    Los collections son totalmente nuevos para mí, a la primara cuesta entenderlos.

    • Srna

      *Primera

    • Wilson Marino Pablo Mendez

      Gracias por la observación.

      Saludos!!

Aplicar Abstracción

026. Clases Abstractas

Descripción:

A veces NO necesitamos implementar todos los métodos de una clase heredada o interfaz. No siempre necesitamos crear instancias o implementar todos los métodos heredados de una clase padre, así como tampoco podremos necesitamos algún método de nuestras interfaces, pero estas nos obligan a escribir el código de todos los métodos que definimos genéricamente.

Afortunadamente, las Clases Abstractas resuelven todos estos problemas. Son una combinación entre interfaces y herencia donde no implementaremos todos los métodos ni tampoco crearemos instancias.

public abstract class Figura {
    // ...
}

class Triangulo extends Figura {
    // ...
}

Comentarios:

  • Félix Alejandro Zelaya Orellana

    Genial genial geniaaal!!

  • JavierJ

    Interface: te obliga a implementar todos los métodos.

    Herencia: A veces no necesitamos crear instancias de una clase padre, porque es muy genérica.

    Clases Abstractas: Combinación entre Interface y Herencia , no implementa todos los métodos, por su composición no es necesario instanciarlo, no se pueden crear instancias de una clase abstracta.

027. Miembros abstractos

Descripción:

Los Métodos Abstractos son los métodos que debemos implementar obligatoriamente cada vez que usemos nuestras clases abstractas, mientras que los métodos que no sean abstractos van a ser opcionales.

public abstract class Figura {
    abstract void dibujar(); // obligatorio
    void dibujar3D(); // no es obligatorio
}

class Triangulo extends Figura {
    void dibujar() {
        // Instrucciones para dibujar el triángulo...
    }
}

Recuerda los métodos abstractos solo se pueden implementar en clases abstractas. Y las clases abstractas no necesitan ser instanciadas para ser implementadas.

Comentarios:

  • Félix Alejandro Zelaya Orellana

    Genial!! Se va poniendo mas interesante!

  • andresazuara98

    Creo yo que lo correcto o al menos para que fuera mas fácil de implementarlo, es no dejar las salidas de texto hardcodeadas, sino que tomaran esos datos como atributos de la misma clase

  • JavierJ

    Métodos Abstractos: es obligatorio de implementación

    • Wilson Marino Pablo Mendez

      Exacto 👍

    • Brayan Mamani

      Son obligatorios.

028. Clases Anónimas

Descripción:

Las Clases Anónimas son una forma de instanciar clases abstractas sin necesidad de usar sus clases hijas. Pero este tipo de instanciación tiene algunas restricciones: el ciclo de vida de estas instancias NO es duradero, no las tendremos disponibles durante toda la ejecución del programa.

// Clase Abstracta:
public abstract class Figura {
    abstract void dibujar();
}

// Clase Anónima:
User user = new User() {
    @Override
    public void showDataUser() {
        // Instrucciones...
    }
};

Comentarios:

  • Félix Alejandro Zelaya Orellana

    Super!!

  • Jeffersson Muñoz Torres

    No entendí muy bien :C … si estamos hablando de clases anónimas porque los ejemplos es instanciar, entonces son objetos, por consiguiente no debería ser objetos anónimos?

    • Gerald Zamora

      No son objetos ya que los objetos se define como la instancia de una clase. Ella esta haciendo una instancia de tipo User que se llama user1, osea user1 es el Objeto, y para crear este Objeto se esta usando una clase anónima.

  • johnkegd

    si no me gustase tanto Java y el hecho de la capacidad que nos da de realizar cosas increibles, ya hubiese renunciado a este curso, el nivel de complejidad aumenta pero el nivel de amor incrementa, definitivamente debe ser asi.

  • Juan David Castro

    Java hace 1 hora : las clases son como moldecitos para crear objetos, solo debemos instanciarlas… Java hace 30 minutos : bueno, también existen las clases con métodos estáticos, estas funciones se pueden llamar/ejecutar sin necesidad de instanciar las clases… Java hace 10 minutos : bueno, también existen las clases abstractas, son clases que nunca instanciamos pero que nos permiten definir métodos opcionales u obligatorios de implementar en las clases que hereden de ellas… Java Ahora : bueno, también existen las clases anónimas, son un "hack" para instanciar clases abstractas… … 😳😳😳😳😂

    • caramirezc

  • JavierJ

    Clases Anónimas: van de la mano con las clases abstractas, es una forma de instanciar una clases abstracta de manera anónima.

029. Diferencias entre las Interfaces y las Clases Abstractas

Descripción:

Comentarios:

  • Félix Alejandro Zelaya Orellana

    Super!!

  • Luis Fernando Chacha Montenegro

    Clase Abstracta: No se instancian, solo se heredan. Cierto? 😃

    • Gerald Zamora

      parcial mente cierto, ya que si hay maneras de instanciarlas

    • Brayan Mamani

      Pero si las instancias no realizas una buena practica de programación.

  • andresazuara98

    Me causa un poco de conflicto y siento que lo hará en el examen, el hecho de que diga que no se puede heredar de una clase abstracta y luego diga que hay un pequeño hack para hacer una instancia

  • caramirezc

    "Forma en como nombramos: Clase abstracta: pensamos en objetos Interfaz: pensamos en acciones que pueden tener muchos objetos"

030. Interfaces en Java 8 y 9

Descripción:

Las Interfaces nos permiten usar métodos abstractos y campos constantes para implementar herencia/polimorfismo de forma muy similar a las clases abstractas.

A partir de Java 8 podemos tener implementación en métodos para heredar y reutilizar diferentes comportamientos. No todos los métodos de nuestras interfaces deben ser abstractos, ahora podemos usar el modificador de acceso default y desde Java 9 también private.

Recuerda que el nivel de acceso de default y private son los mismos que estudiamos en clases anteriores.

public interface MyInterface {

    // Métodos default: nos permite heredar la definición
    // de la función y también su implementación...
    default void defaultMethod() {
        privateMethod("Hello from the default method!");
    }

    // Métodos private: nos permiten definir comportamiento,
    // pero solo se puede usar desde otras clases de esta
    // interfaz, no se hereda a la clase hija....
    private void privateMethod(final String message) {
        System.out.println(message);
    }


    // Métodos abstractos: recuerda que todos los métodos
    // son abstractos por defecto...
    void normalMethod();

}

Comentarios:

  • edsonnlb

    Con este cambio, la interfaz y la clase abstracta parecen ser practicamente lo mismo. Sin embargo, la interfaz sigue siendo una abstracción completa (diseñada para que se implementen todos los métodos). La posibilidad de crear métodos default parace obedecer únicamente a facilitar la actualización de las interfaces sin que esto rompa las clases que ya la implementaban con anterioridad.

  • Bryan Fabricio Vásquez García

    Excelente!

  • Félix Alejandro Zelaya Orellana

    Genial! Buena información!

  • Alexis Navarro Ramos

    Muy buena clase 😄 ❤️

031. Herencia en interfaces

Descripción:

Las interfaces pueden heredar de otras interfaces utilizando la palabra clave extends, el concepto de herencia se aplicará como naturalmente se practica en clases, es decir, la interfaz heredará y adquirirá los métodos de la interfaz padre.

Una cosa interesante que sucede en caso de herencia con interfaces es que, aquí sí es permitido la herencia múltiple como ves a continuación:

public interface IReadable {
    public void read();
}

public interface Visualizable extends IReadable, Serializable {
    public void setViewed();
    public Boolean isViewed();
    public String timeViewed();
}

Además siguiendo las implementaciones de métodos default y private de las versiones Java 8 y 9 respectivamente podemos sobreescribir métodos y añadirles comportamiento, si es el caso.

public interface Visualizable extends IReadable, Serializable {
    public void setViewed();
    public Boolean isViewed();
    public String timeViewed();

    @Override
    default void read() {
        // TODO Auto-generated method stub
    }
}

Comentarios:

  • iesous_flor

    Vientos, aquí estoy repasando la teoría.

  • DubAvenXP

    Excelente explicacion!

  • Gerald Zamora

    ooh esto va a ser bastante útil.

  • Félix Alejandro Zelaya Orellana

    Genial!! Estas cositas no me las enseñaron

Ensamblando Objetos el proyecto

032. Simulando autenticación de usuarios

Descripción:

Comentarios:

  • Félix Alejandro Zelaya Orellana

    Super!!

  • johnkegd

    ¿son ideas mias o vas super rapido haciendo el código?

  • caramirezc

    equals: método de la clase Object

033. Modularizando la UI de Doctores

Descripción:

Comentarios:

  • Jeyson Alexandro Fernández Fabres

    muy bueno, pero falta mostrar el que se esta consiguiendo con el todo ese código

  • Félix Alejandro Zelaya Orellana

    Super loco, habrá que revisarlo con calma

  • Yone Moreno Jiménez

    Lo que hecho en falta del curso es ir mostrando el diagrama de clases en UML , a la par que el código de cada lección.

    Lo escribo porque hay gente que tiene un estilo de aprendizaje visual, a la que le ayuda a asentar lo aprendido un refuerzo al inicio y/o al final de la clase mediante una imagen general de lo que estamos construyendo.

    También sería interesante comprobar mediante la ejecución del programa , en el vídeo, el comportamiento correcto de lo que estamos añadiendo.

    El motivo es que en esta y la anterior lección, en las cuales se escribe bastante código, no se ejecutó el programa, y eso puede causar confusión a quienes nos cueste entender qué se logra con lo escrito.

    • William Camilo Guzmán Espitia

      Totalmente de acuerdo!

034. Definiendo las citas disponibles

Descripción:

Algunas veces necesitamos trabajar las fechas como tipo de dato Date y otras veces como String. Para resolver esto podemos usar SimpleDateFormat.

    SimpleDateFormat format = new SimpleDateFormat(pattern: "dd/MM/yyyy");

    // Transformar fechas de formato String a Date:
    this.date = format.parse(dateAsString);

    // Transformar fechas de formato Date a String:
    this.date = format.format(dateAsDate);

Comentarios:

  • Gerald Zamora

    en esta linea va a haber un problema

      System.out.println(monthSelected + " . " + UIMenu.MONTHS[monthSelected]);

    ya que va a mostrar un mes adelante del que se seleccionó lo correcto sería

      System.out.println(monthSelected + " . " + UIMenu.MONTHS[monthSelected - 1]);
  • oscargonzalezbonifacio

    Pero que no en java 8 se maneja diferente las fechas?

    • Gerald Zamora

      Hay muchas maneras de manejar fechas en java. Lo hubiera podido hacer con Calendar o GregorianCalendar por darte unos ejemplos, pero hay muchas maneras.

  • Oscar Fernando Ventura Ortiz

    Creo que este video se pudo haber hecho de una manera mas ordenada y mejor explicada, demasiado contenido y tratado a la carrera.

    • Yone Moreno Jiménez

      Síi estoy de acuerdo. ¿Quizá dejar los 11 primeros minutos en una parte y luego hacer una lección con los otros 4 minutos?. Porque al principio se trata de pedir la hora y hacer los cambios necesarios en Doctor para que pueda crear appointments en esa fecha.

  • mauricioTequita

    No seria mejor manejar una clase de utilidades con métodos para realizar tareas como por ejemplo el parseo de fechas?

    • danielveraec

      Me parece que si.

    • Brayan Mamani

      Seria una buena alternativa, pero se puede tener varias opciones.

035. Modularizando la UI de Pacientes

Descripción:

Comentarios:

036. Recorriendo estructuras de árbol en Java

Descripción:

Las estructuras de árbol pertenecen al grupo de estructuras de datos no lineales, es decir, donde toda la información es almacenada con un orden específico. En estas estructuras tenemos "troncos" principales con diferentes ramificaciones que surgen a partir de ellos. Son muy útiles para trabajar con grandes cantidades de datos organizados de forma jerárquica.

La forma de implementarlos en Java es usando un Map de tipo TreeMap. Recuerda que también podemos guardar Maps dentro de otros Maps. De esta forma podemos definir una lista ordenada de doctores y sus fechas disponibles para agendar citas médicas.

    // 1. Doctor#1
    // - - - Fecha#1
    // - - - Fecha#2

    // 2. Doctor#2
    // - - - Fecha#1
    // - - - Fecha#2

    // 3. Doctor#3
    // - - - Fecha#1
    // - - - Fecha#2

    Map<Integer, Map<Integer, Doctor>> doctors = new TreeMap<>();

Comentarios:

  • Gerald Zamora

    sinteticé un poco esta parte de "showBookAppointmentMenu" para que sea mas comprensible:

      int k = 0;
      for(Doctor doctor: UIDoctorMenu.doctorsAvailableAppointments){
    
          Map<Integer, Doctor>  doctorAppointments = new TreeMap<>();
    
          int j = 0;
          for(Doctor.AvailableAppointment appointment : doctor.getAvailableAppointments()){
              k++;
              System.out.println(k + ". " + appointment.getDate());
              doctorAppointments.put(Integer.valueOf(j++), doctor);
              doctors.put(Integer.valueOf(k), doctorAppointments);
          }
      }
  • Félix Alejandro Zelaya Orellana

    Super!!

  • johnkegd

    Bastante complejo me ha parecido, pero interesante. He tenido que ver cada video unas 3 veces.

037. Agendando Citas

Descripción:

Comentarios:

  • Gerald Zamora

    Eso fue difícil de digerir

  • Félix Alejandro Zelaya Orellana

    Ya me morí

  • juanbollati

    En cada par del TreeMap doctors se esta guardando un TreeMap con un solo elemento. El for que recorre este ultimo TreeMap no hace nada, solo se queda con el ultimo elemento, y funciona porque hay uno solo.

    Se debería cambiar esta estructura y que el TreMap de doctors no guarde otro TreeMap, que solo guarde una tupla…

038. Cierre del curso Continúa con Programación Funcional en Java

Descripción:

¡Felicitaciones por terminar el Curso de Introducción a Java SE!

En este curso aprendimos a implementar los 4 pilares de la programación orientada a objetos en Java con un proyecto para agendar citas médicas.

Recuerda resolver los ejercicios, completar el examen, darle 5 estrellas a la profesora y compartir tu proyecto, notas, dudas y comentarios en la sección de discusiones.

No olvides que puedes continuar tu ruta de aprendizaje de Java con los siguientes cursos:

  • Curso de Java SE: Programación Funcional

  • Curso de Java SE: Persistencia de Datos

Comentarios:

  • iesous_flor

    Excelente curso, seguimos con el avanzado.

  • DNAvacio

    De los cursos que menciona y que aun no estan si ese es el caso, creo que un adelanto de esos cursos se puede encontrar en el curso de java avanzado son los ultimos dos apartados de JDBC y Lambdas.

  • Christian zambrano

    Disuclpen Hay un curso que se hable de jaba bean jsp java faces es decir JAVA EE?

  • Gerald Zamora

    Estuvo muy bueno el curso!!!

  • Félix Alejandro Zelaya Orellana

    Qué genial!! Funciono todo

  • eduardo-moora

    no ecuentro los cursos de

    Curso de Java SE: Programación Funcional Curso de Java SE: Persistencia de Datos

    que mencionas 😦

    • jorge espinoza

      al parecer todavia no hacen el lanzamiento hasta hoy la fecha 01 de octubre de 2019, me dijo hace unos dias la propia anahi

  • Erick Alejandro Benitez Tenorio

    Excelente curso!

  • Yone Moreno Jiménez

    Si queremos mostrar las citas que un doctor tiene:

    1º En UIMenu ponemos la lista de patients como atributo de clase (para poder acceder a ella desde UIDoctorMenu)

      public static ArrayList<Patient> patients = new ArrayList<>();

    Quedando

      public class UIMenu{
    
          public static final String[] MONTHS = {"January", "February", "March", "April", "May", "June",
                                      "July", "August", "September", "October", "November", "December"};
    
          public static Doctor doctorLogged;
          public static Patient patientLogged;
          public static ArrayList<Patient> patients = new ArrayList<>();
    
      }

    2º Añadimos la función showScheduledAppointments en UIDoctorMenu

      private static void showScheduledAppointments(){
          int numberOfAppointments = 0;
          for (Patient patient : UIMenu.patients) {
              for (AppointmentDoctor appointmentDoctor : patient.getAppointmentDoctors()) {
                  if(appointmentDoctor.getDoctor() == UIMenu.doctorLogged){
                      numberOfAppointments++;
                      System.out.println(numberOfAppointments + ". " +
                              "Appointment with patient: " + patient.getName() +
                              "\nDate: " + appointmentDoctor.getDate() +
                              "Time: " + appointmentDoctor.getTime());
                  }
              }
          }
          if(numberOfAppointments == 0){
              System.out.println(UIMenu.doctorLogged.getName() + " you don't have appointments!");
          }
      }
3º Llamamos a la función desde showDoctorMenu()

```java
showScheduledAppointments();

Quedando:

public class UIDoctorMenu {

    public static ArrayList<Doctor> doctorsAvailableAppointments = new ArrayList<>();

    public static void showDoctorMenu(){
        int response = 0;
        do {
            System.out.println("\n\nWelcome doctor: " + UIMenu.doctorLogged.getName());

            System.out.println("1. Add available appointment");
            System.out.println("2. Show scheduled appointments");
            System.out.println("0. Exit");

            Scanner scanner = new Scanner(System.in);
            response = Integer.parseInt(scanner.nextLine());

            switch (response){
                case1:
                    showAddAvailableAppointmentMenu();
                    break;
                case2:
                    showScheduledAppointments();
                    break;
                case0:
                    UIMenu.showMenu();
            }

        }while(response != 0);
    }
}

Cuando no hay appointments:

Cuando un paciente sí agenda una cita:

```

  • Ricardo Coronado

    Gracias!!

  • jesus-jeff

    Este video dice que puedo continuar con Curso de Java SE: Programación Funcional Curso de Java SE: Persistencia de Datos

    pero no veo los cursos, cunado estarán disponibles ?

  • caramirezc

    Muchas gracias por la buena explicación Anahí.

  • juanbarcinilla

    Excelente curso gracias por compartir su conocimiento.

  • Claudio Jesus Vázquez Villanueva

    Cuando salen? Curso de Java SE: Programación Funcional Curso de Java SE: Persistencia de Datos

  • Alexander Mateo

    Muchas gracias Anahí @anncode 😄 aprendí mucho. 😃

  • Wilson Marino Pablo Mendez

    Un curso de gran valor. Gracias!!

  • Juan David Castro

    Los cursos de Java con Anahí siempre son espectaculares. 👏👏👏

Last updated