Hacer referencia a objetos de subclase con referencia de subclase frente a superclase

Requisito previo: herencia
En Java, todos los métodos no estáticos se basan en el tipo de tiempo de ejecución del objeto subyacente en lugar del tipo de referencia que apunta a ese objeto. Por lo tanto, no importa qué tipo use en la declaración del objeto, el comportamiento será el mismo.

Cómo referir un objeto de subclase

Hay dos enfoques para referir un objeto de subclase. Ambos tienen algunas ventajas/desventajas sobre el otro. El efecto de la declaración se ve en los métodos que son visibles en tiempo de compilación.

  1. Primer enfoque (Referencia usando referencia de superclase): una variable de referencia de una superclase se puede usar para referir cualquier objeto de subclase derivado de esa superclase. Si los métodos están presentes en SuperClass, pero SubClass los anula, será el método anulado el que se ejecutará.
  2. Segundo enfoque (Hacer referencia usando referencia de subclase): una referencia de subclase se puede usar para referir su objeto.

Considere un ejemplo que explique ambos enfoques.

// Java program to illustrate 
// referring to a subclass
// base class
class Bicycle 
{
    // the Bicycle class has two fields
    public int gear;
    public int speed;
          
    // the Bicycle class has one constructor
    public Bicycle(int gear, int speed)
    {
        this.gear = gear;
        this.speed = speed;
    }
          
    // the Bicycle class has three methods
    public void applyBrake(int decrement)
    {
        speed -= decrement;
    }
          
    public void speedUp(int increment)
    {
        speed += increment;
    }
      
    // toString() method to print info of Bicycle
    public String toString() 
    {
        return("No of gears are "+gear
                +"\n"
                + "speed of bicycle is "+speed);
    } 
}
  
// derived class
class MountainBike extends Bicycle 
{
      
    // the MountainBike subclass adds one more field
    public int seatHeight;
  
    // the MountainBike subclass has one constructor
    public MountainBike(int gear,int speed,
                        int startHeight)
    {
        // invoking base-class(Bicycle) constructor
        super(gear, speed);
        seatHeight = startHeight;
    } 
          
    // the MountainBike subclass adds one more method
    public void setHeight(int newValue)
    {
        seatHeight = newValue;
    } 
      
    // overriding toString() method
    // of Bicycle to print more info
    @Override
    public String toString() 
    {
          
        return (super.toString()+
                "\nseat height is "+seatHeight);
    }
      
}
  
// driver class
public class Test 
{
    public static void main(String args[]) 
    {
        // using superclass reference
        // first approach
        Bicycle mb2 = new MountainBike(4, 200, 20);
          
        // using subclass reference( )
        // second approach
        MountainBike mb1 = new MountainBike(3, 100, 25);
          
        System.out.println("seat height of first bicycle is " 
                                            + mb1.seatHeight);
              
        // In case of overridden methods
        // always subclass 
        // method will be executed
        System.out.println(mb1.toString());
        System.out.println(mb2.toString());
  
        /* The following statement is invalid because Bicycle
        does not define a seatHeight. 
        // System.out.println("seat height of second bicycle is " 
                                                + mb2.seatHeight); */
                      
        /* The following statement is invalid because Bicycle
        does not define setHeight() method. 
        mb2.setHeight(21);*/
  
    }
}

Producción:

seat height of first bicycle is 25
No of gears are 3
speed of bicycle is 100
seat height is 25
No of gears are 4
speed of bicycle is 200
seat height is 20

Explicación del programa anterior:

  • Se crea el objeto de la clase MountainBike, al que se hace referencia mediante la referencia de subclase ‘mb1’. Usando esta referencia tendremos acceso a ambas partes (métodos y variables) del objeto definido por la superclase o subclase. Vea la imagen a continuación para una comprensión clara.
    MountainBike mb1 = new MountainBike(3, 100, 25);
    

    z

  • Ahora volvemos a crear el objeto de la clase MountainBike, pero esta vez se hace referencia mediante el uso de la referencia de bicicleta de la superclase ‘mb2’. Usando esta referencia tendremos acceso solo a aquellas partes (métodos y variables) del objeto definido por la superclase.
    Bicycle mb2 = new MountainBike(4, 200, 20);
    

    a

  • Dado que la referencia ‘mb1’ tiene acceso al campo ‘seatHeight’, imprimimos esto en la consola.
    System.out.println("seat height of first bicycle  is " + mb1.seatHeight);
    
  • Si hay métodos presentes en la superclase, pero anulados por la subclase, y si se crea el objeto de la subclase, cualquier referencia que usemos (ya sea subclase o superclase), siempre será el método anulado en la subclase que se ejecutará. Entonces, a continuación, dos declaraciones llamarán al método toString() de la clase MountainBike.
    System.out.println(mb1.toString());
    System.out.println(mb2.toString());
    
  • Dado que la referencia hecha por ‘mb2’ es del tipo Bicycle , obtendremos un error de tiempo de compilación en la siguiente declaración.
    System.out.println("seat height of second bicycle  is " + mb2.seatHeight);
    
  • Nuevamente, la referencia hecha por ‘mb2’ es del tipo Bicycle, por lo que obtendremos un error de tiempo de compilación en la siguiente declaración.
    mb2.setHeight(21);
    

    Uso de fundición tipográfica

    En el ejemplo anterior, hemos visto que al usar la referencia ‘mb2’ del tipo Bicicleta, no podemos llamar a métodos específicos de subclase o acceder a campos de subclase. Este problema se puede resolver utilizando la conversión de tipos en Java. Por ejemplo, podemos declarar otra referencia, por ejemplo, ‘mb3’ de tipo MountainBike y asignarla a ‘mb2’ mediante el encasillado.

    // declaring MountainBike reference
    MountainBike mb3;
    
    // assigning mb3 to mb2 using typecasting.
     mb3 = (MountainBike)mb2;
    

    Entonces, ahora las siguientes declaraciones son válidas.

    System.out.println("seat height of second bicycle  is " + mb3.seatHeight);
    mb3.setHeight(21);
    

Cuándo ir por primera aproximación (Referencia usando referencia de superclase)

Si no conocemos el tipo de tiempo de ejecución exacto de un objeto, entonces deberíamos usar este enfoque. Por ejemplo, considere una ArrayList que contenga diferentes objetos en diferentes índices. Ahora, cuando tratamos de obtener elementos de arraylist usando el método ArrayList.get(int index) , debemos usar la referencia de objeto , ya que en este caso, no conocemos el tipo de tiempo de ejecución exacto de un objeto. Por ejemplo :

/* Java program to illustrate referring to a subclass
using superclass reference variable */
import java.util.ArrayList;
  
public class Test 
{
       public static void main(String args[]) 
       {
           ArrayList al = new ArrayList(2);
             
           // adding String object to al
           al.add(new String("GeeksForGeeks"));
             
           // adding Integer object to al
           al.add(new Integer(5));
             
           // getting all elements using Object reference
           for (Object object : al)
           {
               System.out.println(object);
           }    
       }
}

Producción:

GeeksForGeeks
5

Ventaja: podemos usar la referencia de superclase para contener cualquier objeto de subclase derivado de ella.

Desventaja: al usar la referencia de superclase, tendremos acceso solo a aquellas partes (métodos y variables) del objeto definido por la superclase. Por ejemplo, no podemos acceder a la variable seatHeight o llamar al método setHeight(int newValue) usando la referencia de bicicleta en el primer ejemplo anterior. Esto se debe a que están definidos en la subclase, no en la superclase.

Cuándo optar por el segundo enfoque (Hacer referencia usando una referencia de subclase)

Si conocemos el tipo de tiempo de ejecución exacto de un objeto, entonces este enfoque es mejor. Usando este enfoque, también podemos llamar métodos específicos de un objeto en particular. Por ejemplo :

/* Java program to illustrate referring to a subclass
using subclass reference variable */
import java.util.ArrayList;
  
public class Test 
{
       public static void main(String args[]) 
       {
           ArrayList al = new ArrayList(2);
             
           // adding String objects to al
           al.add(new String("GeeksForGeeks"));
           al.add(new String("for java archives"));
             
              
           // getting  elements using String reference
            String str1 = (String)al.get(0);
            String str2 = (String)al.get(1);
              
            System.out.println(str1);
            System.out.println(str2);
              
            // using String class specific method
            System.out.println(str1.length());
            System.out.println(str2.substring(4,8));
       }
}

Producción:

GeeksForGeeks
for java archives
13
java

Ventaja: al usar la referencia de subclase, tendremos acceso a ambas partes (métodos y variables) del objeto definido por la superclase o subclase. Por ejemplo, podemos llamar al método setHeight(int newValue) o al método speedUp(int increment) usando la referencia MountainBike en el primer ejemplo anterior.

Desventaja: podemos usar la referencia de la subclase para mantener solo los objetos de esa subclase en particular.

Referencia: StackOverflow

Este artículo es una contribución de Gaurav Miglani . Si le gusta GeeksforGeeks y le gustaría contribuir, también puede escribir un artículo usando contribuya.geeksforgeeks.org o envíe su artículo por correo a contribuya@geeksforgeeks.org. Vea su artículo que aparece en la página principal de GeeksforGeeks y ayude a otros Geeks.

Escriba comentarios si encuentra algo incorrecto o si desea compartir más información sobre el tema tratado anteriormente.

Publicación traducida automáticamente

Artículo escrito por GeeksforGeeks-1 y traducido por Barcelona Geeks. The original can be accessed here. Licence: CCBY-SA

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *