Java中的重载和覆盖

Posted

技术标签:

【中文标题】Java中的重载和覆盖【英文标题】:Overloaded and overridden in Java 【发布时间】:2012-05-21 01:52:25 【问题描述】:

我知道如何重载方法,以及如何重写方法。但是有可能同时重载和覆盖一个方法吗?如果有,请举个例子。

【问题讨论】:

【参考方案1】:

重载和覆盖是互补的东西,重载是指方法名相同但参数不同,而覆盖是指子类中方法名相同但参数相同。因此,重载和覆盖不可能同时发生,因为重载意味着不同的参数。

例子:

class A 
    public void doSth()  /// 


class B extends A 
    public void doSth()  /* method overriden */ 

    public void doSth(String b)  /* method overloaded */ 


干杯!

【讨论】:

如果你愿意,你可以重写一个重载的方法。它尽可能接近。 当这种情况发生时,哪个负责绑定(静态或动态)的方法呢?覆盖还是重载?【参考方案2】:

重载和重载只是抽象。重载只是意味着编译器使用名称以及参数的类型和数量来确定要调用的函数。实际上,重载一个方法与给它命名不同,因为编译器用来查找函数的键是名称和参数列表的组合。

除了编译器可以使用 super 关键字来处理被覆盖的函数之外,覆盖的原理是相同的。

那么你能覆盖一个重载的函数吗?是的,因为重载方法在编译器眼中是完全不同的方法。

【讨论】:

覆盖根本不是一回事。关于调用哪个方法的决定推迟到运行时。编译器没有决定。 @EJP - 最终编译器会做出决定,即使它是通过构建 vtable 和分配 vpointer 以促进动态调度而抽象出来的。绑定的关系必须在某个地方初始化。 @EJP - 其次,如果您仔细阅读,您会发现我所说的只是编译器会将重载方法视为完全不同的方法,因为编译器使用名称和参数列表来形成键.这绝对在编译时的动态调度初始化过程中发挥作用。至于最后一点,继续在带有final修饰符的子类中的重载方法中添加override注解,看看编译器是否决定参与 @nsfyn55 当决定可能涉及编译器在据称这样做时没有看到的类时,不能说编译器做出决定。编译器做什么来生成代码,该代码运行时系统或运行时库一起确保调用正确的方法。这与做出决定的编译器不同。这与编译器在重载之间做出决定也不是一回事,这与您在回答中的上述陈述相反。 @EJP-呃。我什至不确定你在说什么。该调用是虚拟的,但它仍然设置了一个跳转指令,它只是碰巧在它到达那里时跳转到其他地方。它确实为重载方法设置了两个不同的地址,因为它们是完全不同的方法。实现无关紧要。我要说的是,重载之所以存在,是因为编译器不仅仅关闭名称,但在覆盖方法时确实特别考虑了super 关键字。【参考方案3】:

这取决于你的意思。方法可以是超类中重载方法的覆盖。并且您可以重载一个您同时使用另一个方法覆盖的方法。

但是,您不能拥有一个既是 new 重载又是覆盖的方法。对于要成为覆盖的方法,具有相同签名的另一个方法必须已经存在于超类中......这意味着该方法不能是 new 覆盖。

【讨论】:

【参考方案4】:

是的,这是可能的,你可以在同一个类中重载和覆盖一个函数,但你不能在两个不同的类中重载一个函数,因为这在逻辑上是不可能的。

#include <bits/stdc++.h>
using namespace std;

class Base 
   public:
    void print() 
    
        cout << "Base Function" << endl;
    
    void print(string name) //Overloaded Function
    
        cout << "Base Function : " <<name<< endl;
    
;

class Derived : public Base 
   public:
    void print() 
    
        cout << "Derived Function" << endl;
    
     void print(string name) //Overloaded Function
    
        cout << "Derived Function : "<<name<< endl;
    
;

int main() 
    Derived derived1, derived2;
   
    //accesses the print function in derived class
    derived1.print();
   
    //accesses the overloaded print function in derived class
    derived1.print("Gitanshu");
    
    //accesses the print function in base class
    derived2.Base::print();

    //accesses the overloaded print function in base class
    derived2.Base::print("Gitanshu");

    return 0;

输出:

Derived Function
Derived Function : Gitanshu
Base Function
Base Function : Gitanshu

我是用 C++ 回答的,Java 也一样。

【讨论】:

以上是关于Java中的重载和覆盖的主要内容,如果未能解决你的问题,请参考以下文章

java 重载和重写的区别

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

java语言中,overload(重载)和override(覆盖)有何区别?

重写(覆盖,Override)和重载(Overload)的区别

java 重载和重写的区别

重写和重载的三点区别