如何调用超类的重载方法

如何在代码中使用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议:

  1. 不要将子类引用传递给超类,除非超类方法必须被重载方法调用。 从超类实例中调用超类方法。

     Animal myAnimal = new Animal(); myAnimal.eat(); 
  2. 如果你想从子类调用超类方法,用super.methodName()显式调用超类方法名;

     public void eat() { super.eat(); System.out.println("Cat Eats"); } 
  3. 不要在子类中重载超类方法。 总是调用超类方法。
 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(); } }