多态性 - 重载/覆盖

Posted

技术标签:

【中文标题】多态性 - 重载/覆盖【英文标题】:Polymorphism - Overloading/Overriding 【发布时间】:2011-06-26 13:04:52 【问题描述】:

我知道这个问题在 *** 上已经被彻底解决了,并且已经发布了很多问题。 我可能已经阅读了其中的每一个,但是,有一个琐碎的疑问:我认为我非常了解重载和覆盖。让我明白的是多态性。

例如,this question 接受的答案用shape.Draw() 解释了这一点。我对这与覆盖有何不同感到困惑(有时我对它与重载有何不同感到困惑)。

另外——多态本质上是否意味着从抽象类派生? (我认为我读过的关于该主题的几乎所有答案都使用了一个抽象的动物类,并使猫和狗喵喵叫/吠叫:)

总结一下,我的问题是:

    什么是多态性 w.r.t.重载和覆盖?

    谁能解释一下没有抽象类的多态性 - 谢谢!

    重载/覆盖不是多态性的子类型,是吗?

编辑添加第三个问题并修改第二个问题。

【问题讨论】:

重载与子类型/接口 (Java) 多态性是正交的。每个重载的方法都有一个 distinct 签名。编译器只是省去了选择(可能更好的)唯一名称的工作:-) 【参考方案1】:

回答您的问题:

    它能够在运行时中选择更专业的方法,具体取决于用于调用它的对象。 当然。多态性可能在不涉及抽象类的情况下发生。 不,重载/覆盖不是类型的多态性。

这是一个不涉及抽象类的多态性示例。

// non abstract
class A

    public void a()
    
        System.out.println("Hello from A");
    


class B
   extends A

    @Override
    public void a()
    
        System.out.println("Hello from B");
    


class C

    public static void SomeStatic(A a)
    
         // HERE IS WHERE POLYMORPHISM OCCUR
         a.a();
    

C 中的多态性发生是因为SomeStatic 方法可以通过对A 对象的引用对B 对象的引用 进行调用。如果引用 A 调用它,则将调用 Aa 方法。如果引用 B 来调用它,则会调用Ba 方法。这种在运行时改变被调用的实际方法的能力称为多态性

重载多态性几乎没有任何关系。事实上,如果您愿意,您可以在不涉及继承的情况下进行 重载。您甚至可以在不涉及面向对象 的情况下进行重载重载只是让两个函数同名但参数不同。

另一方面,

重写只是在专门的(继承的)类上重新定义方法。 重写方法是多态发生所必需的。否则,运行时将没有 DUAL POSSIBILITIES(仔细查看示例)。

C类是理解这一切的关键:

class Main

    public static void main(String[] args)
    
        A a = new A();
        B b = new B();
        C.SomeStatic(a); // will call A's a
        C.SomeStatic(b); // will call B's a
        // AND THIS IS POLYMORPHISM
        // C will decide WHICH METHOD TO CALL 
        // only at runtime
    

Poly:来自希腊。表示很多Morph:来自希腊语。表示形式

所以在多态性中有"many" (poly) "forms" (morph ) 调用方法。调用哪一个,取决于用于调用该方法的对象。

【讨论】:

@Pablo Santa Cruz - 这正是让我困惑的地方:) 我假设 Java 中 Class B : A 的等效代码是 Class B extends A。你不是重写 Class B 中 Class A 的方法 a() 吗? 好的,将语法更改为 Java。不,相反:我在 B 类上覆盖了 A 类的 a 方法。 @Pablo Santa Cruz - 抱歉修正了错字,但我的问题是 - 这怎么不是覆盖的例子?哦,我想我可能明白了——是因为这是对象的类型而不是方法的区别吗? 是的,决定调用哪个方法的是对象的实际类型。不是方法。你重写方法,也意味着你重新定义它。 只是吹毛求疵,但 poly 和 morph 是希腊语而不是拉丁语(ph 和 y 通常是赠品;))【参考方案2】:

实际上,除了重载和覆盖之外,多态并不是独立的。

重载和覆盖都是特定类型的多态性:

重载称为临时多态性。 覆盖用于面向对象的类型多态性以在子类上实现不同的行为。

【讨论】:

【参考方案3】:

多态是一个 OOP 概念,其中单个任务以多种方式执行。例如。您可以通过借记卡、网上银行支付账单。

它有两种类型:

1) 编译时多态性:导致静态绑定(编译器用来匹配签名的签名匹配技术)。运算符重载、函数重载其实是实现编译时多态的一种方式。

2) 运行时多态性:导致动态绑定。重写(在后续子类中重新定义方法)是实现运行时多态性的一种方式。

【讨论】:

以上是关于多态性 - 重载/覆盖的主要内容,如果未能解决你的问题,请参考以下文章

如果仅部分覆盖重载函数,则多态性不起作用

为啥这行得通?方法重载+方法覆盖+多态

C++ 多态性和重载?

重载是编译时多态性。真的吗?

如果重载和覆盖相同的方法,Java中的意外多态行为

重写覆盖重载多态几个概念的区别分析