# Curso de Java SE Orientado a Objetos

> [¡Prueba la suscripción de Platzi!](https://platzi.com/r/NestorPlasencia/)

## 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()`.&#x20;

### 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) &#x20;

## 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

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

    }
}
```

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

```java
// 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:

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

Instanciar un Objeto:

```java
// 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:

```java
// Declarar el objeto ---- Instanciar el objeto
Doctor myDoctor = new Doctor();
```

1. Declara e instancia Doctor en clase Main

`src/Main.java`

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

`Run Main.main() -> output`

```bash
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&#x20;
* 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.

```java
public class Doctor {
    // Atributos...

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

```java
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`

```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`

```bash
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`

```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`

```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`

```bash
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:

```java
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

```java
public class Calculador {
    public static final double PI = 3.1415926;
    public static int suma(int a, int b){
        return a + b;
    }
}
```

```java
Calculadora.suma(5,2);
Calculadora.PI;
```

El scope y el nivel de acceso es global

```java
public class ClaseC {
    public static valor = 0;
}
```

```java
public class ClaseA {
    ClaseC.valor = ClaseC.valor + 1;
}
```

```java
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:

```java
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`

```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`

```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`

```bash
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`

```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`

```bash
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`

```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`

```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`

```bash
Construyendo el objeto Doctor
ID Doctor: 1
Construyendo el objeto Doctor
ID Doctor: 1
```

Add class `UIMenu`

`src/UIMenu.java`

```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`

```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`

```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`

```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:

```java
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

```java
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.

```java
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.

![](/files/-Lw9r9CkclZpuA_7UIhj)

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.

```java
int a = 1;
int b = a; // b = 1
```

> Si asigno el valor de un objeto a otro ojeto

`src/Main.java`

```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`

```bash
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)

```java
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.

```java
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.

```java
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

```java
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);

    }
}
```

```bash
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`.

```java
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);

    }
}
```

```bash
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**.

![Encapsulamiento: Modificadores de acceso](https://static.platzi.com/media/user_upload/Screen%20Shot%202019-07-16%20at%205.42.34%20PM-05985be5-929e-4e87-8137-c1c5b16c96c2.jpg)

![modificadoresAcceso.jpg](https://static.platzi.com/media/user_upload/modificadoresAcceso-c0f8004c-f28d-431b-8d2f-5eef98a94b43.jpg)

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.

```java
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!**

  ![Mind Blowing](https://media.tenor.com/images/2e2f908309dd8a576d1193506c16f147/tenor.gif)
* **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.
* **Srna**

  Take a look to the link below to know more about nested class

  Esp:<https://javadesdecero.es/poo/clases-anidadas/#forward>\
  Eng:<https://docs.oracle.com/javase/tutorial/java/javaOO/nested.html>
* **Wilson Marino Pablo Mendez**

  Para trabajar con fechas es necesario importar una librería

  ```java
    import java.util.Date
  ```

### 017. Clases Internas y Locales a un método

#### Descripción:

#### Comentarios:

* **Gerald Zamora**

  Pero esas no son todas, faltan las clases anónimas. No?
* **Félix Alejandro Zelaya Orellana**

  Interesante y loco!
* **johnkegd**

  la verdad es que al ver estas clases me empezo a doler la cabeza un poco, pero me lo tomare con calma.
* **Srna**

  Take a look to the link below to learn more about inner classes

  Esp: <https://javadesdecero.es/poo/clases-internas/>\
  Eng: <https://www.tutorialspoint.com/java/java_innerclasses>

### 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.**

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

Puedo crear referencias de enumerations de la siguiente forma:

```java
    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í:

```java
    Day.MONDAY;
    Day.FRIDAY;
    Day.SATURDAY
```

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

```java
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í:

```java
System.out.println(Day.MONDAY);
```

*Imprimirá:* **MONDAY**

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

*Imprimirá:* **Lunes**

#### Comentarios:

* **Samuel Narciso**

  ```java
    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.

  ```java
        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 " ; "

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

  así

  ```java
    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.

```java
        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**
  * [Don’t repeat yourself](https://en.wikipedia.org/wiki/Don%27t_repeat_yourself)
  * [The DRY Principle Explained: Its Benefit and Cost with Examples](http://web-techno.net/dry-principle-explained/)
  * [Lesson 1. Intro to DRY code](https://www.earthdatascience.org/courses/earth-analytics-bootcamp/loops/intro-dry-code/)
  * [Is Your Code DRY or WET?](https://dzone.com/articles/is-your-code-dry-or-wet)
  * [Stop trying to be so DRY, instead Write Everything Twice (WET)](https://dev.to/wuz/stop-trying-to-be-so-dry-instead-write-everything-twice-wet-5g33)
  * [SOLID Principles-simple and easy explanation](https://hackernoon.com/solid-principles-simple-and-easy-explanation-f57d86c47a7f)
  * [DESIGN PATTERNS: DON’T REPEAT YOURSELF – VIDEO AND RESOURCES](https://iamtimcorey.com/design-patterns-dry/)
* **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*.

```java
public class User {
    int age = 1
    public int getAge() {
        return this.age;
    }
}
```

```java
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:

  ```java
    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

  * **FixingMind5**

    Puedes entrar al curso de [Programación Orientada a Objetos](https://platzi.com/clases/oop/) ahí se ve lo más importante de la diagramación con UML.
* **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*.

```java
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](https://docs.oracle.com/javase/8/docs/api/java/lang/Comparable.html) 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

  ```java
        @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](https://docs.oracle.com/javase/8/docs/api/java/util/Arrays.html) que tiene un método static sort()\
  Ejemplo de su uso:

  ```java
    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:

![IMG1.png](https://static.platzi.com/media/user_upload/IMG1-b5d51fc9-f21a-47c9-960c-409d2cf43f7d.jpg)

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.

![IMG2.png](https://static.platzi.com/media/user_upload/IMG2-48dd5387-187c-4193-b74b-b205ee81376d.jpg)

Sigamos con Map

Lo primero que debes saber es que tiene tres implementaciones:

HashTable\
LinkedHashMap\
HashMap\
SortedMap ➡️ TreeMap

![img3.png](https://static.platzi.com/media/user_upload/img3-105ac91c-3d09-4ed5-a5cc-3b0a21f3c12b.jpg)

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:

```java
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

```java
// 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

```java
// 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

```java
// 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](https://docs.oracle.com/javase/tutorial/collections/interfaces/deque.html) 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**

  ![](https://www.adictosaltrabajo.com/wp-content/uploads/2015/09/java-collections-img1.png)\
  Un pequeño aporte a la comunidad
* **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**

  La Deque es una estructura que permite inserciones y borrados al principio y al final.\
  ![](https://qph.fs.quoracdn.net/main-qimg-0963b373f0e1156e6ef34e6235eb6712)
* **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) &#x20;
  * 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.

```java
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.

```java
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.

```java
// 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**

    ![](https://media.giphy.com/media/sVJQGDjEVIBwY/giphy.gif)
* **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.

```java
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();

}
```

![Encapsulamiento: Modificadores de acceso](https://static.platzi.com/media/user_upload/Screen%20Shot%202019-07-16%20at%205.42.34%20PM-05985be5-929e-4e87-8137-c1c5b16c96c2.jpg)

#### 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:

```java
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.

```java
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`.

```java
    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

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

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

  ```java
    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:

* **Juan David Castro**

  **Más sobre estructuras de árbol:**

  * [Estructuras de Datos - Curso de Básico de Algoritmos en Platzi](https://platzi.com/clases/1469-algoritmos/16967-estructuras-de-datos/)
  * [Diagrama de árbol (treemap) - HighBond](https://help.highbond.com/helpdocs/results/current/user-guide/es/Content/visualizations/interpretations/charts/treemap_chart.htm)

### 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.

```java
    // 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:

  ```java
    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)

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

  Quedando

  ```java
    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

  ```java
    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:

```java
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:

![](https://i.imgur.com/LeMiybM.png)

Cuando un paciente sí agenda una cita:

![](https://i.imgur.com/ebHXqkR.png)

\`\`\`

* **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. 👏👏👏*


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://kitybear.gitbook.io/cursospedia/plataformas/platzi/rutas-de-aprendizaje/desarrollo-con-java/curso-de-java-se-orientado-a-objetos-1629.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
