6

これがJavaで機能する理由がわかりません:

オブジェクトに整数オブジェクトがある場合、例:

Object myIntObj = new Integer(5);

今私がする場合:

System.out.println(myIntObj);

出力は次のとおりです。5

Integer クラスには toString メソッドの ovveride があるようになりましたが、この場合は異なります (私は思います)。ポリモーフィズムの場合、「親変数」に「子オブジェクト」がある場合、オブジェクトはその実際の型 (この場合は整数) を変更しませんが... (オブジェクト変数で) のメソッドを使用するだけです。オブジェクトクラスなので、次のように書くとどうなりますか?

System.out.println(myIntObj);

このオブジェクトの参照ではなく、数字の 5 を直接見ることができますか? オブジェクトクラスの toString メソッドは、デフォルトではオブジェクトの参照の文字列のみを返すためです。

お気に入り:

Object currentPlayer = new Player();
System.out.println(currentPlayer);

この場合、オブジェクト クラスで toString メソッドが呼び出されるため、出力は Player オブジェクトの参照です。

では、前の例では、参照が表示されず、直接番号が表示されるのはなぜですか? 論理的には、ポリモーフィズムのルールは次のように述べています。「親」変数に「子」オブジェクトがある場合、このオブジェクトは内部で同じままですが、オブジェクトのインスタンスのように使用されるため、単にクラスオブジェクトとオブジェクトのメソッドだけなので、参照が表示されずに直接番号が表示されるのは本当に奇妙です。

私の言いたいことを理解していただければ幸いです。

4

5 に答える 5

4

理由を説明する最後の段落は少し間違っています。

では、前の例で参照が表示されず、直接番号が表示されるのはなぜですか? 論理的には、ポリモーフィズムのルールは次のように述べています。「親」変数に「子」オブジェクトがある場合、このオブジェクトは内部で同じままですが、オブジェクトのインスタンスのように使用されるため、 単にクラスオブジェクトとオブジェクトのメソッドだけなので、参照が表示されずに直接番号が表示されるのは本当に奇妙です。

冒頭は正しいが、私が太字にした部分はあなたがそこから引き出した誤った結論です.

ポリモーフィズムを使用すると、オブジェクトは実際にどのような型であってもそのまま残りますが、参照型 (変数の型) によって何ができるかが定義されます。ただし、参照型はオブジェクトが何をするかを説明しません

それがポリモーフィズムの背後にある意図です。それがどのように機能するかとは別に、何ができるかを定義するのは抽象化です。たとえば、次の例があるとします。

public class Vehicle {
    public int getWheelCount() {
        return 1;
    }
}

public class Car extends Parent {
    public int getWheelCount() {
        return 4;
    }

    public void blowHorn() {
        System.out.println("Honk honk!");
    }
}

public class Bicycle extends Parent {
    public int getWheelCount() {
        return 2;
    }
}

Car car = new Car();
car.getWheelCount();  // 4
car.blowHorn();  //"Honk honk!"

Vehicle v = new Car();
v.getWheelCount()  // 4
v.blowHorn();  // COMPILE ERROR HERE!  Unknown method

Bicycle b = new Bicycle();
b.getWheelCount();  // 2

Vehicle v = new Bicycle();
v.getWheelCount();  // 2

このことから結論できることは、サブクラスのメソッドをオーバーライドすると、常に子バージョンが呼び出されるということです。乗り物と呼んでいようと車と呼んでいようと、車は常に車です。しかし、これを車両として参照することで、すべての車両で定義されているメソッドの呼び出しに制限されます。

この例に結び付けると、すべてのVehicleオブジェクトにはホイール サイズがあるため、getWheelCount() は Vehicle.getWheelCount() または Car.getWheelCount() のいずれであっても常に呼び出すことができます。ただし、Car.getWheelCount() は、Car がオーバーライドするため実行されるものです。

参照型が の場合、そのメソッドは Car でのみ使用できるため、Vehicle呼び出すことはできません。blowHorn()

あなたの例に戻ると、整数は整数です。

Object i = new Integer(5);
i.toString();  // 5

i は整数であるため、これは 5 を出力します。Integer クラスは toString をオーバーライドします。参照型 (オブジェクトを参照する型) は、呼び出すことができるメソッドのみを決定しますが、メソッドのどの親/子クラスのバージョンが呼び出されるかは決定しません。

于 2013-11-23T02:58:11.363 に答える
3

これを定義すると、クラスObjectで定義されているメソッドにのみアクセスできるようになります。Object

これにはtoString().

したがって、インスタンス化するときはnew Player()からのメソッドにしかアクセスできませObjectんが、これをオーバーライドすると (同様Integer.toString()に)、インスタンス化されたクラスで定義された出力が得られます。

PS: 父 -> 親

于 2013-11-23T02:33:34.653 に答える
2

メソッドのオーバーライドの概念は次のように機能します。継承階層のどこかにあるオブジェクトが実装を提供すると、継承階層のさらに下にある別のクラスによってオーバーライドされない限り、呼び出されるのはこの実装です。

java.lang.Integerは のオーバーライドを提供するためtoString()、 によって提供される実装の代わりに、このオーバーライドが呼び出されますjava.lang.Object

は、印刷方法がわからないすべてのオブジェクトに対して内部的に呼び出されるため、System.out.println(myIntObj)との間に違いはありません。System.out.println(myIntObj.toString())printlntoString

クラスの動作が異なる理由Playerは、オーバーライドしないためtoString()です。もしそうなら、あなたはその結果が印刷されるのを見るでしょう。ただし、オーバーライドがない場合は、によって提供されるデフォルトの実装java.lang.Objectが呼び出され、一般的なオブジェクト情報が出力されます。

于 2013-11-23T02:36:57.760 に答える
1
Object myIntObj = new Integer(5);

ここでIntegerは、ベアObjectインスタンスではなく、新しいインスタンスを作成しています。それを参照に割り当てているという事実は、Objectそれを裸の に変換しませんObject。まだですが、 を拡張Integerしているため、 として参照できます。したがって、 を呼び出すと、そのインスタンスのメソッドが呼び出されます。そのインスタンスはインスタンスであることがわかります。そしてそう呼ばれます。ObjectObjectmyIntObj.toString()toString()IntegerInteger.toString()


Object currentPlayer = new Player();

この場合、 を呼び出すときも同じルールが適用されます。つまり、currentPlayer.toString()実際に を呼び出しているのですPlayer.toString()Playerclass が をオーバーライドしない場合、toString()最初に昇順の親クラスのtoString()実装が呼び出されます。Playerを直接拡張するObject場合はObject.toString()が呼び出されますが、たとえばPlayer extends HumanandHuman extends ObjectHuman.toString()場合、存在する場合は呼び出されます。そうでない場合は、Object.toString().

于 2013-11-23T02:35:18.630 に答える