多态性 vs 覆盖 vs 重载

就Java而言,当有人问:

什么是多态性?

重载覆盖是一个可以接受的答案吗?

我认为还有更多的东西。

如果你有一个抽象基类,它定义了一个没有实现的方法,而你在子类中定义了该方法,那么这是否仍然过度引用?

我认为过载肯定不是正确的答案。


答案 1

表达多态性的最清晰方法是通过抽象基类(或接口)

public abstract class Human{
   ...
   public abstract void goPee();
}

此类是抽象的,因为该方法对于人类是不可定义的。它只能针对子类 Male 和 Female 进行定义。此外,人类是一个抽象的概念——你不能创造一个既不是男性也不是女性的人。它必须是一个或另一个。goPee()

因此,我们使用抽象类来延迟实现。

public class Male extends Human{
...
    @Override
    public void goPee(){
        System.out.println("Stand Up");
    }
}

public class Female extends Human{
...
    @Override
    public void goPee(){
        System.out.println("Sit Down");
    }
}

现在我们可以告诉满是人类的整个房间去撒尿。

public static void main(String[] args){
    ArrayList<Human> group = new ArrayList<Human>();
    group.add(new Male());
    group.add(new Female());
    // ... add more...

    // tell the class to take a pee break
    for (Human person : group) person.goPee();
}

运行此操作将产生:

Stand Up
Sit Down
...

答案 2

多态性是类实例的行为能力,就好像它是其继承树中另一个类的实例一样,最常见的是其祖先类之一。例如,在 Java 中,所有类都继承自 Object。因此,可以创建 Object 类型的变量,并为其分配任何类的实例。

重写是一种函数类型,它发生在从另一个类继承的类中。重写函数“替换”从基类继承的函数,但这样做的方式是,即使其类的实例通过多态性伪装成不同类型,也会调用它。参考前面的示例,您可以定义自己的类并重写 toString() 函数。由于此函数是从 Object 继承的,因此,如果将此类的实例复制到 Object 类型变量中,它仍将可用。通常,如果您在类上调用 toString() 而它假装是一个对象,那么实际将触发的 toString 版本就是 Object 本身上定义的版本。但是,由于该函数是重写,因此即使类实例的真实类型隐藏在多态性后面,也会使用类中 toString() 的定义。

重载是定义具有相同名称但具有不同参数的多个方法的操作。它与覆盖或多态性无关。