如何使用代码中的Animal
实例调用myAnimal
类的eat and drink方法?
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
答案 0 :(得分:61)
你无法做你想做的事。多态性的工作方式是做你所看到的。
基本上猫总是知道它是一只猫并且总是表现得像一只猫,不管你是否像猫,猫,猫科动物,猫科动物,猫科动物,食肉目,Theria,Mammalia,Vertebrata,Chordata,Eumetazoa,Animalia一样对待,动物,物体或其他任何东西: - )
答案 1 :(得分:18)
在这里,您可以选择要调用的方法:
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");
}
}
答案 2 :(得分:6)
这一行:
Animal myAnimal = myCat;
将变量myAnimal
指定给您之前创建的对象myCat
。因此,当您在此之后调用myAnimal.eat()
时,您实际上正在调用原始myCat对象的方法,该方法输出Cat Eats
。
如果要输出Animal Eats
,则必须为变量分配Animal
实例。所以如果你愿意这样做:
Animal myAnimal = new Animal()
变量myAnimal将是Animal
的实例,因此将覆盖之前的Cat
赋值。
如果您在此之后拨打myAnimal.eat()
,则实际上是在调用您创建的eat()
实例的Animal
方法,该方法将输出Animal Eats
。< / p>
总结:您的代码应为:
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();
}
}
答案 3 :(得分:2)
如果你在每个类中创建静态方法,它应该可以工作。
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
答案 4 :(得分:2)
您可以为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();
}
}
答案 5 :(得分:2)
这与实例方法的情况相反 在实例方法的情况下,调用对象的实际类的方法。
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
),但实际对象的类型为Cat
,并且它的行为与它是猫一样。
希望这有帮助。
答案 6 :(得分:0)
猫不能不再是猫,即使它是动物。猫会吃,猫会以猫的方式喝。它可能类似于Animal所做的,这就是为什么它会覆盖该方法。如果你想让它做默认动物做的事情,不要覆盖。你可以用反射做一些奇怪的事情,并制作访问父方法的单独方法,如:
public void superDrink() {
Animal.class.getMethod("drink").invoke();
}
但是你觉得这可能有点矫枉过正?
当然,这可能不会起作用,因为它不是静态的。
答案 7 :(得分:0)
很少有建议:
不要将子类引用传递给超类,并且必须为重写方法调用超类方法。从超类实例调用超类方法。
Animal myAnimal = new Animal();
myAnimal.eat();
如果要从子类调用超类方法,请使用super.methodName()显式调用超类方法名称;
public void eat() {
super.eat();
System.out.println("Cat Eats");
}
答案 8 :(得分:0)
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");
}
}
输出:
Cat eat()叫
猫饮()叫
动物吃()叫
动物饮料()叫
您需要创建超类Animal
的对象或另一个选项是在子类方法中使用关键字super
,例如super.eat()
或super.drink()
< / p>
答案 9 :(得分:0)
您可以使用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();
}
}
答案 10 :(得分: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
答案 11 :(得分:-1)
请不要对这个答案进行投票......你可以对另一个投票:-)这是一个糟糕的答案,但是会说明你将如何做你想做的......很糟糕。
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();
}
}