2011-08-18 25 views
7

Sto leggendo Thinking In Java al momento e ho riscontrato un piccolo problema. Sto facendo esercizio 12 dal capitolo 8.Classe interna ed ereditarietà Java

Creare un'interfaccia con almeno un metodo, nel proprio pacchetto. Crea una classe in un> pacchetto separato. Aggiungi una classe interna protetta che implementa l'interfaccia. In un terzo> pacchetto, ereditate dalla vostra classe e, all'interno di un metodo, restituite un oggetto della classe interna protetta, l'upcasting all'interfaccia durante il ritorno.

Così ho creato questi file .java:

A.java

package c08; 
    public interface A 
    { 
     void one(); 
    } 

Pr2.java

package c082; 
    import c08.*; 
    public class Pr2 
    { 
     protected class InPr2 implements A 
     { 
      public void one() {System.out.println("Pr2.InPr2.one");} 
      protected InPr2() {} 
     } 
    } 

Ex.java

package c083; 
    import c082.*; 
    import c08.*; 
    class Cl extends Pr2 
    { 
     A foo() 
     { 
      InPr2 bar=new InPr2(); 
      return bar; 
     } 
    } 

E il mio NetBeans IDE sottolinea

InPr2(); 

e dice che: InPr2() ha protetto l'accesso a C082.Pr2.InPr2 e sto chiedendo perché. Se non dichiari esplicitamente che il costruttore di InPr2 dovrebbe essere protetto, sarebbe accessibile solo nel pacchetto C082, ma quando erediterò la classe Pr2 non sarà disponibile nella classe Cl, perché InPr2 è protetto? Va tutto bene quando cambio costruttore in pubblico.

+2

possibile duplicato del [Impossibile accedere classe interna protetta mentre ereditando] (http://stackoverflow.com/questions/1487734/cant- è protetto dall'accesso-protetto-interno-classe-while) – Kal

risposta

2

Dovrebbe funzionare perfettamente come si ha, ad eccezione di cambiare il protected InPr2() {} a public InPr2() { }. In altre parole "chiunque può istanziare questa classe SE può vedere la classe per cominciare".

+0

Questo è vero, ma in excersise si dice che dovrei rendere questa classe interna come protetta, e mi chiedevo perché dopo aver ereditato e reso protetto il costruttore non funzionasse. – Andrew

+0

Poiché l'accesso alla classe è limitato a 'quelli con accesso protetto a 'Pr2''. Questo include 'C1' perché estende' Pr2'. Il costruttore all'interno di 'InPr2' è tuttavia disponibile solo per' quelli con accesso protetto a 'InPr2', che a questo punto sono solo' InPr2' e 'Pr2'. Ha senso ciò? L'accesso per utilizzare la classe e utilizzare la funzione di costruzione ha un ambito diverso. – corsiKa

4

Il costruttore di InPr2 è protetta, il che significa che solo le classi che ereditano da InPr2 (nonPr2) possono chiamare. Le classi che ereditano da Pr2 possono vedere la classe Pr2, ma non possono chiamare i membri protetti, come il costruttore protetto.

+1

Ha senso, avevo solo l'impressione che se avessi ereditato Pr2 dovrei ottenere automaticamente l'accesso alla classe protetta. – Andrew

+0

@Andrew: Sì, quindi credo che C1 dovrebbe essere in grado di vedere la _class_ 'InPr2', poiché' InPr2' è un membro protetto di 'Pr2'. Il costruttore, tuttavia, non è un membro di 'Pr2'. – RustyTheBoyRobot

1

Anche se la classe InPr2 è accessibile in Cl, suo costruttore non è. Un costruttore protetto è accessibile solo a sottoclassi e classi nello stesso pacchetto.

0

Cambio:

Pr2.java

package c082; 
import c08.*; 
public class Pr2 
{ 
    protected class InPr2 implements A 
    { 
     public void one() {System.out.println("Pr2.InPr2.one");} 
     // This constructor was available only 
     // to a class inheriting form Pr2.InPr2 - protected InPr2() {} 
     public InPr2() {} 
    } 
} 

Il costruttore da Pr2.InPr2 era solo a disposizione di una classe se si estendeva Pr2.InPr2.

-1

nessuna classe in java può essere protetta.

+1

Puoi spiegare la tua risposta un po '..? – NREZ

0

Le variabili membro, i metodi ei costruttori protetti non sono accessibili al di fuori del pacchetto a meno che non siano ereditati. Quando proviamo a creare un oggetto di InPr2 il compilatore mostrerà un errore in quanto il costruttore protetto non è accessibile al di fuori del pacchetto. La creazione di un oggetto dipende anche dal modificatore di accesso del Costruttore.

È possibile fare una cosa: InPr2 può essere ereditata all'interno di classe C.