在Java中,当有人问:

什么是多态性?

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

我认为事情远不止如此。

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

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


当前回答

经典的例子,狗和猫是动物,动物有制造声音的方法。我可以迭代调用makeNoise的动物数组,并期望它们在各自的实现。

调用代码不需要知道它们是什么特定的动物。

这就是我所说的多态性。

其他回答

多态性涉及到一种语言通过使用单一接口统一处理不同对象的能力;因此,它与覆盖有关,因此接口(或基类)是多态的,实现者是覆盖的对象(同一奖章的两个面)

无论如何,这两个术语之间的区别可以用其他语言更好地解释,比如c++:如果基本函数是虚的,那么c++中的多态对象的行为就像Java对应的对象一样,但如果方法不是虚的,那么代码跳转是静态解析的,并且在运行时不检查真实类型,因此,多态包括对象根据用于访问它的接口而表现不同的能力;让我在伪代码中做一个例子:

class animal {
    public void makeRumor(){
        print("thump");
    }
}
class dog extends animal {
    public void makeRumor(){
        print("woff");
    }
}

animal a = new dog();
dog b = new dog();

a.makeRumor() -> prints thump
b.makeRumor() -> prints woff

(假设makeRumor不是虚拟的)

Java并没有真正提供这种级别的多态性(也称为对象切片)。

动物a =新狗(); Dog b = new Dog ();

a.makeRumor() -> prints thump
b.makeRumor() -> prints woff

在这两种情况下,它只会打印woff.. 因为a和b指的是类dog

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

重写和重载都用于实现多态性。

你可以在一个类中有一个方法 它在或中被覆盖 更多的子类。这个方法可以 不同的东西取决于哪个 类用于实例化对象。

    abstract class Beverage {
       boolean isAcceptableTemperature();
    }

    class Coffee extends Beverage {
       boolean isAcceptableTemperature() { 
           return temperature > 70;
       }
    }

    class Wine extends Beverage {
       boolean isAcceptableTemperature() { 
           return temperature < 10;
       }
    }

你也可以有一种方法 用两组或多组参数重载。这个方法可以 不同的东西基于 传递的参数类型。

    class Server {
        public void pour (Coffee liquid) {
            new Cup().fillToTopWith(liquid);
        }

        public void pour (Wine liquid) {
            new WineGlass().fillHalfwayWith(liquid);
        }

        public void pour (Lemonade liquid, boolean ice) {
            Glass glass = new Glass();
            if (ice) {
                glass.fillToTopWith(new Ice());
            }
            glass.fillToTopWith(liquid);
        }
    }

下面是伪c# /Java中的多态性示例:

class Animal
{
    abstract string MakeNoise ();
}

class Cat : Animal {
    string MakeNoise () {
        return "Meow";
    }
}

class Dog : Animal {
    string MakeNoise () {
        return "Bark";
    }
}

Main () {
   Animal animal = Zoo.GetAnimal ();
   Console.WriteLine (animal.MakeNoise ());
}

Main函数不知道动物的类型,并且依赖于MakeNoise()方法的特定实现的行为。

编辑:看来布莱恩先我一步了。有趣的是我们用了同样的例子。但是上面的代码应该有助于阐明概念。

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

An override is a type of function which occurs in a class which inherits from another class. An override function "replaces" a function inherited from the base class, but does so in such a way that it is called even when an instance of its class is pretending to be a different type through polymorphism. Referring to the previous example, you could define your own class and override the toString() function. Because this function is inherited from Object, it will still be available if you copy an instance of this class into an Object-type variable. Normally, if you call toString() on your class while it is pretending to be an Object, the version of toString which will actually fire is the one defined on Object itself. However, because the function is an override, the definition of toString() from your class is used even when the class instance's true type is hidden behind polymorphism.

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