wake-up-neo.com

Wie rufe ich die überschriebene Methode einer Superklasse auf?

Wie kann ich die eat and drink-Methode der Klasse Animal mit der Instanz myAnimal im Code aufrufen?

public class Animal {
    public void eat() {
        System.out.println("Animal Eats");
    }

    public void drink() {
        System.out.println("Animal Drinks");
    }
}

public class Cat extends Animal {
    @Override
    public void eat() {
        System.out.println("Cat Eats");
    }

    @Override
    public void drink() {
        System.out.println("Cat Drinks");
    }

    public static void main(String[] args) {
        Cat myCat = new Cat();
        myCat.eat();
        myCat.drink();

        Animal myAnimal = myCat;        
        myAnimal.eat();
        myAnimal.drink();
    }
}

Ausgabe, die ich bekomme: 

Cat Eats
Cat Drinks
Cat Eats
Cat Drinks

Dies ist meine erwartete Ausgabe:

Cat Eats
Cat Drinks
Animal Eats
Animal Drinks
38
Hisham Muneer

Du kannst nicht machen, was du willst. Der Polymorphismus funktioniert, indem Sie das tun, was Sie sehen.

Grundsätzlich weiß eine Katze immer, dass es sich um eine Katze handelt, und verhält sich immer wie eine Katze, unabhängig davon, ob Sie Katzen behandeln, Felis, Felinae, Felidae, Feliformia, Carnivora, Theria, Mammalia, Wirbeltiere, Chordata, Eumetazoa, Animalia Objekt oder sonstiges :-)

61
TofuBeer

Hier haben Sie die Möglichkeit zu wählen, welche Methode Sie aufrufen möchten:

public class Cat extends Animal {

    public void superEat() {
        super.eat();
    }

    public void superDrink() {
        super.drink();
    }

    @Override
    public void eat() {
        System.out.println("Cat Eats");
    }

    @Override
    public void drink() {
        System.out.println("Cat Drinks");
    }
}
18
Andrii Dzhyrma

Diese Linie:

Animal myAnimal = myCat;

weist die Variable myAnimal dem zuvor erstellten Objekt myCat zu. Wenn Sie danach myAnimal.eat() aufrufen, rufen Sie tatsächlich die Methode des ursprünglichen myCat-Objekts auf, die Cat Eats ausgibt.

Wenn Sie Animal Eats ausgeben möchten, müssen Sie einer Variablen eine Animal -Instanz zuweisen. Wenn Sie dies stattdessen tun würden:

Animal myAnimal = new Animal()

die Variable myAnimal ist eine Instanz von Animal und überschreibt somit die vorherige Zuordnung zu Cat.

Wenn Sie danach myAnimal.eat() aufrufen, rufen Sie tatsächlich die Methode eat() der von Ihnen erstellten Animal -Instanz auf, die Animal Eats ausgibt.

Fazit: Ihr Code sollte lauten:

public class Cat extends Animal {

    @Override
    public void eat() {
        System.out.println("Cat Eats");
    }

    @Override
    public void drink() {
        System.out.println("Cat Drinks");
    }

    public static void main(String[] args) {
        Cat myCat = new Cat();
        myCat.eat();
        myCat.drink();

        Animal myAnimal = new Animal();        
        myAnimal.eat();
        myAnimal.drink();
    }
}
6
Piet van Dongen

Wenn Sie in jeder Klasse Methoden statisch machen, sollte dies funktionieren.

public class Animal {
    public static void eat() {
        System.out.println("Animal Eats");
    }

    public static void drink() {
        System.out.println("Animal Drinks");
    }
}


public class Cat extends Animal {
    @Override
    public static void eat() {
        System.out.println("Cat Eats");
    }

    @Override
    public static void drink() {
        System.out.println("Cat Drinks");
    }

    public static void main(String[] args) {
        Cat myCat = new Cat();
        myCat.eat();
        myCat.drink();

        Animal myAnimal = myCat;        
        myAnimal.eat();
        myAnimal.drink();
    }
}

Der obige Code liefert die folgende Ausgabe

Cat Eats
Cat Drinks
Animal Eats
Animal Drinks
2
Vbee
  • Der Zugriff auf statische Felder, Instanzfelder und statische Methoden hängt von der Klasse der Referenzvariablen und ab und nicht vom tatsächlichen Objekt , auf das die Variable zeigt. 
  • Denken Sie daran, dass Mitgliedsvariablen gespiegelt und nicht überschrieben werden.
  • Dies ist das Gegenteil von dem, was bei Instanzmethoden geschieht.
    Bei Instanzmethoden wird die Methode der actual-Klasse des Objekts aufgerufen.

    class ABCD {
        int x = 10;
        static int y = 20;
    
        public String getName() {
            return "ABCD";
        }
    }
    
    class MNOP extends ABCD {
        int x = 30;
        static int y = 40;
    
        public String getName() {
            return "MNOP";
        }
    }
    
    public static void main(String[] args) {
    
      System.out.println(new MNOP().x + ", " + new MNOP().y);
    
      ABCD a = new MNOP();
      System.out.println(a.x); // 10
      System.out.println(a.y); // 20
      System.out.println(a.getName()); // MNOP
    }
    

Obwohl in diesem Beispiel das Objekt myCat einer Animal-Objektreferenz zugewiesen ist, hat (Animal myAnimal = myCat) das tatsächliche Objekt den Typ Cat und verhält sich wie eine Katze.

Hoffe das hilft.

2
tharindu_DG

Sie können einen Konstruktor für die Klasse Animal erstellen, der ein anderes Animas als Parameter verwendet und eine neue Instanz basierend auf dem bereitgestellten erstellt.

public class Animal {
    //some common animal's properties
    private int weight;
    private int age;

    public Animal() {
        // empty.
    }

    public Animal(final Animal otherAnimal) {
        this.weight = otherAnimal.getWeight();
        this.age = otherAnimal.getAge();
    }

    public void eat() {
        System.out.println("Animal Eats");
    }

    public void drink() {
        System.out.println("Animal Drinks");
    }

    // setters and getters.
}

public class Cat extends Animal {
    @Override
    public void eat() {
        System.out.println("Cat Eats");
    }

    @Override
    public void drink() {
        System.out.println("Cat Drinks");
    }

    public static void main(String[] args) {
        Cat myCat = new Cat();
        myCat.eat();
        myCat.drink();

        // note: myAnimal is not a Cat, it's just an Animal.
        Animal myAnimal = new Animal(myCat);         
        myAnimal.eat();
        myAnimal.drink();
    }
}
2
friednail
public class Main {
    public static void main(String[] args) {
        Cat myCat = new Cat();
        myCat.eat();
        myCat.drink();

        Animal myAnimal = new Animal();
        myAnimal.eat();
        myAnimal.drink();
    }
}

public class Animal {
    public void eat(){
        System.out.println("Animal eat() called");
    }
    public void drink(){
        System.out.println("Animal drink() called");
    }
}

public class Cat extends Animal {
    @Override
    public void eat() {
        System.out.println("Cat eat() called");
    }

    @Override
    public void drink() {
        System.out.println("cat drink() called");
    }
}

AUSGABE:

Katze frisst () gerufen

katzendrink () genannt

Tier fressen () gerufen

Tiergetränk () genannt

Sie müssen ein Objekt der Superklasse Animal OR erstellen. Eine andere Option besteht darin, das Schlüsselwort super in den Kindklassenmethoden zu verwenden, z. B. super.eat() oder super.drink()

0
cNgamba

Einige Vorschläge:

  1. Übergeben Sie die untergeordnete Klassenreferenz nicht an die übergeordnete Klasse. Außer die Superklassenmethode muss für die überschriebene Methode aufgerufen werden. Superklassenmethoden aus der Superklasseninstanz aufrufen. 

    Animal myAnimal = new Animal();
    myAnimal.eat();
    
  2. Wenn Sie die Superklassenmethode von der untergeordneten Klasse aufrufen möchten, rufen Sie explizit die Superklassenmethode name mit super.methodName () auf.

    public void eat() {
        super.eat();
        System.out.println("Cat Eats");
    }
    
  3. Überschreibe keine Superklassenmethode in der Kindklasse. Es wird immer eine Superklassenmethode aufgerufen. 
0
Ravindra babu

Bitte stimmen Sie nicht über diese Antwort ab ... Sie können über die andere abstimmen :-) Dies ist eine schlechte Antwort, zeigt aber, wie Sie tun würden, was Sie versuchen ... schlecht.

public class Main
{
    public static void main(final String[] argv) 
    {        
        Child  child;
        Parent parent;

        child  = new Child();
        parent = child;

        child.a();
        parent.a();
        child.otherA();
        parent.otherA();
    }
}

class Parent
{
    public void a()
    {
        System.out.println("Parent.a()");
    }

    public void otherA()
    {
        // doesn't matter what goes here... really should be abstract
    }
}

class Child
    extends Parent
{
    @Override
    public void a()
    {
        System.out.println("Child.a()");
    }

    @Override
    public void otherA()
    {
        super.a();
    }
}
0
TofuBeer

Katze kann nicht aufhören, eine Katze zu sein, auch wenn es sich um ein Tier handelt. Die Katze frisst und die Katze trinkt auf die Art einer Katze. Es könnte ähnlich sein wie ein Tier, weshalb es die Methode überschreibt. Wenn Sie möchten, dass das Tier standardmäßig das tut, überschreiben Sie es nicht. Sie könnten wahrscheinlich einige seltsame Dinge mit Reflektion ausführen und separate Methoden erstellen, die auf die übergeordneten Methoden zugreifen, z.

public void superDrink() {
   Animal.class.getMethod("drink").invoke();
}

aber das könnte übertrieben sein, meinst du nicht?

Natürlich würde das wahrscheinlich nicht funktionieren, da es nicht statisch ist. 

0
Jimi Kimble