[英]How to call the superclass implementation of an overridden method from inside the superclass in Java?
[英]How to call the overridden method of a superclass?
如何在代码中用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,动物界,动物,对象,或其他任何东西:-)
在这里,您可以选择要调用的方法:
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;
将变量myAnimal
分配给您之前创建的对象myCat
。 因此,当您在那之后调用myAnimal.eat()
时,实际上是在调用原始 myCat 对象的方法,该方法输出Cat Eats
。
如果要输出Animal Eats
,则必须将Animal
实例分配给变量。 因此,如果您改为这样做:
Animal myAnimal = new Animal()
变量 myAnimal 将是Animal
的一个实例,因此将覆盖之前对Cat
的赋值。
如果您在此之后调用myAnimal.eat()
,则实际上是在调用您创建的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();
}
}
这与实例方法的情况相反。
在实例方法的情况下,调用对象的实际类的方法。
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 }
在此示例中,尽管对象 myCat 被分配给 Animal 对象引用( Animal myAnimal = myCat
),但 Actual 对象是Cat
类型,它的行为就像一只猫。
希望这可以帮助。
您可以为类 Animal 创建构造函数,该构造函数将另一个Animas 作为参数,并基于提供的一个创建新实例。
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
几点建议:
不要将子类引用传递给超类,并且必须为重写的方法调用超类方法之外的方法。 从超类实例调用超类方法。
Animal myAnimal = new Animal(); myAnimal.eat();
如果要从子类调用超类方法,使用 super.methodName() 显式调用超类方法名;
public void eat() { super.eat(); System.out.println("Cat Eats"); }
你可以使用 super 关键字实现你想要的,它允许访问被覆盖的方法。
public class Animal {
public void eat() {
System.out.println("Animal Eats");
}
public void drink() {
System.out.println("Animal Drinks");
}
}
public class Cat extends Animal {
public void eat() {
System.out.println("Cat Eats");
}
public void drink() {
System.out.println("Cat Drinks");
}
public void printMessage(){
super.eat();
super.drink();
}
public static void main(String[] args) {
Cat myCat = new Cat();
myCat.eat();
myCat.drink();
myCat.printMessage();
}
}
请不要对这个答案投票......你可以对另一个投票:-) 这是一个糟糕的答案,但显示了你将如何做你想做的事情......糟糕。
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();
}
}
猫不能停止成为猫,即使它是动物。 猫会吃猫会喝猫的方式。 它可能类似于 Animal 所做的事情,这就是它覆盖该方法的原因。 如果你想让它做动物默认做的事情,不要覆盖。 您可能可以通过反射做一些奇怪的事情,并制作访问父方法的单独方法,例如:
public void superDrink() {
Animal.class.getMethod("drink").invoke();
}
但这可能有点矫枉过正,你不觉得吗?
当然,这可能行不通,因为它不是静态的。
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");
}
}
输出:
猫吃()调用
猫喝()调用
动物吃()调用
动物饮料()调用
您需要创建超类Animal
的对象,或者另一个选项是在子类方法中使用关键字super
,例如super.eat()
或super.drink()
您可以通过对代码进行一些小的更改来做您想做的事情。 自然地,Animal 类的方法已被覆盖,您不能简单地通过更改引用类型来访问它们。 相反,你可以稍微改变一下 eat 和 Drink 函数的定义,如下所示。
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
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.