2017-05-30 2 views
-1

Ich bin ein Student, Java zu lernen. Ich weiß, protected bedeutet Zugriff von children oder the same package. Hier erben und überschreiben wir eine geschützte Methode. Und wenn die Basisklasse nach einer solchen Aktion ihre eigene Methode aufrufen will, ruft sie die neue überschriebene aus der Unterklasse auf. Ich habe das für eine Weile getestet und die Ausführungsreihenfolge mit Kommentaren markiert. Aber ich kann nicht verstehen, warum es nicht die Basismethode aufruft, wenn ich das aus dem Basisklassenkonstruktor herausrufe.Warum ruft der Aufruf einer Methode aus der Basisklasse die Child-Methode auf?

public class Solution { 

    public static void main(String[] args) { 
     new B(); // first 
    } 

    public static class A { 

     public A() { 
      initialize(); // third 
     } 

     protected void initialize() { 
      System.out.println("class A"); // we never go here 
     } 
    } 

    public static class B extends A { 

     public B() { 
      super(); // second 
      initialize(); // fifth 
     } 

     protected void initialize() { 
      System.out.println("class B"); // fourth, sixth 
     } 
    } 
} 

Das ist eine Aufgabe von einer Website ist, so dass im Grunde ist die Lösung Zugriffsmodifikator der initialize Methode protected-private zu ändern. Aber ich verstehe immer noch nicht, warum das Problem passiert.

+0

Ich denke, es ist nur Aufruf der überschriebenen Methode, weil Sie den Super von der Klasse aufrufen, die es überschreibt, so dass es immer diese Methode aus der B-Klasse verwenden wird? –

+0

Das ist der springende Punkt beim Überschreiben ... –

Antwort

0

Als Dakoda beantwortet, ist die Ursache polymorphism. Das bedeutet, dass wir untergeordnete Objekte erstellen können, sie jedoch als ihren übergeordneten Typ bezeichnen. Wenn wir die Methoden der übergeordneten Ebene aufrufen, beziehen wir uns tatsächlich auf die Methoden des untergeordneten Objekts.

In meinem Fall erstelle ich ein Kindobjekt (markiert // zuerst) B, das seinen eigenen Körper der initialize Methode hat. Eine Nuance der Vererbung ist, dass sie keine Konstruktoren enthält, so dass ich den Konstruktor der Eltern aufrufen kann (markiert // Sekunde). Im Konstruktor des Parents rufe ich die Methode initialize auf - das ist der Polymorphismus, weil ich die Methode des Kinds von seiner Eltern-Abstraktionsschicht aus anrufe. Hier

ist die Antwort auf die Frage - dies geschieht, weil wir nur Speicher für eine B Instanz zugewiesen, das heißt, wir haben A als unsere Basis und begann, sie zu verlängern (während wir etwas nach innen überschreiben können). Die einzigen beiden Dinge, die wir haben, sind:

  1. Wir Konstruktor erstellt (es war nicht in der Basis enthalten sind, wie oben erwähnt)
  2. Wir überschrieb die initialize Methodencode. Der Code für diese Methode innerhalb der Basis ist jetzt für dieses Objekt verloren.

Dieses Konzept der polymorphism ist so ausgelegt, und es gibt keine Möglichkeit für uns, die Basis Methode zuzugreifen, es sei denn wir speziell ein Objekt erstellen, die entweder A selbst oder ein Kind ist, dass diese Methode nicht überschreiben.

1

Was Sie versuchen, ist der Zweck des Polymorphismus zu besiegen. Sie können, aber Sie müssen den Anruf speziell machen. Fügen Sie Ihrer Methode einen booleschen Wert hinzu und rufen Sie den Befehl super.initialize (Boolean) auf. Auch dies besiegt den Polymorphismus und die ausdehnende Klasse muss über die Superklasse Bescheid wissen. Nicht sehr elegant.

public class Solution { 
    public static void main(String[] args) { 
     new B(); // first 
    } 

    public static class A { 

    public static boolean USE_SUPER = true; 

     public A() { 
      initialize(USE_SUPER); 
     } 

     protected void initialize(boolean unusedHere) { 
      System.out.println("class A"); 
     } 
    } 

    public static class B extends A { 
     public static boolean USE_EXTENDED = false; 

     public B() { 
      super(); 
      initialize(USE_EXTENDED); 
     } 

    protected void initialize(boolean useSuper) { 
     if (useSuper) 
       super.initialize(useSuper); 
     else 
       System.out.println("class B"); 
    } 
} 

    } 
+0

@SamKruglov, Wenn A.initialize() unterscheidet sich von B.initialize(), warum Polymorphie verwenden? Nennen Sie sie anders. A.initializeA() und B.initializeB(). – Dakoda

+0

Oh ja, ich denke, ich habe es verstanden. Wir haben nur Objekt B erstellt, daher haben wir nur Methoden aus dieser Perspektive. Und das Aufrufen der Methode vom Elternteil impliziert nur Polymorphismus. Vielen Dank! – Sam

Verwandte Themen