多态性与重写与重载

问题

就Java而言,当有人问:

什么是多态?

would重载or覆盖是可接受的答案?

我认为还有更多的东西。
如果你有一个抽象基类定义了一个没有实现的方法,并且你在子类中定义了该方法,那还是会覆盖吗?
我认为6810153015重载**肯定不是正确答案。


#1 热门回答(844 赞)

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

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

这个类是抽象的,因为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 热门回答(81 赞)

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

An覆盖是一种函数,它发生在继承自另一个类的类中。覆盖函数"替换"从基类继承的函数,但这样做的方式是,即使它的类的实例假装通过多态而成为不同的类型,也会调用它。参考前面的示例,你可以定义自己的类并覆盖toString()函数。因为此函数是从Object继承的,所以如果将此类的实例复制到Object类型变量中,它仍然可用。通常,如果在假装是Object时调用类上的toString(),实际触发的toString版本就是在Object本身上定义的版本。但是,因为函数是覆盖,所以即使类实例的真实类型隐藏在多态背后,也会使用类中toString()的定义。

重载是使用相同名称但使用不同参数定义多个方法的操作。它与重写或多态无关。


#3 热门回答(42 赞)

这是伪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()方法的特定实现的行为。

编辑:看起来Brian打败了我。有趣的我们使用相同的例子。但上面的代码应该有助于澄清这些概念。