En PC Resumen hablaremos de las herencias en Java. La herencia es una de las herramientas fundamentales de la programación orientada a objeto porque permite la creación de clasificaciones jerárquicas. Mediante la herencia el programador puede crear una clase general que defina las características comunes de un conjunto de términos relacionado. Esta clase puede ser heredada por otras clases más específicas, cada una de las cuales añadirá nuevas características.

En Java, una clase que es heredada llama superclase y la clase que hereda denomina subclase.

Para heredar una clase sólo tenemos que incorporar la palabra clave extends. Vemos el siguiente programa el cual crea una superclase llamada A y una subclase llamada B. Fíjese en la utilización de la palabra clave extends.

// Creación de la superclase A.
class A {
    int i, j;
    void showij() {
        System.out.println("i y j:" + y + "" + j);
    }
}

// Creación de la subclase B

class B extends A {
    int k;
    void showk () {
        System.out.println("k:" + k);
    }

    void suma () {
        System.out.println("i + j + k:" + (i + j + k));
    }
}

class SimpleHerencia {
    public static void main (String args[]) {
        A superOb = new A();
        B subOb = new B();

        // La superclase se puede utilizar por sí misma
 
        superOb.i = 10;
        superOb.j = 20;
        System.out.println ("Contenidos de superOb:");
        superOb.showij();
        System.out.println();

        / * La subclase accede a todos los miembros públicos de la su superclase. * /

        subOb.i = 7;
        subOb.j = 8;
        subOb.k = 9;
        System.out.println("Contenidos de subOb:");
        subOb.showij();
        subOb.showk();
        System.out.println();
        System.out.println("Suma de i, j y k a subOb:");
        subOb.suma();
    }
}

Hay que tener claro que estas dos clases son independientes. El hecho de ser una superclase para una subclase no impide que pueda ser utilizada por sí sola. Además una subclase puede ser una superclase para otra subclase.

Sólo se puede especificar una superclase para cada subclase que creamos. Java no permite que una subclase herede de muchas superclases.

Acceso a miembros y herencia

Aunque una subclase incluye todos los miembros de una superclase, no puede acceder a aquellos miembros de las superclases que hayan sido declarados como private. Por ejemplo:

class A {
    int i; // público predeterminado.
    private int j; // private a A.
    void setij(int x, int y) {
        y = x; 
        j = y;
    }
}

// Aquí no se puede acceder a la variable j de A.

class B extends A {
    int total;
    void suma () {
        total = i + j; // ERROR, no se puede acceder a j aquí.
    }
}

class Access {
    public static void main(String args[]) {
        B subOb = new B();
        subOb.setij(10, 12);
        subOb.suma();
        System.out.println("Total is" + subOb.total);
    }
}

Este programa no se compilará porque la referencia a j dentro del método suma() de B provoca una violación de acceso. Como j ha declarado private, sólo es accesible por otros miembros de su propia clase.

Ejemplo práctico

Veremos ahora un ejemplo más práctico que nos ayudará a entender el poder de la herencia. En este caso, extenderemos la clase Caja para incluir un cuarto componente llamado peso.

class Caja {
    double anchura;
    double altura;
    double profundidad;

    // Construcción de un duplicado

    Caja(Caja ob) { // Pasa un objeto al constructor.
        anchura = ob.amplada;
        altura = ob.altura;
        profundidad = ob.profundidad;
    }

    Caja(double w, double h, double d) {
        anchura = w;
        altura = h;
        profundidad = d;
    }

    Caja() {
        anchura = -1;
        altura = -1;
        profundidad = -1;
    }

    Caja(double instalan) {
        anchura = altura = profundidad = instalan;
    }

    double volumen() {
        return ancho * altura * profundidad;
    }
}

// Aquí, se extiende Caja para incluir el peso.

class CajaPeso extends Caja {
    double peso;
    
    // Constructor para CaixaPes.

    CajaPeso(double w, double h, double d, double m) {
        anchura = w;
        altura = h;
        profundidad = d;
        peso = m;
    }
}

class DemoCaixaPes {
    public static void main(String args[]) {
        CajaPeso cajaMia1 = new CajaPeso(10, 20, 15, 34.3);
        CajaPeso cajaMia2 = new CajaPeso(2, 3, 4, 0.076);
        double volumen;
        volumen = caixameva1.volumen();
        System.out.println("Volumen de cajaMia1 es" + volumen);
        System.out.println("Peso of cajaMia1 es" + cajaMia1.peso);
        System.out.println();
        volumen = cajaMia2.volumen();
        System.out.println("Volumen de cajaMia2 es" + vuelo);
        System.out.println("Peso of cajaMia2 es" + cajaMia2.peso);
    }
}

La principal ventaja de la herencia es que, una vez se ha creado una superclase que define los atributos comunes a un conjunto de objetos, puede utilizarse para crear cualquier número de subclases más específicas. Cada subclase puede adoptar de forma más precisa su propia clasificación. Por ejemplo, la siguiente clase hereda de Caja y le añade un atributo color.

class CajaColor extends Caja {
    int color;
    CajaColor(double anchura, double altura, double profundidad, int color) {
        this.ancho = ancho;
        this.altura = altura;
        this.profundidad = profundidad;
        this.color = color;
    }
}

Una variable de superclase puede referirse a un objeto de una subclase

A una variable de referencia de una superclase se le puede asignar cualquier subclase derivada de esta superclase. Este aspecto de la herencia resulta muy útil en gran cantidad de ocasiones. Por ejemplo:

class RefDemo {
    public static void main (String args []) {
        CajaPeso pesoCaja = new CajaPeso(3, 5, 7, 08:37);
        Caja cajaSimple = new Caja();
        double volumen;
        volumen = pesoCaja.volum();
        System.out.println("Volumen de pesoCaja es" + vuelo);
        System.out.println("Peso de pesoCaja es" + pesCaixa.pes);
        System.out.println();
        
        // Se asigna una referencia de CajaPeso a una referencia de Caja.
        
        cajaSimple = pesoCaja;
        volumen = cajaSimple.volum(); // OK, volumen() se define en Caja.
        System.out.println("Volumen de cajaSimple es" + volumen);
        
        / * La siguiente sentencia no es válida, ya que peso no es miembro de Caja * /
        // System.out.println("El peso de cajaSimple es" + cajaSimple.peso);
    }
}

Otro uso de super

La segunda forma de super actúa de forma similar a este, excepto en que siempre hace referencia a la superclase de la subclase en la que se utiliza. La forma general es la siguiente:

super.miembro

En este caso miembro puede ser tanto un método como una variable de instancia. Esta forma de super tiene una mayor aplicación en situaciones en las que los nombres de miembros de una subclase ocultan miembros del mismo nombre en la superclase.

Pin It