多态性 vs 覆盖 vs 重载
2022-08-31 04:44:57
就Java而言,当有人问:
什么是多态性?
重载或覆盖是一个可以接受的答案吗?
我认为还有更多的东西。
如果你有一个抽象基类,它定义了一个没有实现的方法,而你在子类中定义了该方法,那么这是否仍然过度引用?
我认为过载肯定不是正确的答案。
就Java而言,当有人问:
什么是多态性?
重载或覆盖是一个可以接受的答案吗?
我认为还有更多的东西。
如果你有一个抽象基类,它定义了一个没有实现的方法,而你在子类中定义了该方法,那么这是否仍然过度引用?
我认为过载肯定不是正确的答案。
表达多态性的最清晰方法是通过抽象基类(或接口)
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
...
多态性是类实例的行为能力,就好像它是其继承树中另一个类的实例一样,最常见的是其祖先类之一。例如,在 Java 中,所有类都继承自 Object。因此,可以创建 Object 类型的变量,并为其分配任何类的实例。
重写是一种函数类型,它发生在从另一个类继承的类中。重写函数“替换”从基类继承的函数,但这样做的方式是,即使其类的实例通过多态性伪装成不同类型,也会调用它。参考前面的示例,您可以定义自己的类并重写 toString() 函数。由于此函数是从 Object 继承的,因此,如果将此类的实例复制到 Object 类型变量中,它仍将可用。通常,如果您在类上调用 toString() 而它假装是一个对象,那么实际将触发的 toString 版本就是 Object 本身上定义的版本。但是,由于该函数是重写,因此即使类实例的真实类型隐藏在多态性后面,也会使用类中 toString() 的定义。
重载是定义具有相同名称但具有不同参数的多个方法的操作。它与覆盖或多态性无关。