2009-04-11 2 views
6

Mi chiedevo se c'è una caratteristica del linguaggio Java in cui i metodi di una superclasse sarebbero invisibili per i membri di una sottoclasse:Struttura di classe protetta in Java?

public class Subclass extends protected Superclass 

o qualcosa del genere. Darò un esempio.

Ecco la tua superclasse.

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){...} 
} 

Se si desidera creare una sottoclasse A, proteggendo alcuni dei suoi metodi, e non è possibile cambiare modifyers accesso a metodi meno che vengano modificate, che ci si finisce con qualcosa come questo-

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){...} 
} 

uno che o è possibile mantenere un'istanza privata di a e avere qualcosa di simile:

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){...} 
} 

si può avere qualcosa che richiede sia in un modo che non si dispone di alcun metodo ridichiarare?

risposta

10

Non esiste un'eredità "non pubblica" in Java, diversamente dalla situazione in C++.

L'ereditarietà crea una relazione di sottotitoli. Qualsiasi istanza di B è anche un'istanza di A e dovrebbe rispondere agli stessi messaggi. Se le istanze di B chiaramente non rispondono a tutti i messaggi a cui le istanze di A rispondono, allora l'ereditarietà sarebbe comunque inappropriata.

L'ultima soluzione (B non eredita da A) è quella appropriata: non si crea una relazione sottotipizzazione, basta usare un tipo per implementare (segretamente) l'altro.

+0

+1 per il confronto con C++ (che ha un'eredità protetta e privata). –

+0

Quando insegnavo C++ avanzato, disegnavo diagrammi di Venn per mostrare le relazioni di sottotitoli e mostrare ciò che si vede all'interno e all'esterno delle sottoclassi, trovavo molto efficace dimostrare il concetto. Tuttavia, sentivo che spesso erano più problemi di quanti ne valesse la pena. – Uri

2

Altro che impostare campi/metodi su privato nella superclasse, non credo che ci sia un modo per aggirare questo.

penso che la tua migliore migliore sarebbe la seconda opzione, dove la classe B contiene un riferimento privato a classe A.

3

Non credo che è o dovrebbe essere possibile.

Se si utilizza l'ereditarietà in modo che B estende A, si dovrebbe essere in grado di utilizzare un oggetto B come oggetto A. Per esempio, questo sarebbe possibile:

A obj = new B(); 

Ora il programma non ha modo di sapere che non è possibile chiamare alcuni dei metodi pubblici di A.

E senza ereditarietà, la ridefinizione delle funzioni è inevitabile.