// 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
// ...
}