2016-08-07 14 views
1

Die Superklassenreferenzvariable kann das Unterklassenobjekt enthalten, aber mit dieser Variablen können Sie nur auf die Mitglieder der Oberklasse zugreifen. Daher wird empfohlen, immer auf die Elemente beider Klassen zuzugreifen Referenzvariable für die Unterklasse.Schwierigkeit mit dem Konzept der Java-Vererbung und des Überschreibens

class Animal { 
    public void move() { 
     System.out.println("Animals can move"); 
    } 
} 

class Dog extends Animal { 
    public void move() { 
     System.out.println("Dogs can walk and run"); 
    } 
    public void bark() { 
     System.out.println("Dogs can bark"); 
    } 
} 

public class TestDog { 

    public static void main(String args[]) { 
     Animal a = new Animal(); // Animal reference and object 
     Animal b = new Dog(); // Animal reference but Dog object 

     a.move(); // runs the method in Animal class 
     b.move(); // runs the method in Dog class 
     b.bark(); 
    } 
} 

Ausgang:

TestDog.java:26: error: cannot find symbol 
    b.bark(); 
^
symbol: method bark() 
location: variable b of type Animal 
1 error 

Was ich nicht verstehe, ist hier, warum das Objekt ‚b‘ in der Lage, um das Dog.move() und nicht Dog.bark(), weil die URL oben besagt, dass es nur auf die Mitglieder der Oberklasse und nicht auf die Unterklasse zugreifen kann. Nach dieser Logik sollte die Ausgabe von b.move() "Tiere können sich bewegen" und nicht "Hunde können laufen und laufen". Aber das ist nicht der Fall. Kann mir jemand dabei helfen? Vielen Dank im Voraus!

+0

b.bark typecasting(); ist falsch, weil Animal nicht bellt.Ein Downcasting ist erforderlich wie: ((Hund) b) .bark(); –

Antwort

1

Herzlichen Glückwunsch - Sie haben gerade Polymorphie entdeckt.


In Java sind die Klassen dynamisch gebunden. Das heißt, wenn Sie eine Methode aufrufen, wird die Implementierung des Objekts aufgerufen (in Ihrem Fall die Dog) und nicht die Methode des Referenztyps (in Ihrem Fall die Animal).

Dies ermöglicht das Überschreiben von Methoden und ersetzen oder erfüllen ihre Implementierung.


Auf der anderen Seite können Sie Zugriffsmethoden nur, dass Sie in der Art vorhanden sind verweisen, nicht auf die Implementierung Typen (in Ihrem Fall der Animal). Um die Methoden der Instanz aufzurufen, müssten Sie sie als Referenztyp verwenden (in Ihrem Fall Dog).

+0

Vielen Dank @Fabian Damken. – cooltogo

0

Dieser Code ist falsch, da die Zeile b.bark(); Ihnen einen Compilerfehler gibt, weil b nur als ein Tier definiert ist, das nicht bellen kann().

Wenn Sie Animal b = new Dog(); zu Dog d = new Dog(); ändern, wird es ordnungsgemäß funktionieren.

Sie haben Vererbung vermischt. Hund kann tun, was Tier tun kann, nicht umgekehrt.

class Animal { 
    public void move() { 
     System.out.println("Animals can move"); 
    } 
} 



class Dog extends Animal { 
    @Override public void move() { 
     System.out.println("Dogs can walk and run"); 
    } 
    public void bark() { 
     System.out.println("Dogs can bark"); 
    } 
    public void moveSuper() { 
     super.move(); 
    } 
} 



public class TestDog { 

    public static void main(final String args[]) { 
     final Animal a = new Animal(); // Animal reference and object 
     a.move(); // runs the method in Animal class 

     final Dog d = new Dog(); // Animal reference but Dog object 
     d.move(); // runs the method in Dog class 
     d.bark(); 
     d.moveSuper(); 
    } 
} 
1

Dieses seit Animal nicht kompiliert werden nicht über eine Methode namens bark.

Betrachten Sie es auf diese Weise, alle Hunde sind Tiere, aber nicht alle Tiere sind Hunde. Alle Hunde bellen, aber nicht alle Tiere bellen.

1

In Ihrer Frage Animal ist eine Elternklasse, die keine bark() Methode hat, so dass die Methode nicht überschrieben wird. Wenn Sie von der Elternklasse auf bark() zugreifen könnten, ohne eine der abstrakten Methoden zu deklarieren oder zu definieren, dann wäre dies eine Verletzung des Prinzips Polymorphism.

Wenn Sie es wirklich für den Zugriff auf diese Art und Weise wollen, dann können Sie entweder eine abstract public void bark(); in Ihrer Eltern definieren oder diese Methode zugreifen, indem ähnliche

((Dog) b).bark();