简体   繁体   English

子类中的方法可以重载超类中的方法吗?

[英]Can a method in sub class overloading a method in super class?

Java code: Java代码:

class P {
    public void hello() {}
}

class C extends P {
    public void hello(String s) {}
}

My question is: Is the hello in class C overloading the one with same name in super class P ?我的问题是: C类中的hello是否重载了超类P中的同名?

My friend says they are not because the are not in the same class.我的朋友说他们不是因为他们不在同一个班级。

Taking a more formal approach, the Java Language Specification for Java 7 states:采用更正式的方法,Java 7 的 Java 语言规范指出:

If two methods of a class (whether both declared in the same class, or both inherited by a class, or one declared and one inherited) have the same name but signatures that are not override-equivalent, then the method name is said to be overloaded.如果一个类的两个方法(无论是在同一个类中声明,还是都由一个类继承,或者一个声明一个继承)具有相同的名称但签名不是覆盖等效的,则该方法名称被称为超载。

http://docs.oracle.com/javase/specs/jls/se7/html/jls-8.html#jls-8.4.9 http://docs.oracle.com/javase/specs/jls/se7/html/jls-8.html#jls-8.4.9

I would point your friend to this link.我会把你的朋友指向这个链接。

So, in short, in your example, the hello method is indeed overloaded.因此,简而言之,在您的示例中, hello 方法确实是重载的。

Simple Explanation:简单说明:

I think this question arises because at times we hear the following,我认为这个问题的出现是因为有时我们会听到以下内容,

" Method overloading is performed within class. Method overriding occurs in two classes that have inheritance relationship. " "方法重载在类内部进行。方法覆盖发生在两个具有继承关系的类中。 "

The above statement is correct.上述说法是正确的。 But your friend is wrong.但是你的朋友错了。 why?为什么?

Because when you extend a class, the subclass have all the methods defined by superclass.因为当你扩展一个类时,子类拥有超类定义的所有方法。 It is as if all the methods of superclass have been implemented by the subclass.就好像超类的所有方法都被子类实现了一样。 That means the hello() method has been implemented by the class C as well.这意味着 hello() 方法也已由 C 类实现。 Now, you added a method in class C with different parameter (hello(String s)).现在,您在 C 类中添加了一个具有不同参数 (hello(String s)) 的方法。 That means, class C has two methods in all with same name but different parameters and that is " overloading ".这意味着,C 类共有两个名称相同但参数不同的方法,即“重载”。

Hope it is crystal clear.希望它是晶莹剔透的。

Yes, your friend is wrong because he thinks only of the concept of overriding.是的,你的朋友错了,因为他只考虑了压倒一切的概念。

But here hello() , and hello(String s) are different by there parameters so it's overloading not overriding.但是这里hello()hello(String s)的参数不同,所以它是重载而不是覆盖。

重载可以发生在同一个类以及父子类关系中,而覆盖仅发生在继承关系中。

Source of confusion: Your friend would be right if speaking about C++ not Java.困惑之源:如果您谈论的是 C++ 而不是 Java,那么您的朋友是对的。 In C++, function overloading can only occur between members of the same class.在 C++ 中,函数重载只能发生在同一类的成员之间。 Whereas in Java, overloading can occur, in addition to that, across two classes with inheritance relationship.而在 Java 中,除此之外,还可能在具有继承关系的两个类之间发生重载。

Long story short, an instance of C will have both the hello() and the hello(String s) methods available.长话短说, C的实例将同时提供hello()hello(String s)方法。 An instance of P will only have the hello method available. P的实例将只有hello方法可用。

This is indeed overloading , as you have two methods of the same name taking different parameters.这确实是重载,因为您有两个同名的方法采用不同的参数。

However, it is not overriding , because overriding is having a method declared in a subclass with the same name and same parameters as a method in a superclass.但是,它不是覆盖,因为覆盖是在子类中声明的方法与超类中的方法具有相同的名称和相同的参数

Eg if you had例如,如果你有

class C extends P {
    public void hello() {}
}

it would be overriding the hello() method declared in P .它将覆盖P中声明的hello()方法。 When invoking new C().hello() in that case, you would invoke the implementation of the hello() method declared in class C .在这种情况下调用new C().hello()时,您将调用类C中声明的hello()方法的实现。

Yes it is overloading , This overloading is happening in case of the class ' C ' which is extending P and hence having two methods with the same nam e but different parameters leading to overloading of method hello() in Class C . Yes it is overloading ,这种重载发生在扩展P的类“ C ”的情况下,因此有two methods with the same namdifferent parameters的方法,导致Class C中方法hello()的重载。 However Class P is only able to access one of the methods which is present in its own definition.但是, Class P只能访问其定义中存在的方法之一。

It is a valid question since usually, overloading is explained using two methods with the same name (but different parameters) in the same class.这是一个有效的问题,因为通常在同一个类中使用两个具有相同名称(但参数不同)的方法来解释重载。

I would argue that yes, the method hello in C is overloading P 's hello method because of the "is a" relation.我认为是的,由于“is a”关系, C中的方法hello重载了Phello方法。

The "is a" relation states that since C subclasses P, it is also an instance of P ("C is a P"). “is a”关系表明,由于 C 是 P 的子类,它也是 P 的一个实例(“C is a P”)。 Hence C has 2 overloaded hello -methods.因此 C 有 2 个重载的hello方法。

Good question!!!In sub class if method name |好问题!!!在子类中如果方法名 | parameter type |参数类型 | list is changed then sub class method will not be considered as overriding it is considered as overloading method Example :列表被更改然后子类方法将不会被视为覆盖它被视为重载方法示例:

class A{
void m1(int a){}
}

class B extends A{
  void m1(float f)
   {}
}

In above program m1 method is a overloaded method.在上面的程序中,m1 方法是一个重载方法。

Yes we can overload the super class method in sub class like as bellow:是的,我们可以在子类中重载超类方法,如下所示:

    public class OverLoading {

    public static void main(String[] args) {
        B b = new B();
        b.display();
        b.display(4);
    }
}


class A {
    public void display() {
        System.out.println("A class display method");
    }
}

class B extends A {
    public void display() {
        System.out.println("class B subclass");
    }

    public void display(int a) { //Overloading in subclass
        System.out.println("class B subclass with overloading");
    }
}
Output: 
class B subclass
class B subclass with overloading

Depends on the class.取决于班级。 From class P's perspective (if the reference is P, the object can be of C) it is not.从类 P 的角度来看(如果引用是 P,则对象可以是 C)它不是。 If you write something like: P p = new C();如果你写这样的东西: P p = new C(); there is no overloading because you cannot call p.hello("foo") .没有重载,因为您不能调用p.hello("foo")

From class C's perspective it is overloaded because if you write C c = new C();从 C 类的角度来看,它是重载的,因为如果你写C c = new C(); it has two methods with same name and different signatures.它有两个名称相同但签名不同的方法。

This is a good question and the answer is a bit tricky.这是一个很好的问题,但答案有点棘手。

Well, it's true that you can overload an inherited method from a parent class into a subclass.的确,您可以将继承的方法从父类重载到子类中。 However, and here's the interesting part, the actual behavior depends on the reference variable type.然而,有趣的是,实际行为取决于引用变量的类型。

Let's consider the following example:让我们考虑以下示例:

public class OverLoadingTest {

    public static void main(String[] args) {
        ChildClass cc = new ChildClass();
        SuperClass sc = cc;
        sc.method("lol");
        cc.method("lol");
    }

    static class SuperClass {

        public void method(Object o) {
            System.out.println("SuperClass called.");
        }
    }

    static class ChildClass extends SuperClass {
        public void method(String s) {
            System.out.println("ChildClass called.");
        }
    }
}

So, we have a class extending another and with a method that overloads a method from the parent.所以,我们有一个类扩展了另一个类,并且有一个从父类重载方法的方法。

It's easy to guess that if you have an instance of ChildClass , the two methods are overloaded, and overloading resolution takes place as it normally does.很容易猜到,如果你有一个ChildClass的实例,这两个方法就会被重载,并且重载决议会像往常一样发生。

However, let's consider creating an instance of ChildClass and assigning it to a reference variable of type SuperClass .但是,让我们考虑创建ChildClass的实例并将其分配给SuperClass类型的引用变量。 Is the overloading thing still standing?超载的东西还在吗?

If you execute this program you will get this outptut:如果你执行这个程序,你会得到这个输出:

SuperClass called.
ChildClass called.

The output clearly indicates that there's no overloading here in this case.输出清楚地表明在这种情况下这里没有过载。 This however can be altered by overriding the original method.然而,这可以通过覆盖原始方法来改变。

static class ChildClass extends SuperClass {
    public void method(String s) {
        System.out.println("ChildClass called.");
    }

    public void method(Object o) {
        System.out.println("ChildClass called.");
    }
}

Now, if you run the program again, you get this output:现在,如果您再次运行该程序,您将得到以下输出:

ChildClass called.
ChildClass called.

Explanation解释

Now, why is JVM behaving that way?现在,为什么 JVM 会这样呢? Why can't it see the overloading method as we're using an instance of the child class?为什么在我们使用子类的实例时看不到重载方法?

This takes us to how does JVM call a method.这将带我们了解 JVM 如何调用方法。 The JVM sees that you're referring to the object with a reference of type SuperClass , so, it can only use the methods that are related to that type, with the only exception is overriden methods. JVM 看到您使用SuperClass类型的引用来引用对象,因此,它只能使用与该类型相关的方法,唯一的例外是被覆盖的方法。 And since method(String) isn't overriding, we have method(Object) of the parent, hence, it's the one chosen for execution.而且由于method(String)没有覆盖,我们拥有父级的method(Object) ,因此,它是选择执行的方法。

We then override the method to break this rule, and this is how the JVM called ChildClass.method(Object) even if the reference variable is of a parent class.然后我们重写该方法来打破这个规则,这就是 JVM 调用ChildClass.method(Object)的方式,即使引用变量是父类的。

Overloading is when you have two methods that have the same name but different signatures (Your case).重载是指您有两个名称相同但签名不同的方法(您的情况)。

Side note: Overriding is when you have two methods that have exactly the same signature and name and the parent class.旁注:覆盖是当您有两个具有完全相同的签名和名称以及父类的方法时。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM