6

次のコードの動作を説明できる人はいますか...?

interface myInterface{}

public class Main {

    public static void main(String[] args) {

        System.out.println(new myInterface(){public String toString(){return "myInterfacetoString";}});

        System.out.println(new myInterface(){public String myFunction(){return "myInterfacemyFunction";}});
    }
}

出力は...

myInterfacetoString
primitivedemo.Main$2@9304b1

println() ステートメントの myInterface は匿名クラスであるというすべての回答。しかし、すでにインターフェイスとして宣言しているので、なぜ同じ名前の匿名クラスを作成できるのでしょうか....?

繰り返します...これらが匿名クラスの場合、クラス main はこれらの匿名クラスに任意の名前を付けることを許可する必要があります..しかし、そうしようとすると..コンパイルエラーが発生します

4

4 に答える 4

14

オブジェクトを出力すると、 toString() メソッドが呼び出されます。最初のステートメントでは、新しいオブジェクトを作成し、toString というメソッドもオーバーライドします。したがって、この toString() メソッドは、オブジェクトが印刷されるときに呼び出されます。

2 番目のステートメントでもオブジェクトを作成しますが、オブジェクト クラスの toString() メソッドを使用するように toString() メソッドをオーバーライドしません。

新しい質問については、このリンクに理解のための良い説明があります: Anonymous Classes

ここに説明のコピーがあります:

new className(optional argument list){classBody}

この式は、名前のない以前に未定義のクラスから新しいオブジェクトをインスタンス化します。このクラスは、className という名前のクラスを自動的に拡張し、インターフェイスを明示的に実装することはできません。新しいクラスの本体は、classBody によって指定されます。

この式を実行すると、className を拡張する新しいクラスが定義され、新しいクラスの新しいオブジェクトがインスタンス化され、式が新しいオブジェクトへの参照に置き換えられます

new interfaceName(){classBody}

この式は、名前のない未定義のクラスから新しいオブジェクトをインスタンス化し、interfaceName という名前のインターフェイスを自動的に実装し、Object という名前のクラスを自動的に拡張します。このクラスは、1 つの interface のみを明示的に実装でき、Object 以外のクラスを拡張することはできません。繰り返しますが、新しいクラスの本体は classBody によって与えられます。

今、あなたにとってそれは明らかですか?

于 2010-06-05T02:15:37.733 に答える
3

最初に、匿名インスタンスからメソッドprintln()をオーバーライドしているため、オーバーライドされたメソッドによって返された文字列を取得します。これが関数のデフォルトの動作です。toString()myAbstractClasstoString()println()

2 番目の では、メソッドをprintln()オーバーライドしていないため、デフォルトのもの (から継承) を使用します。toString()println()Object

補足として、コードを正しくフォーマットしてみてください。読みやすく理解しやすいです。

abstract class myAbstractClass{}

public class Main { 
    public static void main(String[] args) { 
        System.out.println(new myAbstractClass(){
            public String toString(){
                return "myAbstractClass toString";
            }
        });

        System.out.println(new myAbstractClass(){
            public String myFunction(){
                return "myAbstractClass myFunction";
            }
        }); 
    } 
}
于 2010-06-05T02:19:29.940 に答える
3

myAbstractClass は最小限のクラスです。オブジェクトから継承します。

クラス main は、myAbstractClass から 2 つの匿名内部クラスを構築し、それらの toString 出力を出力します。

  1. 内部クラスは toString メソッドをオーバーライドし、その出力が表示されます。
  2. 内部クラスにメソッドが追加され、デフォルトの toString 定義になります。
于 2010-06-05T02:23:37.480 に答える
1

どちらのシナリオでも、オブジェクトを印刷しました。したがってtoString()、オブジェクトのメソッドを呼び出します。最初のシナリオでは、メソッドをオーバーライドしたtoString()ため、印刷していmyAbstractClass toStringます。2 番目のシナリオでは、オーバーライドされていないため、クラスtoString()に実装されているデフォルトを呼び出します。Object

間違っている 2 番目のシナリオで関数呼び出しを期待していると思います。あなたはそれをオーバーライドしましたが、呼び出したことはありません。

于 2010-06-05T02:26:49.437 に答える