Aún no tienes acceso a esta clase

Crea una cuenta y continúa viendo este curso

Curso de Java SE Orientado a Objetos

Curso de Java SE Orientado a Objetos

Anahí Salgado Díaz de la Vega

Anahí Salgado Díaz de la Vega

Creando elementos estáticos

8/38
Recursos

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.

Aportes 71

Preguntas 20

Ordenar por:

¿Quieres ver más aportes, preguntas y respuestas de la comunidad? Crea una cuenta o inicia sesión.

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.

Para el id creo que deberíamos tener algo así:

static int nextValidId = 0;
int id;
Doctor() {
  id = nextValidId++;
}

Si no todos los objetos del tipo Doctor tendrían el mismo id, ya que al dejarlo como static el valor se comparte para todas las instancias del objeto.

Por momentos siento que va un poco rapido!!! solo soy yo o alguien mas le pasa?

Es la primera vez en mi vida que alguien usa el tag static en un import. No me arrepiento de haber tomado este curso

Al definir miembros de una clase como static (y recordando que los miembros de una clase son tanto sus variables -de instancia o no- como sus métodos), estos son implícitamente protected. Esto significa que puedes acceder a ellos desde clases que se encuentren dentro del mismo paquete, o desde la clase en sí misma, pero no puedes acceder a ellos desde clases que se encuentren fuera del paquete, de ahí la necesidad de Anahí de colocar el modificador de acceso public. De lo contrario, no hubiéramos podido acceder a esos miembros de la clase UIMenu

Hola
Para los que desean agregar validación extra al menú, dejo por acá el try{}catch() que utilicé en mi código:

public static void showMenu(){
        System.out.println("Welcome to my Appointments");
        System.out.println("Please type the number according to your user category");

        int response = 0;

        do{
            System.out.println("1. Doctor");
            System.out.println("2. Patient");
            System.out.println("0. Exit");

            Scanner typed = new Scanner(System.in);
            try{
                response = Integer.valueOf(typed.nextLine());
            }catch (NumberFormatException e){
                response = 9;
            }

            System.out.println(response);
            switch (response){

                case 1:
                    System.out.println("Welcome Doctor!!");
                    response = 0;
                    break;

                case 2:
                    System.out.println("Welcome Patient!!");
                    showPatientMenu();
                    break;

                case 9:
                    System.out.println("Hola \n The value received is not admitted, please try again.");
                    break;

                case 0:
                    System.out.println("It was nice to assist you. See you soon!");
                    break;


                default:
                    System.out.println("Hola! \n You typed an incorrect number, please type the number according" +
                            "to your user category");

            }

        }while(response != 0);
    }

    static void showPatientMenu(){
        int response = 0;

        do{
            System.out.println("\n\n");
            System.out.println("Patient");
            System.out.println("1. Book an appointment");
            System.out.println("2. My appointments");
            System.out.println("0. Return to the main menu");

            Scanner typed = new Scanner(System.in);
            try{
                response = Integer.valueOf(typed.nextLine());
            }catch (NumberFormatException e){
                response = 9;
            }

            switch (response){
                case 1:
                    System.out.println(":: Welcome to the booking appointment screen");
                    break;

                case 2:
                    System.out.println(":: Welcome to your appointments dashboard");
                    break;

                    case 9:
                    System.out.println("Hola \n The value received is not admitted, please try again.");
                    break;

                case 0:
                    showMenu();
                    break;

                default:
                    System.out.println("Hola! \n You typed an incorrect number, please type the number according" +
                            "to the available options from the menu");
            }

        }while (response != 0);
    }

Básicamente con esas líneas adicionales podremos manejar las excepciones cuando el usuario ingresa valores nulos o letras. Por otro lado manejamos todos los números incorrecto a través de default.
Saludos

Queda muy claro, las variables y los métodos estáticos pertenecen a la clase y no a la instancia de la clase.

Por fin entendí que es static. Gracias.

Cada vez que creo una instancia del objeto Doctor, el atributo id se incrementa, pero si luego imprimo uno a uno los atributos de las instancias, todas me muestran siempre el mismo id. Como puedo hacer para que el atributo id se mantenga independiente para cada instancia ?

el valor del id no se esta almacenando en la instancia sino en la clase, por lo cual si volvemos a imprimir el id de myDoctor luego de haber impreso el id de myDoctorAnn va a imprimir el valor 2.

<code>
    public static void main(String[] args) {
        Doctor myDoctor = new Doctor();
        myDoctor.id = 1;
        myDoctor.name = "ALejandro Rodríguez";
        myDoctor.showName();
        myDoctor.showId();

        System.out.println();

        Doctor myDoctorAnn = new Doctor();
        myDoctorAnn.name = "Annahi";
        myDoctorAnn.showName();
        myDoctorAnn.showId();

        System.out.println();

        myDoctor.showName();
        myDoctor.showId(); # este imprime 2
    }
</code>

✨ El valor de una variable estática prevalece más allá de la instanciación del objeto.

Este tema siempre se me ha hecho un poco confuso, pero creo que me quedo claro 😃

Woowww que clase, Gracias Miss!




Importamos un metodo estatico usando el import y la palabra reservada static y luego la direccion de la clase

La solución a esto es crear una variable estatica para tener el ultimo número y el id ser un atributo de instancia

public class Doctor {
    static int numerador = 0;

    int id;
    String name;
    String speciality;

    Doctor() {
        System.out.println("Construyendo el Objeto Doctor");
        id = ++numerador;
    }
    //Comportamientos
    public void showName() {
        System.out.println(name);
    }

    public void showId() {
        System.out.println("ID Doctor: " + id);
    }
}```

Me encantó este vídeo, esta super bien explicado por si alguien se quedó con dudas en esta clase
https://www.youtube.com/watch?v=29TnNxNzvZo&ab_channel=CharlyCimino

Conceptualmente ID no estaria mal interpretado?
Seria la cantidad de doctores, no su ID, ya que el mismo se pierde si se quiere volver a usarlo.

Todo iba bien hasta que sacó un código de la nada ya hecho, habría sido más cómodo que nos enseñara cómo lo hizo... :c

lastima que el curso siendo tan bueno, tengamos que omitir procesos y recurrir al gitHub a sacar lo que ya realizo , lo digo porque soy nuevo y me gusta aprender el proceso de cada cosa y no quedar con la duda de donde salio, pero lo tomo mas como que de la nada hice esto, mire si entendio y sigamos, lastima.

Los metodos showMenu y showPatientMenu no los he visto como los creaba, en las anteriores clases de anahi, alguien podria decirme si es que solo estan en los proyectos enlazados en la parte inferior o tambien los enseño como se construian. gracias

muy pobre explicacion de algunas cosas, como “vamos a quitar esto, y vamos a quitar esto” en el minuto 5:25. debería explicar todo, por qué si le quito el static a una variable debo “comentar” “System…(Doctor…);” ?

Siempre se queda corta en explicar los detalles y eso hace que no se pueda aprender todo con esta profesora

En nuestra clase anterior vimos que se puede realizar el cambio de una varible statica c desde otra clase a.
Esto no sucede en casos de la clase Math porque el programador la declró como constante(final).

mi aporte
main principal:

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

        mydoc.cont=1;

        mydoc md = new mydoc();//objeto 1
        md.name="Alex Cremento";
        md.showname();
        md.showSerialID();
        mydoc.showMenu();


        System.out.println("\n");


        mydoc d = new mydoc();//objeto 2
        d.name="Ana Busado de Hesa";
        d.showname();
        d.showSerialID();
        mydoc.showMenu();


    }
}

Clase mydoc:

import java.util.Scanner;
public class mydoc {


    static int IDglobal = 0;//atributo estático
    static int cont = 0; // contador estático
    String name; // atributo nombre

    mydoc (){//constructor
        System.out.println("----------Regristro "+ (cont++) + "----------");
        IDglobal++;
    }
    public void showname(){ //metodo mostrar nombre
        System.out.println("Nombre del doctor: "+ name);
    }
    public void showSerialID(){//metodo sin retorno mostrar ID serial
        System.out.println("Número de ID : "  +IDglobal);
    }

    public static void showMenu(){ // métodos estáticos
        int response = 0 ;
        do {
            System.out.println("1. Doctor");
            System.out.println("2. Patients");
            System.out.println("0. Exit");
            System.out.println("------------------------");
            System.out.println("Ingrese la opción: ");
            Scanner s = new Scanner(System.in);
            response = Integer.valueOf(s.nextLine());
            switch (response) {
                case 1:
                    response=0;
                    System.out.println("Doctor ");
                    break;
                case 2:
                    response = 0;
                    showPatientsMenu();
                    break;
                case 0:
                    System.out.println("Gracias por su visita!");
                    break;
                default:
                    System.out.println("Error de ingreso [x]");
            }
        }while (response != 0);

    }//fin showMenu

    public static void showPatientsMenu(){
        int response;
        do{
            System.out.println("\n\n");
            System.out.println("Patient");
            System.out.println("1. Book an appointment");
            System.out.println("2. My appointments");
            System.out.println("0. Return");
            Scanner sc = new Scanner(System.in);
            System.out.println("Ingrese la opción: ");
            response=Integer.valueOf(sc.nextLine());
            switch(response){
                case 0:
                        System.out.println("Volviendo al menú principal..");
                        showMenu();
                        break;
                case 1:
                    response=3;
                    System.out.println(":: Book an appointment");break;
                case 2:
                    response = 3;
                    System.out.println("2. My appointments");
                case 3:
                    System.out.println("Gracias por tu visita! ");break;
                default:
                    System.out.println("Por favor Ingrese la alternativa correcta [x]");
                    showPatientsMenu();
            }
        }while(response !=3);
    }




}

Las variables declaradas como estáticas (static) son, esencialmente, variables globales. Cuando se declara un objeto, no se realiza una copia de una variable estática. En cambio, todas las instancias de la clase comparten la misma variable estática. Aquí hay un ejemplo que muestra las diferencias entre una variable estática y una variable de instancia:

class StaticDemo
{
    int x; //Variable de instancia normal
    static int y; //Variable estática

    //Retornar la suma de la variable de instancia 'x'
    //y la variable estática 'y'
    int suma(){
        return x+y;
    }
}

class Test{
    public static void main(String[] args) {
        StaticDemo ob1=new StaticDemo();
        StaticDemo ob2=new StaticDemo();

        //Cada objeto tiene su propia copia de una variable de instancia
        ob1.x=10;
        ob2.x=12;

        System.out.println("Por supuesto, ob1.x y ob2.x son independientes.");
        System.out.println("ob1.x: "+ob1.x+"\nob2.x: "+ob2.x);
        System.out.println();

        //Cada objeto comparte una copia de una variable estática
        System.out.println("La variable estática 'y' es compartida.");
        StaticDemo.y=100;
        System.out.println("Cambio de StaticDemo.y a 100");

        System.out.println("ob1.suma(): "+ob1.suma());
        System.out.println("ob2.suma(): "+ob2.suma());
    }
}

Salida:

1. Palabra clave static

Para crear dicho miembro, preceda su declaración con la palabra clave static. Cuando un miembro se declara estático, se puede acceder antes de crear cualquier objeto de su clase y sin referencia a ningún objeto.

Puede declarar que tanto los métodos como las variables sean estáticos. El ejemplo más común de un miembro estático es . main() se declara como estático porque la JVM debe llamarlo cuando comienza tu programa. Fuera de la clase, para usar un miembro estático, solo necesita especificar el nombre de su clase seguido por el operador de punto. Ningún objeto necesita ser creado.

Por ejemplo, si desea asignar el valor 10 a una variable estática llamada contar que es parte de la clase Temporizador, use la siguiente línea:

Temporizador.contar = 10;

Este formato es similar al utilizado para acceder a las variables de instancia normales a través de un objeto, excepto que se utiliza el nombre de clase. Se puede invocar un método estático de la misma manera: mediante el uso del operador punto en el nombre de la clase.

es un modificador de no acceso en Java que se aplica a lo siguiente:

Variables
Métodos
Bloques
Clases anidadas

Compañeros, les comparto mis apuntes de la clase.

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

    Doctor myDoctor = new Doctor();
    myDoctor.name="Sandra Rodriguez";
    myDoctor.showName();
    myDoctor.showId();

    Doctor myDoctornn = new Doctor();
    myDoctor.showId();


}

}

Sinceramente me confundi un poco a la mitad de la clase pero al llegar a la esplicacion final entendi completamente! me encanta la manera que tienes de explicar las cosas.

Lo que realmente creo que deberías explicar con el public static, es que se toma como una variable Global.

De seguro que static me va a ser muy útil. Poder modular más es genial.

Al archivo Doctor.java le falta el método showId.
Aquí está:

public void showId()
    {
        System.out.println("ID Doctor: " + id);
    }

Muy interesante los usos del método static…
Por conceptualización no se llama una instancia 👍

Esa frase: “El Valor de una variable estática prevalece más allá de las instanciación del objeto”, me llegó al corazón.

increíble clase

Una consulta, porque falla la compilacion si al pasarlo el UIMenu al package, no agregamos public a la funcion showMenu:
public static void showmenu(){
si queda :
static void showmenu(){
da error.

Hola, una consulta, donde se encuentra el código base?

Buenas compañeros y profe…Una pregunta para variables no estaticas cada vez que creamos un constructor creamos un espacio en memoria para cada uno de los atributos??

Esto me recuerda a las librerías que contienen muchas funciones.

😃

Si una variable es estática el valor del dato prevalece más allá de la instanciación del objeto

Muy buena explicación de como crear variables estáticas

La llamada del id la hiciste por medio de un método, el resultado es el mismo si lo haces por medio del constructor, hay alguna diferencia que pueda afectar a futuro?

Excelente clase, muy interesante la forma de utilizar métodos static para ser llamados más fácilmente en otras clases.

Excelente es muy util para realizar clases con todos los metodos comunes de nuestro proyecto y poder usarlos en todas nuestras clases sin necesidad de crear objetos.

Buens compañeros y profe tengo una pregunta …Porque se pudo llamar la clase UImenu dentro del metodo main, si no se tiene un impor de la misma??

Excelente, ahora se como usar los metodos static

En una variable static el valor prevalece más allá de la instanciación del objeto

La verdad me gusto mucho, quedo genial.

Super 😃

Excelente explicacion!!

Solo quiero decir, que despues de años mirando de lejos la programación en el mundo TI, me estoy acercando perdiendo el miedo, de manos de este curso.

Requisitos para utilizar métodos estáticos sin nombrar a su clase contenedora:

  • Mover la clase a un paquete independiente
  • Poner los métodos, constantes y variables como public para ser accedidos desde fuera de su paquete
  • Hacer una importación estática del paquete donde está la clase con los métodos estáticos, import static paquete.MiClase
  • Traer todo el contenido de la clase con el operador *, import static paquete.MiClase*

Gracias, me sirvio mucho de ayuda

Pienso que el primer uso de static no estuvo del todo correcto, pues la variable iba creciendo para todos los objetos, puesto que es estatica todos los objetos creados compartirian el mismo valor.

En la clase se mostro que el valor para el primero era 1 y para el siguiente era 2, puesto que primero creamos el primer objeto, lo cual sumo 1, despues imprimimos el id, el cual era 1.
Despues creamos otro objeto, que cambio el valor a 2, y a partir de ahi unicamente se mostro el valor del segundo objeto, cuando el valor cambio tanto para el primero como para el segundo

Esta es una manera de implementar lo primero para que funcione.



public class Doctor{
    static double id=0;
    double dId;
    String name;
    String speciality;

    Doctor(String name, String speciality){
        id++;
        this.name= name;
        this.speciality=speciality;
        dId=id;
    }
    public void showName(){
        System.out.println(name);
    }
    public void showId(){
        System.out.println("El id de " + name + " es "+ (int)dId);
    }
}

ALGUIEN QUE ME AYUDE PORFA
Lo que aun no entiendo bien son estas lineas:
Scanner sc = new Scanner(System.in);
response = Integer.valueOf(sc.nextLine());

Cual es la diferencia en esta manera de hacer la entrada de datos:
Scanner sc = new Scanner(System.in);
int response = sc.nextInt;

Como nota, las variables estaticas son accesibles desde todos los lugares, por lo que cambiar el valor es cambiar su valor en todas las referencias, para asegurar un ID unico para cada doctor podría ser lo siguiente:

public class Doctor {

    static int ID = 0;//Autoincrement
    int id;
    String name, speciality;

    public Doctor() {
        System.out.println("Se ha creado un doctor");
        id = ++ID;
    }

    public Doctor(String name) {
        System.out.println("Se ha creado el doctor: " + name);
        id = ++ID;
    }

    public void showName() {
        System.out.println("El doctor se llama: " + name);
    }

    public void showId() {
        System.out.println("El ID del doctor es: " + id);
    }
}```

Excelente clase!

Me costo un poco entender, porque en el ejemplo la variable id, en realidad aumentaba de manera global (al ser static) y no se le asignaba un id único a cada objeto, lo solucione de esta manera:
Agrege una variable static idIncrement, y esa daba el valor al id

ublic class Doctor {
    int id = 0;//Autoincrement
    static int idIncrement = 1;
    String name;
    String speciality;

    Doctor(){
        System.out.println("Estamos construyendo el proyecto");
        id = idIncrement;
        idIncrement++;
    }

    Doctor(String name){
        System.out.println("El Doctor asignado es: " + name);
    }

    //Comportamientos

    public void showName(){
        System.out.println(name);
    }

    public void showID(){
        System.out.println("ID Doctor: " + id);
    }
}

Se debe agregar el modificador de acceso public a los métodos para poder ser invocados en otra clase de un paquete diferente

Deberíamos declarar id como:
private static int id;
para que no pueda ser accesada e incrementada por otra clase que no sea Doctor.

Se me ha quedado algo que puede llegar a ser muy importante, inclusive en diagnósticos y debug:
refiriéndose a una variable estática, “el valor del dato prevalece mas allá de la instanciación del objeto.” 06:19

Clase 8: Creando elementos estáticos

Para los que les apetezca tomar la clase en Eclipse iré subiendo mi código; hay pequeñas diferencias con Intellij, por no decir ninguna, pero con Eclipse se puede trabajar igual de bien.

Jerarquía del Proyecto


Archivo Main.java

package mymedicalappointment;

import static ui.UIMenu.*;

public class Main {

	public static void main(String[] args) {
		Doctor myDoctor = new Doctor();
		myDoctor.name = "Anahí Salgado";
		myDoctor.showName();
		myDoctor.showId();
		System.out.println(Doctor.id);
		
		Doctor.id++;
		
		Doctor myDoctorAnn = new Doctor();
		myDoctorAnn.showId();
		System.out.println(Doctor.id);
		
		showMenu();
	}
}


Archivo Doctor.java

package mymedicalappointment;

public class Doctor {
//	State/Attributes
	public static int id = 0;
	public String name;
	public String specialty;
	
//	Constructors
	public Doctor() {
		System.out.println("Construyendo el Objeto Doctor");
		id++;
	}
	
	public Doctor(String name) {
		System.out.println("El nombre del Doctor asignado es: " + name);
	}
	
//	Behavior
	public void showName() {
		System.out.println(name);
	}
	
	public void showId() {
		System.out.println("Id Doctor: " + id);
	}
}


Archivo UIMenu.java

package ui;

import java.util.Scanner;

public class UIMenu {
	 public static void showMenu(){
	        System.out.println("Welcome to My Appointments");
	        System.out.println("Selecciona la opción deseada");

	        int response = 0;
	        do {
	            System.out.println("1. Doctor");
	            System.out.println("2. Patient");
	            System.out.println("0. Salir");

	            Scanner sc = new Scanner(System.in);
	            response = Integer.valueOf(sc.nextLine());

	            switch (response){
	                case 1:
	                    System.out.println("Doctor");
	                    break;
	                case 2:
	                    response = 0;
	                    showPatientMenu();

	                    break;
	                case 0:
	                    System.out.println("Thank you for you visit");
	                    break;
	                default:
	                    System.out.println("Please select a correct answer");
	            }
	        }while (response != 0);
	    }

	    public static void showPatientMenu(){
	        int response = 0;
	        do {
	            System.out.println("\n\n");
	            System.out.println("Patient");
	            System.out.println("1. Book an appointment");
	            System.out.println("2. My appointments");
	            System.out.println("0. Return");

	            Scanner sc = new Scanner(System.in);
	            response = Integer.valueOf(sc.nextLine());

	            switch (response){
	                case 1:
	                    System.out.println("::Book an appointment");
	                    break;
	                case 2:
	                    System.out.println("::My appointments");
	                    break;
	                case 0:
	                    showMenu();
	                    break;
	            }
	        }while (response != 0);
	    }
}

Utilizaremos elementos static para que su scope sea mas allá de la clase y utilizarlos sin necesidad de instanciar la clase.

Me encantó esta clase, es súper útil tener métodos y variables estáticas.

Creando elementos estáticos

Los métodos estáticos son muy útiles cuando se quiere llamar a un método pero sin tener que instanciar una Clase, pues hace eso no quedaría bien a nivel de lógica, pues se instanciaría una Clase que sólo muestra elementos en pantalla pero que no tiene atributos ni nada más, lo cuál sería totalmente incensario.

En esos casos se puede crear un método statico y así mantener el código lo más limpio posible. Para empezar se puede crear un package y en su interior crear la Clase que muestra el menú.

package UI; // Relaciona la Clase con el package UI

import java.util.Scanner; // Importa Scanner una Clase que permite ingresar datos desde la terminal

public class UIMenu {
    // Métodos
        // Mostrar menú
        public static void showMenu() {
            // Código qu emuestra el ménú
        }   
}

Luego para usar ese método hay que importar el método estático para poder usarlo.

import static UI.UIMenu.*;

public class Main {

    public static void main(String[] args) {        
        // Mostar menú de la UI
        showMenu();
    }
}

Copie y pegue el código exactamente igual a como lo tiene la profe Anahí pero aún así me salen 5 warnings.

¿Alguien sabe por qué?

Que tan frecuente se usan este tipo de variables en un proyecto mas avanzado?