Java 如何调用超类的重写方法?
如何使用代码中的Java 如何调用超类的重写方法?,java,inheritance,overriding,Java,Inheritance,Overriding,如何使用代码中的myAnimal实例调用Animal类的饮食方法 public class Animal { public void eat() { System.out.println("Animal Eats"); } public void drink() { System.out.println("Animal Drinks"); } } 我得到的输出: Cat Eats Cat Drinks Cat Eats Cat
myAnimal
实例调用Animal
类的饮食方法
public class Animal {
public void eat() {
System.out.println("Animal Eats");
}
public void drink() {
System.out.println("Animal Drinks");
}
}
我得到的输出:
Cat Eats
Cat Drinks
Cat Eats
Cat Drinks
这是我的预期输出:
Cat Eats
Cat Drinks
Animal Eats
Animal Drinks
你不能做你想做的事。多态性的工作方式是做你所看到的事情 基本上,猫总是知道自己是猫,无论你把它当作猫、猫科动物、猫科动物、猫科动物、猫科动物、食肉动物、兽类动物、哺乳类动物、脊椎动物、脊索动物、真动物、动物、物体或其他任何东西,它的行为都会像猫一样:-)这一行:
Animal myAnimal=myCat代码>
将变量myAnimal
指定给您以前创建的对象myCat
。因此,当您在此之后调用myAnimal.eat()
时,实际上是在调用原始myCat对象的方法,该对象输出Cat Eats
如果要输出animaleats
,必须将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();
}
}
请不要对这个答案投票。。。你可以对另一个投票:-)这是一个糟糕的答案,但表明你将如何做你正试图做的事。。。糟糕
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();
}
}
猫不能停止做一只猫,即使它是一只动物。猫会像猫一样吃喝。它可能与动物的行为相似,这就是为什么它会覆盖该方法。如果你想让它做动物默认做的事情,不要重写。您可能会对反射执行一些奇怪的操作,并创建访问父方法的单独方法,例如:
public void superDrink() {
Animal.class.getMethod("drink").invoke();
}
但那可能太过分了,你不觉得吗
当然,这可能行不通,因为它不是静态的 在这里,您可以选择要调用的方法:
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");
}
}
如果您使每个类中的方法都是静态的,那么它应该可以工作
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创建构造函数,该类将另一个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();
}
}
- 对静态字段、实例字段和静态方法的访问取决于参考变量的类,而不是变量指向的实际对象李>
- 请记住,成员变量是隐藏的,而不是重写的
- 这与实例方法的情况相反。
对于实例方法,调用对象的实际类的方法
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 myAnimal=myCat
),但实际对象的类型为Cat
,其行为与猫一样
希望这能有所帮助。几点建议:
不要将子类引用传递给超类,除非必须为重写的方法调用超类方法。从超类实例调用超类方法
Animal myAnimal = new Animal();
myAnimal.eat();
若要从子类调用超类方法,请使用super.methodName()显式调用超类方法名称
不要重写子类中的超类方法。始终调用超类方法李>
输出:
猫吃东西
猫喝饮料
动物吃
动物饮料
您需要创建super类Animal
的对象,或者另一个选项是在子类方法中使用关键字super
,例如super.eat()
或super.drink()
,您可以使用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();
}
}
您只需对代码进行一些小的更改,就可以做您想做的事情。当然,Animal类的方法已经被重写,您不能简单地通过更改引用类型来访问它们。相反,您可以对eat和drink函数的定义稍作修改,如下所示
类动物{
公共void eat(布尔值){
System.out.println(“动物吃”);
}
公共无效饮料(布尔值){
System.out.println(“动物饮料”);
}
}
猫科动物{
公共空吃(布尔Wantoveriden){
如果(Wantoveriden){
布尔随机布尔值=真|假;
super.eat(随机布尔值);
}
否则{
System.out.println(“猫吃”);
}
}
公共无效饮料(布尔Wantoveriden){
如果(Wantoveriden){
布尔随机布尔值=真|假;
超级饮料(布尔值);
}
否则{
System.out.println(“猫饮料”);
}
}
}
现在,您应该能够通过Cat类对象访问动物类的重写方法,只需传入一个布尔值,指示是否要这样做,例如:
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
你想调用animal
实现而不调用cat
实现吗?除非你在cat
中有一个witch调用super.eat()的方法代码>您不能直接从Cat
执行此操作,您不应该期望您所期望的。。。不应该在语言定义和什么是合理的或可取的方面。继承多态性的全部目的是得到你所看到的,而不是你所说的你所期望的
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");
}
}
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();
}
}
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