如何调用超类的重载方法
如何在代码中使用myAnimal
实例调用Animal
类的吃喝方法?
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
你不能做你想做的。 多态性的工作方式是通过做你所看到的。
基本上,一只猫总是知道它是一只猫,并且总是像猫一样的行为,无论你如何对待猫是猫,猫,猫,猫科动物,食肉目,Theria,哺乳动物,脊椎动物,脊索动物,Eumetazoa,Animalia,动物,对象,或其他任何东西:-)
在这里你可以select你想要调用的方法:
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"); } }
这一行:
Animal myAnimal = myCat;
将variablesmyCat
分配给您之前创build的对象myCat
。 所以当你在那之后调用myAnimal.eat()
,实际上是调用原始myCat对象的方法,它输出Cat Eats
。
如果你想输出Animal Eats
,你必须将一个Animal
实例赋值给一个variables。 所以,如果你会这样做,而不是:
Animal myAnimal = new Animal()
variablesmyAnimal将是Animal
一个实例,因此将覆盖之前的分配给Cat
。
如果你在这之后调用myAnimal.eat()
,你实际上调用了你创build的Animal
实例的eat()
方法,它会输出Animal 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(); } }
- 访问静态字段,实例字段和静态方法取决于引用variables的类而不是variables指向的实际对象 。
- 请记住,成员variables是被覆盖的,而不是覆盖。
-
这与实例方法的情况相反。
在实例方法的情况下,调用对象的实际类的方法。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(ax); // 10 System.out.println(ay); // 20 System.out.println(a.getName()); // MNOP }
在这个例子中,尽pipe对象myCat被分配给一个Animal对象引用( Animal myAnimal = myCat
),但Actual对象的types是Cat
,它的行为就像是一个cat。
希望这可以帮助。
您可以为Animal类创build构造函数,并将另一个Animas作为参数,并根据提供的实例创build新的实例。
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(); } }
如果你在每个类中的方法是静态的,它应该工作。
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(); } }
上面的代码将给出以下输出
Cat Eats Cat Drinks Animal Eats Animal Drinks
几点build议:
-
不要将子类引用传递给超类,除非超类方法必须被重载方法调用。 从超类实例中调用超类方法。
Animal myAnimal = new Animal(); myAnimal.eat();
-
如果你想从子类调用超类方法,用super.methodName()显式调用超类方法名;
public void eat() { super.eat(); System.out.println("Cat Eats"); }
- 不要在子类中重载超类方法。 总是调用超类方法。
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"); } }
OUTPUT:
猫吃()叫
猫喝()叫
动物吃()叫
动物饮料()叫
你需要创build一个超类Animal
的对象,或者另一个选项是在子类方法中使用super
关键字,比如super.eat()
或super.drink()
猫不能停止成为一只猫,即使它是一只动物。 猫会吃,猫会用猫的方式喝。 它可能类似于动物所做的,这就是为什么它覆盖了方法。 如果你想让它做默认的动物,不要重写。 你也许可以用reflection来做一些奇怪的事情,并且可以使用独立的方法访问父方法,比如:
public void superDrink() { Animal.class.getMethod("drink").invoke(); }
但这可能是矫枉过正,你不觉得?
当然,这可能不会工作,因为它不是静态的。
请不要在这个答案上投票…你可以在另一个投票:-)这是一个不好的答案,但显示你将如何做你正在做的努力…糟糕。
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(); } }