3

Java の継承は言語の基本的な機能であることに加えて、いくつか質問があります。
私のテスト例のソースは次のとおりです。

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!)
    }
}

次の質問があります:

1. klass オブジェクトは のインスタンスですMyClass。なぜMyClass2クラスからメソッドを実行するのですか?

2,3。質問 1 で、クラスはクラスのメソッドを呼び出しますMyClass2。ここでは、オーバーライドされたメソッドとオーバーロードされた (同時に) メソッドのそれぞれに適合するパラメーターを使用しました。クラスオブジェクトが常にクラスからメソッドを呼び出すのはなぜMyClassですか?

4.正常です。質問はありません。

5. 例外をスローするのは正しい。klass オブジェクトには、double パラメーターを持つこのメソッドはありません。しかし、MyClass2質問 1 で起こったように、クラスからメソッドが呼び出されないのはなぜですか?

4

4 に答える 4

8

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.

于 2013-05-15T16:47:12.867 に答える
2

クラスのインスタンスには、親のメソッドと独自のメソッドがあります。子クラスのいずれかの署名が親クラスのメソッドの署名と同じ場合、 はそれをオーバーライドします。

この例では、MyClass2 のインスタンスに次のメソッドがあります。

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

しかし、クラスを MyClass として宣言しているので、このメソッドが利用可能になります。

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

さて、ご質問にお答えします

1 - MyClass のようなメソッドを呼び出します。しかし、実行時には、実際には klass は MyClass2 のオブジェクトであり、MyClass2 はこのメソッドをオーバーライドするため、MyClass2 からのメソッドを呼び出します。

2,3 - MyClass の print メソッドを呼び出します。実行時、klass は MyClass2 からのものですが、MyClass2 はこのメソッドをオーバーライドしていません。サインが違います。したがって、呼び出されるのは MyClass です。MyClass2 は MyClass であるため、MyClass2 オブジェクトをパラメータとして使用しても問題なく動作します

5 - MyClass には、double を受け取る anotherPrint と呼ばれるメソッドがありません

于 2013-05-15T17:07:30.413 に答える
0

Java でのメソッドのオーバーロードとメソッドのオーバーライドは、Java プログラマーが同じ名前で動作が異なるメソッドを宣言できるようにする Java の 2 つの重要な概念です。メソッドのオーバーロードとメソッドのオーバーライドは、Java のポリモーフィズムに基づいています。メソッドのオーバーロードの場合、同じ名前のメソッドは同じクラスに共存しますが、メソッド シグネチャが異なる必要があります。一方、メソッドのオーバーライドの場合、同じ名前のメソッドは派生クラスまたはサブクラスで宣言されます。メソッドのオーバーロードは static を使用して解決されます。メソッドのオーバーライドは、実行時に Java で動的バインディングを使用して解決されますが、コンパイル時に Java でバインディングします。要するに、Javaでメソッドをオーバーロードすると、そのメソッドの署名が変更されましたが、メソッドの署名をオーバーライドする場合は同じままですが、メソッドはサブクラスでのみオーバーライドできます。

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

于 2014-06-10T09:55:15.030 に答える
0

質問 1:- 行 MyClass klass = new MyClass2(); で 子クラスの参照ID(オブジェクト)をキャッチして、アップキャストを行いました。アップキャストの場合、子クラスのメソッドが呼び出されます。コンパイラはコンパイル時に親の say() 関数をチェックしますが、実行時にコンパイラは子にも say() 関数があることを確認するため、それを子クラスのメソッドにバインドして呼び出します。これが、質問 1 の出力が Hello MyClass2 h として得られる理由です。

于 2013-05-15T16:57:59.550 に答える