多态与覆盖和重载是什么意思?

内容来源于 Stack Overflow,并遵循CC BY-SA 3.0许可协议进行翻译与使用

  • 回答 (10)
  • 关注 (0)
  • 查看 (234)

就Java而言,当有人问:

什么是多态?

重载 或 重写 是一个可以接受的答案么?

我认为应该比这还要多一些。

如果您有一个抽象基类,它定义了一个没有实现的方法,并且在子类中定义了该方法,那么这是否仍然是 重载 的呢?

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

提问于
用户回答回答于

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

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

类是抽象的,因为goPee()方法是 Human 无法定义的。它只适用于男性和女性的子类。另外,Human 是一个抽象的概念--你不能创造一个既不是男性也不是女性的 Human,一定是其中一个。

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

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");
    }
}

现在我们可以让一整间屋子的 Human 去做某件事。

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中,您在集合库中看到了很多多态性:

int countStuff(List stuff) {
  return stuff.size();
}

List是基类,编译器不知道是否要计算链接列表、向量、数组或自定义列表实现,只需要它的作用像列表:

List myStuff = new MyTotallyAwesomeList();
int result = countStuff(myStuff);

如果你是重载,你会:

int countStuff(LinkedList stuff) {...}
int countStuff(ArrayList stuff) {...}
int countStuff(MyTotallyAwesomeList stuff) {...}
etc...

编译器将选择正确版本的CountStuff()来匹配参数。

用户回答回答于

多态是对象以多种形式出现的能力。这涉及到使用继承和虚拟函数来构建一个可以交换的对象系列。基类包含虚拟函数的原型,可能是未实现的,也可能是应用程序指示的默认实现,各个派生类的实现方式各不相同,以实现不同的行为。

用户回答回答于

经典的例子,狗和猫是动物,动物有制造噪音的方法。我可以迭代一组动物,调用makeNoise,并预计它们在那里执行各自的实现。

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

这就是我认为的多态性。

用户回答回答于

具体地说,重载或重写并不能给出完整的结果。多态仅仅是对象根据其类型专门化其行为的能力。

我不同意这里的一些答案,因为重载是一种多态(参数多态),在具有相同名称的方法可能有不同行为的情况下,会给出不同的参数类型。一个很好的例子是操作符重载。您可以定义“+”来接受不同类型的参数--例如字符串或数字--并且基于这些类型,“+”的行为将有所不同。

多态还包括继承和重写方法,尽管它们在基类型中可以是抽象的或虚拟的。在基于继承的多态性方面,Java只支持单类继承,将其多态行为限制为基类型的单链。Java确实支持多个接口的实现,这是多态行为的另一种形式。

用户回答回答于

你是对的,重载不是答案。

两者都不重要。重写是获得多态性的方法。多态是对象根据其类型改变行为的能力。

当显示多态性的对象的调用方不知道该对象的特定类型时,最好展示这一点。

用户回答回答于

实际上,两者都是用来实现多态性的。

  • 您可以在一个类中有一个方法,该方法是重写在一个或多个子类中。该方法根据用于实例化对象的类执行不同的操作。 abstract class Beverage {boole isAcceptableTemperature();}
  • class Coffee extends Beverage{boboalisAcceptableTemperature(){revertentableTemperature(){RevertentableTemperature();}}
  • class Wine extends Beverage{boboalisAcceptableTemperature(){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); } }

用户回答回答于

多态意味着多个形式,同一个对象根据需求执行不同的操作。

可以使用两种方法来实现多态性,这两种方法是:

  1. 方法重写
  2. 方法重载

方法重载意味着使用相同的方法名在同一个类中写入两个或多个方法,但是传递的参数是不同的。

方法重写意味着我们在不同的类中使用同样方法名,这意味着父类方法在子类中使用。

在Java中,为了实现多态性,超类引用变量可以保存子类对象。

要实现多态性,每个开发人员必须在项目中使用相同的方法名。

用户回答回答于

下面是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 ());
}

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

用户回答回答于

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

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

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

扫码关注云+社区

领取腾讯云代金券