在Java中,当有人问:

什么是多态性?

重载或重写是可以接受的答案吗?

我认为事情远不止如此。

如果你有一个抽象基类,它定义了一个没有实现的方法,并且你在子类中定义了这个方法,这仍然是覆盖的吗?

我认为超负荷肯定不是正确的答案。


当前回答

Polymorphism is a multiple implementations of an object or you could say multiple forms of an object. lets say you have class Animals as the abstract base class and it has a method called movement() which defines the way that the animal moves. Now in reality we have different kinds of animals and they move differently as well some of them with 2 legs, others with 4 and some with no legs, etc.. To define different movement() of each animal on earth, we need to apply polymorphism. However, you need to define more classes i.e. class Dogs Cats Fish etc. Then you need to extend those classes from the base class Animals and override its method movement() with a new movement functionality based on each animal you have. You can also use Interfaces to achieve that. The keyword in here is overriding, overloading is different and is not considered as polymorphism. with overloading you can define multiple methods "with same name" but with different parameters on same object or class.

其他回答

多态性是一个对象以多种形式出现的能力。这涉及到使用继承和虚函数来构建可交换的对象族。基类包含虚函数的原型,这些原型可能未实现,也可能具有应用程序指定的默认实现,而各种派生类都以不同的方式实现它们,以影响不同的行为。

术语重载指的是具有相同名称的东西的多个版本,通常是具有不同参数列表的方法

public int DoSomething(int objectId) { ... }
public int DoSomething(string objectName) { ... }

这些函数可能做同样的事情但你可以选择用ID或名称来调用它。与继承、抽象类等无关。

覆盖通常指的是多态性,就像你在问题中描述的那样

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

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

这个类是抽象的,因为goPee()方法对人类是不可定义的。它只对子类Male和Female可定义。此外,人是一个抽象的概念——你不能创造一个既不是男性也不是女性的人。一定是两者之一。

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

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

and

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
...

你说得对,超载不是解决问题的办法。

两者都不是最重要的。覆盖是获得多态性的方法。多态性是对象根据其类型改变行为的能力。当显示多态的对象的调用者不知道该对象是什么具体类型时,最能说明这一点。

重写更像是通过声明一个与上层方法(超级方法)具有相同名称和签名的方法来隐藏一个继承的方法,这为类添加了多态行为。 换句话说,选择要调用的级别方法的决定将在运行时而不是在编译时做出。 这就引出了接口和实现的概念。