Java inheritance (method overriding and overloading)

一曲冷凌霜 提交于 2019-12-03 18:10:14

问题


Besides that Java inheritance is a fundamental feature of the language, I have some questions.
Here is the source for my testing example:

class MyClass{

    public void say(String t){
        System.out.println("Hello MyClass "+t);
    }

    public void print(MyClass t){
        System.out.println("MyClass is printed");
    }

    public void anotherPrint(int i){
        System.out.println("MyClass is printed again");
    }
}

class MyClass2 extends MyClass{

    public void say(String t){
        System.out.println("Hello MyClass2 "+t);
    }

    public void print(MyClass2 t){
        System.out.println("MyClass2 is printed");
    }

    public void anotherPrint(double i){
        System.out.println("MyClass2 is printed again");
    }
}

public class HelloWorld{

    public static void main(String []args){
        MyClass klass = new MyClass2();

        klass.say("h"); //Question 1 (Prints: "Hello MyClass2 h")

        klass.print(new MyClass2()); //Question 2 (Prints: "MyClass is printed")
        klass.print(new MyClass()); //Question 3 (Prints: "MyClass is printed")

        klass.anotherPrint(1); //Question 4 (Prints: "MyClass is printed again")
        klass.anotherPrint(1.0); //Question 5 (Throws Exception!)
    }
}

I have the following questions:

1. The klass object is instance of MyClass. Why does it execute the method from the MyClass2 class?

2,3 . At question 1 klass calls the method of the MyClass2 class. Here I used a parameter that fits to each one of the overridden and overloaded (simultaneously) methods. Why klass object always calls the method from the MyClass class?

4. It is normal. No question at all.

5. It is right to throw an exception. The klass object does not have this method with double parameter. But, why it is not called the method from the MyClass2 class, just like it happened at Question 1?


回答1:


1. The klass object is instance of MyClass.

No it is a reference variable of type MyClass but referring to an object of MyClass2.

2. Why does it execute the method from the MyClass2 class?

Since you are invoking say() on an object of MyClass2, it executes the say() of MyClass2. Expected behavior.

This is called the run time polymorphism in Java. This provides the ability to override functionality already available in the class hierarchy tree. At run time, which version of the method will be invoked is based on the type of actual object stored in that reference variable and not on the type of the reference variable.

3. At question 1 klass calls the method of the Class2 class. Here I used a parameter that fits to each one of the overridden and overloaded (simultaneously) methods. Why klass object always calls the method from the MyClass class?

That is not overridden method. An instance method in a subclass with the same signature (name, plus the number and the type of its parameters) and return type as an instance method in the superclass overrides the superclass's method.An overriding method can also return a subtype of the type returned by the overridden method. This is called a covariant return type.Your method signatures are different. Hence invoking klass.print() where klass is a MyClass reference will always refer to the print() of MyClass.

4. It is right to throw an exception. The klass object does not have this method with double parameter. But, why it is not called the method from the MyClass2 class, just like it happened at Question 1?

Because at compile time, the compiler validates if you can call a method based on the reference type. Here the reference type is MyClass and since MyClass doesn't define anotherPrint(double), the compiler complains.It is a compile time check.In question 1, compiler verified klass.say("hi") and it saw that there exists a method in MyClass which can be invoked this way. At that time, it was not concerned whether klass reference variable will refer to a MyClass object or MyClass2 object at runtime. Hence it worked.

You can refer to these Oracle's tutorials here.




回答2:


An instance of a class will have the methods of the father(s) plus its own methods. If the signature of one of the child class is the same than the signature of a method in the father, will override it.

In this example, an instance of MyClass2 will have this methods:

public void say(String t) //From MyClass2 (override)
public void print(MyClass2 t)
public void anotherPrint(double i)
public void print(MyClass t) //Inherited from MyClass
public void anotherPrint(int i) //Inherited from MyClass

But you are declaring klass as a MyClass, so it will have available this methods

public void say(String t) //From MyClass
public void print(MyClass t)
public void anotherPrint(int i)

Now, answering your questions

1 - You invoke the method say of a MyClass. But in runtime, actually klass is an object of MyClass2 and MyClass2 overrides this method, so it will invoke the one from MyClass2

2,3 - You invoke the method print of MyClass. In runtime, klass is from MyClass2, but MyClass2 IS NOT OVERRIDING THIS METHOD. The signature is different. So the one to be called is the MyClass. Works fine with a MyClass2 object as parameter since MyClass2 is a MyClass

5 - MyClass has not any method called anotherPrint receiving a double




回答3:


Question 1:- With the line MyClass klass = new MyClass2(); you have done upcasting, catching the reference id(object) of child class. In case of upcasting, the methods of the child class are called. Though the compiler checks for the say() function in the parent at comiple time but at run time compiler sees that we have say() function in child also, so it binds it with the child class method and calls it. This is the reason you are getting the output for Question 1 as Hello MyClass2 h




回答4:


Method overloading and method overriding in Java is two important concept in Java which allows Java programmer to declare method with same name but different behavior. Method overloading and method overriding is based on polymorphism in Java. In case of method overloading, method with same name co-exists in same class but they must have different method signature, while in case of method overriding, method with same name is declared in derived class or sub class.Method overloading is resolved using static binding in Java at compile time while method overriding is resolved using dynamic binding in Java at runtime. In short When you overload a method in Java its method signature got changed while in case of overriding method signature remains same but a method can only be overridden in sub class. Since Java supports polymorphism and resolve object at run-time it is capable to call overridden method in Java

Read more: http://javarevisited.blogspot.com/2011/12/method-overloading-vs-method-overriding.html#ixzz34EEhLp2u



来源:https://stackoverflow.com/questions/16570663/java-inheritance-method-overriding-and-overloading

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!