2015-11-19 17 views
31

Ich versuche zu verstehen, warum es einen Unterschied zwischen Zugänglichkeit von Klassenmitgliedern gibt, wenn man über Konstruktoren spricht.Java private Konstruktoren Sichtbarkeit

Betrachten Sie das folgende Beispiel:

class A { 
    static class B { 
    private B(String s) {} 
    private void foo() {} 
    } 
    static class C extends B { 
    public C(String s) { 
     super(s); // call B(String), which is private, and obviously accessible 
    } 
    void bar() { 
     foo(); // compilation error (symbol unknown), as B.foo() is private 
    } 
    } 
} 

Privat Mitglieder A, als privat zu sein, sollte von B nicht zugänglich sein. Für Felder und Methoden ist dies der Fall, aber es scheint, dass Konstruktoren nicht der gleichen Regel folgen.

Vom JLS-8 (6.6.1. Determining Accessibility), können wir lesen:

[...]

Element (Klasse, Schnittstelle, Feld, oder das Verfahren) eines Referenztyp oder ein Konstruktor eines Klasse-Typ ist, nur zugänglich, wenn die Art zugänglich ist und das Element oder Konstruktor deklariert Zugang zu ermöglichen:

  • [...]

  • Andernfalls wird das Element oder der Konstruktor als private deklariert, und der Zugriff ist nur dann zulässig, wenn er im Rumpf der obersten Klasse (§7.6) erfolgt, der die Deklaration des Elements oder Konstruktors einschließt.

Kann mir jemand erklären, warum der Konstruktor von C zugänglich ist, auch während private erklärt werden?

+1

Nur weil Sie super aufrufen können, heißt das nicht, dass der Konstruktor zugänglich ist – michaelsnowden

+2

Kann mir jemand erklären, warum der Konstruktor von C aus zugänglich ist, auch wenn er als privat deklariert wird? -> Weil B und C innere Klassen von A sind. Funktioniert nicht mehr, wenn Sie B und C nach A bewegen. –

+3

@ JörnBuitink: Wenn das der Fall ist, warum ist 'foo()' * nicht * zugänglich? Es scheint hier eine Inkonsistenz zu geben. –

Antwort

25

Die Methode foo() ist privat, also erben Sie sie nicht und können sie nicht direkt aus der Klasse C aufrufen.

Sie können jedoch private Methoden und Konstrukteur von B sehen, da alles in der gleichen enthaltenden Klasse deklariert ist, und greifen Sie mit super, weshalb super() funktioniert. Auf die gleiche Weise können Sie auf foo mit super.foo() zugreifen.

Beachten Sie, dass Sie eine neue Foo-Methode in C neu definieren können, aber diese Methode überschreibt B.foo() nicht.

+0

Vielen Dank für Ihre Antworten WilQu & @benzonico. Es scheint der Trick zu sein. Ich akzeptiere deine Antwort. –

3

Also hier der Trick könnte die folgende sein:

Sie nicht foo zugreifen, da sie privat deklariert ist, so dass Sie es in C.

erben nicht jedoch, wie in den Kommentaren darauf hingewiesen wurde, die Sie zugreifen können super.foo();, weil sich super auf einen Typ bezieht, der in derselben Top-Level-Klasse deklariert ist (siehe dazu JLS 6.6.1).

Dann ist der Trick, dass super(s) Aufruf kann als Aufruf super.<init>(s) betrachtet werden, die den gleichen Fall endet als wie super.foo()

-2

Foo() -Methode nicht zugänglich in der Klasse C ist, als foo() Methode ist privat und privat Methode kann nicht an die Basisklasse vererbt werden.

Für Konstrukteure, CONSTRUCTORS NIE VERERBT. Auch ich diesen Code kompiliert:

class Vehicle{ 
     int speed=50; 
     private Vehicle() 
     { 
      System.out.println("Private Vehicle constructor"); 
     } 
    } 
    public class Bike4 extends Vehicle{ 
     int speed=100; 
    Bike4() 
    { 
     super(); 
     System.out.println("Hi I n constructor"); 
    } 
    void display(){ 
    System.out.println(super.speed);//will print speed of Vehicle now 
    } 
    public static void main(String args[]){ 
    Bike4 b=new Bike4(); 
    b.display(); 

} 
} 

Und bekommen Zeit kompilieren Fehler: Fahrzeug() hat einen privaten Zugang in Fahrzeug super(); ^ Das zeigt eindeutig, dass ein privater Konstruktor nicht mit Super zugegriffen werden kann. Wenn wir in der Lage sind, einen privaten Konstruktor zu initialisieren oder darauf zuzugreifen, was ist dann der Grund, einen privaten Konstruktor zu erstellen?

+0

Bitte sehen Sie andere Antworten, Ihre ist nicht wirklich relevant für die Frage. – benzonico

Verwandte Themen