2013-06-12 9 views
6

Voglio alcune discussioni su questo argomento, ma non ho potuto inferire la risposta per il mio caso. Ancora bisogno di aiuto.Java: impossibile accedere ad un membro protetto della superclasse nella sottoclasse di espansione

Ecco il mio codice:

package JustRandomPackage; 

public class YetAnotherClass{ 
    protected int variable = 5; 
} 
package FirstChapter; 

import JustRandomPackage.*; 

public class ATypeNameProgram extends YetAnotherClass{ 
    public static void main(String[] args) { 

     YetAnotherClass bill = new YetAnotherClass(); 
     System.out.println(bill.variable); // error: YetAnotherClass.variable is not visible 

    } 
} 

alcune definizioni a seguito della quale, l'esempio di cui sopra sembra essere fonte di confusione:

1. Subclass is a class that extends another class. 
2. Class members declared as protected can be accessed from 
    the classes in the same package as well as classes in other packages 
    that are subclasses of the declaring class. 

La domanda: Perché non è possibile Accedo al membro protetto (int variable = 5) da un'istanza sottoclasse YetAnotherClass (bill oggetto)?

+1

Qual è la domanda? –

risposta

3

Le classi in altri pacchetti che sono sottoclassi della classe dichiarante possono accedere solo ai membri ereditati protected.

public class ATypeNameProgram extends YetAnotherClass{ 
    public ATypeNameProgram() { 
     System.out.println(this.variable); // this.variable is visible 
    } 
} 

... ma non di altri oggetti ereditato protected membri.

public class ATypeNameProgram extends YetAnotherClass{ 
    public ATypeNameProgram() { 
     System.out.println(this.variable); // this.variable is visible 
    } 

    public boolean equals(ATypeNameProgram other) { 
     return this.variable == other.variable; // error: YetAnotherClass.variable is not visible 
    } 
} 
+0

Questo è sbagliato. Questo codice viene compilato. Una classe in un altro pacchetto può accedere solo ai membri protetti ereditati che sono dello stesso tipo della classe stessa. –

1

bill non fa parte della sottoclasse YetAnotherClass. bill è una classe separata di YetAnotherClass.

Prova int bill = this.variable; (all'interno di un costruttore) per accedere ai membri della sottoclasse.

0

Non si sta creando un'istanza della classe che la estende, ma della classe genitore. Controllare il codice qui sotto:

public class ATypeNameProgram extends YetAnotherClass{ 
    public static void main(String[] args) { 

     YetAnotherClass bill = new YetAnotherClass(); 
     System.out.println(bill.variable); // error: YetAnotherClass.variable is not visible 

     ATypeNameProgram a = new ATypeNameProgram(); 
     System.out.println(a.variable); //this will work 

    } 
} 
1

Il codice funziona se YetAnotherClass sarà nello stesso pacchetto come ATypeNameProgram. Come altri hanno scritto, non funzionerà in altri casi. Ecco l'esempio funzionante.

package my.example; 

public class MainClass extends MyAnotherClass { 
    public static void main(String[] args) { 
     MyAnotherClass bill = new MyAnotherClass(); 
     System.out.println(bill.value); // this will work 
    } 
} 

package my.example; 

public class MyAnotherClass { 

    protected int value = 5; 

} 
1

Una classe Foo possono accedere solo i membri di istanza protette di tipo Bar se e solo se Bar è assegnabile a Foo. Vale a dire, se si può scrivere:

Foo foo = new Bar(); 

Per esempio, dire che abbiamo:

package a; 

public class Base { 
    protected int protectedField; 
} 

allora possiamo avere questa:

package b; 

import a.Base; 

public class Parent extends Base { 
    void foo() { 
     int i = this.protectedField; 
    } 
    void foo(Parent p) { 
     int i = p.protectedField; 
    } 
    void foo(Child c) { 
     int i = c.protectedField; 
    } 
} 

class Child extends Parent { } 

Questo compilerà perché tutti protectedField s sono accessibili tramite istanze di Parent. Si noti che poiché un riferimento a Parent può essere un'istanza Child (ad esempio, è possibile scrivere Parent p = new Child();), è possibile accedere a c.protectedField.

Quanto segue non compilazione:

package b; 

import a.Base; 

public class Parent extends Base { 
    void foo(Stepchild sc) { 
     int i = sc.protectedField; // ERROR 
    } 
} 

class Stepchild extends Base {} 

perché un'istanza di Stepchild non è un'istanza di Parent.

Un po 'confusamente, questo non verrà compilato uno:

package b; 

import a.Base; 

public class Parent extends Base {} 

class Child extends Parent { 
    void foo(Parent p) { 
     p.protectedField; // ERROR 
    } 
} 

questo è perché un oggetto Parent non è una superclasse o superinterfaccia di Child, e così Child non può accedere ai suoi membri protetti.

Se avete problemi a ricordare, pensate solo se il tipo può essere scritto o meno su un riferimento del tipo della classe. Ad esempio, si può scrivere:

Parent p = new Child(); 

ma non può scrivere

Child c = new Parent();  // ERROR 
Parent p = new Stepchild(); // ERROR 

così Child non avrà accesso ai Parent 's membri protetti, e Parent non avrà accesso ai Stepchild' s membri protetti .

Un paio di punti finali:

Ricordate che protected accesso consente visibilità tra il pacchetto. Nella mia esperienza, la gente dimentica questo.

Infine, i membri di protected static sono sempre visibili nella gerarchia di ereditarietà.

Problemi correlati