// Este programa utiliza la herencia para extender la clase Box. class Box { double width; double height; double depth; Box(Box ob) { width = ob.width; height = ob.height; depth = ob.depth; } Box(double w, double h, double d) { width = w; height = h; depth = d; }
Box() { width = -1; height = -1; depth = -1; } Box(double len) { width = height = depth = len; } double volume() { return width * height * depth; } } class BoxWeight extends Box { double weight; // peso de la caja BoxWeight(double w, double h, double d, double m) { width = w; height = h; depth = d; weight = m; } } class DemoBoxWeight { public static void main(String args[]) { BoxWeight mybox1 = new BoxWeight(10, 20, 15, 34.3); BoxWeight mybox2 = new BoxWeight(2, 3, 4, 0.076); double vol; vol = mybox1.volume(); System.out.println("Volumen de mybox1 es " + vol); System.out.println("Peso de mybox1 es " + mybox1.weight); System.out.println(); vol = mybox2.volume(); System.out.println("Volumen de mybox2 es " + vol); System.out.println("Peso de mybox2 es " + mybox2.weight); } }
class RefDemo { public static void main(String args[]) { BoxWeight weightbox = new BoxWeight(3, 5, 7, 8.37); Box plainbox = new Box(); double vol; vol = weightbox.volume(); System.out.println("El volumen de weightbox ex " + vol); System.out.println("El peso de weightbox es " + weightbox.weight); System.out.println(); // asigna una referencia de BoxWeight a una referencia de Box plainbox = weightbox; vol = plainbox.volume(); // OK, volume() definido en Box System.out.println("Volumen de plainbox es " + vol); /* La siguiente sentencia no es válida porque plainbox no define un miembro llamado weight. */ // System.out.println("El peso de plainbox es " + // plainbox.weight); } }
La palabra reservada super permite a una subclase referenciar a su superclase inmediata. Es utilizada en las siguientes situaciones:
En este caso super()
debe ser la primera sentencia ejecutada dentro del constructor.
Ejemplo de uso en caso 1
class BoxWeight extends Box { double weight; BoxWeight(double w, double h, double d, double m) { super(w, h, d); // llama al constructor de la superclase weight = m; } BoxWeight(BoxWeight ob) { super(ob); weight = ob.weight; } }
Ejemplo de uso en caso 2: P19/UseSuper.java
// Utilización de super para evitar la ocultación de nombres class A { int i; } class B extends A { int i; // esta i oculta la i de A B(int a, int b) { super.i = a; // i in A i = b; // i in B } void show() { System.out.println("i en la superclase: " + super.i); System.out.println("i en la subclase: " + i); } } class UseSuper { public static void main(String args[]) { B subOb = new B(1, 2); subOb.show(); } }
// Muestra cuando se ejecutan los constructores. class A { A() { System.out.println("En el constructor de A."); } } class B extends A { B() { System.out.println("En el constructor de B."); } } class C extends B { C() { System.out.println("En el constructor de C."); } } class CallingCons { public static void main(String args[]) { C c = new C(); } }
La salida del programa es:
En el constructor de A. En el constructor de B. En el constructor de C.
class A { int i, j; A(int a, int b) { i = a; j = b; } void show() { System.out.println("i y j: " + i + " " + j); } } class B extends A { int k; B(int a, int b, int c) { super(a, b); k = c; } // muestra k -- sobreescribe el metodo show() de A void show() { System.out.println("k: " + k); } } class Override { public static void main(String args[]) { B subOb = new B(1, 2, 3); subOb.show(); // llama al metodo show() de B } }
Cuando un método sobreescrito se llama a través de una referencia de la superclase, Java determina la versión del método que debe ejecutar en función del objeto que está siendo referenciado.
class A { void callme() { System.out.println("Llama al metodo callme dentro de A"); } } class B extends A { void callme() { System.out.println("Llama al metodo callme dentro de B"); } } class C extends A { void callme() { System.out.println("Llama al metodo callme dentro de C"); } }
class Dispatch { public static void main(String args[]) { A a = new A(); // objeto de tipo A B b = new B(); // objeto de tipo B C c = new C(); // objeto de tipo C A r; // obtiene una referencia del tipo A r = a; // r hace referencia a un objeto A r.callme(); // llama al metodo callme() de A r = b; // r hace referencia a un objeto B r.callme(); // llama al metodo callme() de B r = c; // r hace referencia a un objeto C r.callme(); // llama al metodo callme() de C } }
class Figure { double dim1; double dim2; Figure(double a, double b) { dim1 = a; dim2 = b; } double area() { System.out.println("Area para Figure es indefinida."); return 0; } }
class Rectangle extends Figure { Rectangle(double a, double b) { super(a, b); } double area() { System.out.println("Dentro de Area para Rectangle."); return dim1 * dim2; } } class Triangle extends Figure { Triangle(double a, double b) { super(a, b); } double area() { System.out.println("Dentro de Area para Triangle."); return dim1 * dim2 / 2; } } class FindAreas { public static void main(String args[]) { Figure f = new Figure(10, 10); Rectangle r = new Rectangle(9, 5); Triangle t = new Triangle(10, 8); Figure figref; figref = r; System.out.println("Area es " + figref.area()); figref = t; System.out.println("Area es " + figref.area()); figref = f; System.out.println("Area es " + figref.area()); } }
abstract tipo nombre(parámetros);
Ejemplo: P24/AbstractAreas.java
abstract class Figure { double dim1, dim2; Figure(double a, double b) { dim1 = a; dim2 = b; } abstract double area(); } class Rectangle extends Figure { Rectangle(double a, double b) { super(a, b); } double area() { System.out.println("Dentro del metodo area para un Rectangle."); return dim1 * dim2; } }
class Triangle extends Figure { Triangle(double a, double b) { super(a, b); } double area() { System.out.println("Dentro del metodo area para un Triangle."); return dim1 * dim2 / 2; } } class AbstractAreas { public static void main(String args[]) { // Figure f = new Figure(10, 10); // Esto no es correcto Rectangle r = new Rectangle(9, 5); Triangle t = new Triangle(10, 8); Figure figref; // esto es CORRECTO, no se crea ningún objeto figref = r; System.out.println("Area es " + figref.area()); figref = t; System.out.println("Area es " + figref.area()); } }
Los métodos declarados como final no pueden ser sobreescritos
Se usa final en la declaración de la clase para evitar que la clase sea heredada: O sea, todos sus métodos serán final implícitamente.
Ejemplo de uso en caso 2
class A { final void meth() { System.out.println("Este es un metodo final."); } } class B extends A { void meth() { // ERROR! No se puede sobreescribir. System.out.println("No es correcto!"); } }
Ejemplo de uso en caso 3
final class A { // ... } // La clase siguiente no es válida. class B extends A { // ERROR! No se puede crear una subclase de A // ... }