2009-04-11 31 views
6

me preguntaba si hay una característica del lenguaje Java en el que los métodos de una superclase serían invisibles para los miembros de una subclase:Estructura de clases protegida en Java?

public class Subclass extends protected Superclass 

o algo así. Daré un ejemplo.

Aquí está su superclase.

public class A{ 
    public String getA(){...} 
    public String getB(){...} 
    public String getC(){...} 
    public void setA(String a){...} 
    public void setB(String b){...} 
    public void setC(String c){...} 
} 

Si desea subclase A la vez que protege algunos de sus métodos, y no se puede cambiar en los métodos de acceso modifyers ser que los redefina, acabaría con algo como esto:

public class B extends A{ 
    private String getA(){return super.getA();} 
    private String getB(){return super.getB();}//These four methods have 
    private void setA(String a){super.setA(a);}//to be redeclared. 
    private void setB(String b){super.setB(b);} 

    public String getC(){return super.getC();}//These two methods can be 
    public void setC(String c){super.setC(c);}//removed. 
    public String getD(){...} 
    public void setD(String d){...} 
} 

o eso, o se puede mantener una instancia privada de a y tener algo como esto:

public class B{ 

    private A obj; 

    private String getA(){return obj.getA();} 
    private String getB(){return obj.getB();}//These four methods can also 
    private void setA(String a){obj.setA(a);}//be removed. 
    private void setB(String b){obj.setB(b);} 

    public String getC(){return obj.getC();}//These two methods are 
    public void setC(String c){obj.setC(c);}//redeclared. 
    public String getD(){...} 
    public void setD(String d){...} 
} 

¿puede tener algo que toma tanto de una manera que no tiene que redeclare cualquier método?

Respuesta

10

No hay herencia "no pública" en Java, a diferencia de la situación en C++.

La herencia crea una relación de subtipado. Cualquier instancia de B también es una instancia de A, y debería responder a los mismos mensajes. Si las instancias de B claramente no responden a todos los mensajes a los que responden las instancias de A, entonces la herencia sería inapropiada de todos modos.

Su última solución (B no hereda de A) es la adecuada: no crea una relación de subtipado, solo use un tipo para implementar (secretamente) el otro.

+0

+1 para comparar con C++ (que tiene herencia privada y protegida). –

+0

Cuando solía enseñar C++ avanzado, solía dibujar diagramas de Venn para mostrar las relaciones de subtipado, y mostrar lo que se ve dentro y fuera de las subclases, me pareció muy eficaz para demostrar el concepto. Sin embargo, sentí que a menudo era más problemático de lo que valía. – Uri

2

Aparte de establecer los campos/métodos en privado en la superclase, no creo que haya una forma de evitar esto.

creo que su mejor mejor sería su segunda opción, donde la clase B contiene una referencia privada a la clase A.

3

no creo que es o debería ser posible.

Si usa la herencia para que B amplíe A, debería poder usar un objeto B como un objeto A. Por ejemplo, esto sería posible:

A obj = new B(); 

Ahora el programa no tiene forma de saber que no se puede llamar a algunos de los métodos públicos de A.

Y sin herencia, la redefinición de funciones es inevitable.