9

如果我在 Java 中有以下代码:

class A {

    public int add(int a , int b) {
        return (a+b);
    }
}

class B extends A {
    public float add(float a , float b) {
        return (a+b);
}

在这种特殊情况下,子类并没有完全覆盖基类的add函数,因为它们具有不同的签名,并且只有在它们处于相同范围内时才会出现重载的概念。那么,add(float , float)子类中的函数是否B被视为一个全新的函数,重载和覆盖的概念不适用呢?它使用“静态绑定”还是“动态绑定”?

4

9 回答 9

4

b 类中的方法 add 是 a 类中 add 的重载。不是覆盖。覆盖只是原始 add 方法的不同实现。

于 2013-03-08T10:09:41.230 回答
2

简而言之,是的。要覆盖,您需要复制完整的方法签名,其中包括方法名称、参数和返回类型。从教程

子类中具有相同签名(名称,加上其参数的编号和类型)和返回类型作为超类中的实例方法的实例方法会覆盖超类的方法。

您可能需要考虑@Override 批注,如果您没有成功覆盖方法,它将触发编译器错误。

在这个特定的例子中,看起来你不需要重写包括泛型在内的一些解决方案。所以你可以实例化一个类a<Integer>和一个类似的类a<Float>

于 2013-03-08T10:08:58.280 回答
2

在这种情况下,您不会覆盖该方法,因为签名不同。

但是在 b 类中存在重载,因为您有两个名称相同但参数不同的方法(一个是 a 类,另一个是 b 类)

希望能帮助到你。

于 2013-03-08T10:10:04.263 回答
1

在子类中可以有一个方法没有被重写但被重载。这里的子类有两个 add() 方法。接受 int 参数的版本(未覆盖),以及接受浮点参数的重载方法 add()。

于 2014-03-31T05:48:47.110 回答
0

我知道这是迟到的答案,但我认为对于初学者来说这是一个重要的问题。

重载的一个关键点是它在继承中起作用。

接下来是它的Static bindingDynamic binding

它是静态绑定那么,为什么?

静态绑定

  1. Java 中的静态绑定发生在Compile time.
  2. privatefinal并且static方法和变量使用静态绑定并由编译器绑定。
  3. 静态绑定使用类型(Java 中的类)信息进行绑定。

动态绑定

  1. 动态绑定发生在Runtime.

  2. 基于运行时对象在运行时绑定的动态方法。

  3. 动态绑定使用 Object 来解析绑定。

但重要的部分在这里

重载的方法使用静态绑定进行绑定,而重写的方法在运行时使用动态绑定进行绑定。

Java 编译器根据用于调用方法的参数类型确定要在编译时执行的重载方法的正确版本,这两个类的重载方法的参数接收调用中使用的参数值并执行重载方法。

B a=new B();
a.add(4, 5);
a.add(4.0f, 5.0f);

因此,如果您将创建类型 B 的引用,那么它将搜索正确的参数类型,并且对于上述代码,它将执行这两种方法。

A a=new B();
a.add(4, 5);
a.add(4.0f, 5.0f);

但是对于上面的代码,它会给出浮点参数的编译时错误。

希望它能消除所有疑虑。

于 2018-09-28T20:25:26.917 回答
0

我认为在这种特殊情况下,不会发生重载和覆盖,因为在重载和覆盖的情况下返回类型必须相同,因此在这种情况下既不会发生静态绑定,也不会发生动态绑定。在返回类型不同的情况下,方法重载是不可能的,因为编译器无法确定他需要调用哪个方法。

于 2016-02-03T05:46:27.703 回答
0

第一件事

它是方法覆盖吗?

不,因为要覆盖一个方法,您需要复制完整的方法签名,正如 Brian Agnew 的回答中指出的那样,正如我在下面解释的那样。

是否超载?

是的,方法“add”在 B 类中有一个重载的实现。

考虑以下代码:

class C{
    public static void main(String args[]){
        B a = new B();
        a.add(2 , 3);
        a.add(2.0 , 3.0);
    }
}

class A {

    public int add(int a , int b) {
        System.out.print("INT ");
        return a + b;
    }
}

class B extends A {
    public double add(double a , double b) {
        System.out.print("Double ");
        return a + b;
    }
}

输出:INT 双

因此,代码中 Class B 中的方法重载了它从其父级继承的 add 方法

它使用静态绑定还是动态绑定?

这就是让我得出结论认为 OP 很困惑的原因。它是静态绑定,因为它是一个重载函数。考虑动态绑定的唯一方法是在以下场景中

class C{
    public static void main(String args[]){
        A a = new B();
        a.add(2.0 , 3.0);
    }
}

class A {

    public int add(int a , int b) {
        System.out.println("A : INT");
        return a + b;
    }
}

class B extends A {
    public int add(int a , int b) {
        System.out.println("B : INT");    
        return a + b;
    }
        
    public double add(double a , double b) {
        System.out.println("Double");
        return a + b;
    }   
}

输出:B:INT

在这里,父类 A 有一个契约,上面写着“我有一个整数的添加行为”。B 类继承了这种添加行为并使其更加具体,同时还提供了一种可以添加双打的新行为。但是 A 类“不知道这种行为”。

所以A类的对象“不能”添加双打。为此,您需要更具体的 A 对象类型,即 B 对象。

于 2021-10-02T02:58:53.753 回答
-1

类 A 中的方法add()也可以通过继承提供给类 B,因此overloaded通过将数据类型从 更改为 ,该方法在类int, intfloat, float

于 2015-09-11T16:23:55.763 回答
-1

当且仅当函数在相同的范围或类中时,重载的概念才会起作用。cz 如果这是方法重载的情况,那么对于相同的方法签名或相同的参数类型,编译器会感到困惑并且必须给出编译时错误。但是在上面的B类程序中,如果你以相同的顺序传递相同的参数,那么根据重载它必须给出错误但它没有发生你可以检查它我已经有。这是继承的情况,如果您调用任何方法,则通过对象引用,编译器将在子类中检查它,如果它不存在,则它将查看上述程序所涉及的父类。希望这会有所帮助。

于 2016-07-13T18:06:51.253 回答