在java中,我们可以通过传递超类方法中使用的参数的子类来覆盖方法吗?

SD *_*haw 10 java overriding overloading

根据规则,在覆盖子类中的方法时,参数不能更改,并且必须与超类中的参数相同.如果我们在重写方法时传递参数的子类怎么办?是否会被称为超载或覆盖?

根据我的查询,我在下面写了一些代码.
我期待输出为"狗吃肉食"但令我惊讶的是输出是"动物吃肉食"如果有人可以解释当分配的对象是Dog类型时动物方法如何被调用,我将不胜感激?

    class Food {
        public String toString(){
            return "Normal Food";
        }
    }

    class Flesh extends Food {
        public String toString(){
            return "Flesh Food";
        }
    }

    class Animal {
        public void eat(Food food){
            System.out.println("Animal eats "+ food);
        }
    }

    class Dog extends Animal{

        public void eat(Flesh flesh){
            System.out.println("Dog eats "+ flesh);
        }
    }

    public class MyUtil {

        public static void main(String[] args) {

            Animal animal = new Dog(); 

            Flesh flesh = new Flesh();

            animal.eat(flesh);
        }
    }
Run Code Online (Sandbox Code Playgroud)

Pau*_*ton 13

该方法eatDog不覆盖的方法eatAnimal.这是因为参数不同(一个需要Flesh,另一个需要Food).

eat方法是重载.

重载之间的选择发生在编译时,而不是运行时.它不是基于调用该方法的对象的实际类,而是基于编译时类型(如何声明变量).

animal有编译时类型Animal.我们知道这是因为变量的声明animalAnimal animal = ....这是事实实际上是一个Dog无关紧要-它的版本eatAnimal,必须调用.

另一方面,该toString方法Flesh 确实覆盖了该toString方法Food.

当一个方法覆盖另一个方法时,调用该方法的对象的实际类确定运行哪个版本.

eat方法中Animal,即使参数具有编译时类型Food,如果您传递一个实例Flesh,它也将执行该toString方法Flesh.

因此,您收到了消息"Animal eats Flesh Food".


小智 5

为了能够在运行时动态加载子类,泛型的使用使得它可以完美地工作。

public class HelloWorld{

     public static void main(String []args){
        Animal animal = new Dog(); 

        Food flesh = new Flesh();

        animal.eat(flesh);
     }
}

 class Food {
        public String toString(){
            return "Normal Food";
        }
    }

    class Flesh extends Food {
        public String toString(){
            return "Flesh Food";
        }
    }

    class Animal<T extends Food> {
        public void eat(T food){
            System.out.println("Animal eats "+ food);
        }
    }

    class Dog extends Animal<Flesh>{
        
        public void eat(Flesh flesh){
            System.out.println("Dog eats "+ flesh);
        }
    }
Run Code Online (Sandbox Code Playgroud)


Ahm*_*rdi 2

不,在这种情况下我们不能,您可以通过在 Dog 类中的 eat 方法上方添加 @Override 来检查它,这样编译错误将出现如下所示:

@Override
public void eat(Flesh flesh){
   System.out.println("Dog eats "+ flesh);
}
Run Code Online (Sandbox Code Playgroud)

确保在重写中参数的类型和顺序应与父类相同。