54

コード内のインスタンスを使用して、Animalクラスの Eat and Drink メソッドを呼び出すにはどうすればよいですか?myAnimal

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();
    }
}

私が得ている出力:

Cat Eats
Cat Drinks
Cat Eats
Cat Drinks

これは私の期待される出力です:

Cat Eats
Cat Drinks
Animal Eats
Animal Drinks
4

12 に答える 12

79

やりたいことはできません。ポリモーフィズムが機能する方法は、見ていることを実行することです。

基本的に、猫は自分が猫であることを常に認識しており、猫、フェリス、ネコ科、ネコ科、フェリフォルミア、肉食動物、テリア、哺乳動物、脊椎動物、脊索動物、ユーメタゾア、動物界、動物、オブジェクト、またはその他のもの:-)

于 2013-03-27T19:50:54.057 に答える
30

ここでは、呼び出すメソッドを選択するオプションがあります。

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");
    }
}
于 2014-04-15T21:06:38.737 に答える
9

この行:

Animal myAnimal = myCat;

以前に作成myAnimalした objectに変数を割り当てます。myCatしたがって、myAnimal.eat()その後呼び出すと、実際には元の myCat オブジェクトのメソッドを呼び出していることになり、出力はCat Eats.

を出力したい場合は、インスタンスを変数Animal Eatsに割り当てる必要があります。Animalしたがって、代わりにこれを行う場合:

Animal myAnimal = new Animal()

変数 myAnimal は のインスタンスになるためAnimal、以前の割り当てを に上書きしますCat

この後に呼び出す場合myAnimal.eat()、実際には作成したインスタンスのeat()メソッドを呼び出しており、出力は.AnimalAnimal Eats

結論: コードは次のようになります。

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();
    }
}
于 2013-03-27T19:51:41.470 に答える
4
  • 静的フィールド、インスタンス フィールド、および静的メソッドへのアクセスは、変数が指す実際のオブジェクトではなく、参照変数のクラスに依存します。
  • メンバー変数はオーバーライドされず、シャドウされることに注意してください。
  • これは、インスタンス メソッドの場合とは逆です。
    インスタンスメソッドの場合、オブジェクトの実際のクラスのメソッド が呼び出されます。

    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
    }
    

この例では、オブジェクト myCat が Animal オブジェクト参照に割り当てられていますが、( Animal myAnimal = myCat) Actual オブジェクトはタイプCatであり、猫として動作します。

お役に立てれば。

于 2015-11-27T04:10:34.263 に答える
3

別のアニマをパラメーターとして受け取り、提供されたものに基づいて新しいインスタンスを作成するクラス Animal のコンストラクターを作成できます。

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();
    }
}
于 2014-08-19T06:30:46.413 に答える
2

いくつかの提案:

  1. 子クラス参照をスーパー クラスに渡さないでください。スーパー クラス メソッドをオーバーライドされたメソッドに対して呼び出す必要がある場合を除きます。スーパー クラス インスタンスからスーパー クラス メソッドを呼び出します。

    Animal myAnimal = new Animal();
    myAnimal.eat();
    
  2. 子クラスからスーパークラスのメソッドを呼び出したい場合は、super.methodName(); で明示的にスーパークラスのメソッド名を呼び出します。

    public void eat() {
        super.eat();
        System.out.println("Cat Eats");
    }
    
  3. 子クラスでスーパー クラス メソッドをオーバーライドしないでください。常にスーパー クラス メソッドが呼び出されます。
于 2016-09-30T11:35:13.263 に答える
0

この回答に投票しないでください...他の回答に投票できます:-)これは悪い回答ですが、あなたがやろうとしていることをどのように行うかを示しています...不十分です。

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();
    }
}
于 2013-03-27T20:01:21.383 に答える
0

猫は動物であっても猫であることをやめることはできません。猫は猫のやり方で食べ、猫は飲む。これは、メソッドをオーバーライドする理由である Animal の動作に似ている可能性があります。動物がデフォルトで行うことをしたい場合は、オーバーライドしないでください。おそらく、リフレクションでいくつかの奇妙なことを行い、次のような親メソッドにアクセスする別のメソッドを作成できます。

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

しかし、それはやり過ぎかもしれませんね。

もちろん、静的ではないため、おそらく機能しません。

于 2013-03-27T20:04:54.773 に答える
0

コードを少し変更するだけで、やりたいことを実行できます。当然のことながら、Animal クラスのメソッドはオーバーライドされており、参照型を変更するだけではアクセスできません。代わりに、次のように、食べる関数と飲む関数の定義を少し変更できます。

class Animal{
    public void eat(boolean randomBoolean){
        System.out.println("Animal eats");
    }
    public void drink(boolean randomBoolean){
        System.out.println("Animal drinks");
    }
}

class Cat extends Animal{
    public void eat(boolean wantOverriden){
        if(wantOverriden){
            boolean randomBooleanValue=true|false;
            super.eat(randomBooleanValue);
        }
        else{
            System.out.println("Cat eats");
        }
    }
    public void drink(boolean wantOverriden){
        if(wantOverriden){
            boolean randomBooleanValue=true|false;
            super.drink(randomBooleanValue);
        }
        else{
            System.out.println("Cat drinks");
        }
    }
}

これで、必要かどうかを示すブール値を渡すだけで、Cat クラス オブジェクトを介して Animal クラスのオーバーライドされたメソッドにアクセスできるようになります。例:

Cat c=new Cat();
c.eat(false);     //Indicating that you dont want to access the overriden method
c.drink(false);   //Indicating that you dont want to access the overriden method
c.eat(true);          //Indicating that you want to access the overriden method
c.drink(true);        //Indicating that you want to access the overriden method
于 2020-09-21T17:11:32.807 に答える