0

私は今、匿名クラスを掘り下げようとしていますが、詳細をあまり参照せず、質問を簡単にしたいという1つの質問が発生しましsizzle()た:次の匿名クラスでメソッドを呼び出すにはどうすればよいですか:

public class Popcorn {
    public void pop() {
        System.out.println("popcorn");
    }
}

class Food {
    Popcorn p = new Popcorn() {
        public void sizzle() {
            System.out.println("anonymous sizzling popcorn");
        }

        public void pop() {
            System.out.println("anonymous popcorn");
        }
    };

    public void popIt() {
        p.pop(); // OK, Popcorn has a pop() method
        p.sizzle(); // Not Legal! Popcorn does not have sizzle()
    }
}

スーパークラスの参照は、ダウンキャストなしではサブクラスのメソッドを呼び出すことができないことは、ポリモーフィズムの規則で既知であり、明確です (たとえそれが特定のサブクラスのオブジェクトを参照していたとしても)。sizzle()ただし、上記の場合、メソッドを呼び出すための「キー」は何ですか?

4

3 に答える 3

2

クラスは匿名であるため、sizzle()メソッドに外部からアクセスすることはできません。

p参照は型であり、それPopcornはを定義しませんsizzle()

匿名クラスはワンショットであることが意図されており、Javaにはファーストクラス関数がないため、つまり関数オブジェクトを渡すことができないため、一部のデザインパターン(オブザーバーなど)で頻繁に使用されます。

于 2012-12-04T22:48:47.197 に答える
2

私はこれが機能することを期待していませんでしたが、機能します:

new Object() {
    public void foo() {}
}.foo();

上記はコンパイルされ、期待どおりに機能します。説明は、式のタイプは、 new Object() {}が定義する匿名タイプであり、ではないということObjectです。ただし、そのタイプの変数(またはメソッドパラメーター)を持つことはできません。つまり、式の後にチェーンされている場合を除いて、他の場所でメソッドを呼び出すことはできませんnew

これはあなたの(解決できない)問題を実際には解決しないので、私はそれがより補足的な答えであることを認めます。

于 2012-12-05T01:28:50.420 に答える
1

を呼び出すときは、変数をメソッドを持つ型にp.sizzle()する必要があります。唯一の方法は、サブクラスまたはインターフェイスを使用することです。の型を変更したくない場合はキャストすることもできますが、匿名型にキャストすることはできません。psizzle()p

そのクラスがクラス内でのみ必要な場合はFood、そこで宣言する必要があります

class Food {
    EdiblePopcorn p = new EdiblePopcorn() {

        @Override
        public void sizzle() {
            System.out.println("anonymous sizzling popcorn");
        }

        @Override
        public void pop() {
            System.out.println("anonymous popcorn");
        }
    };

    public void popIt() {
        p.pop(); // OK, Popcorn has a pop() method
        p.sizzle(); // Also legal! EdiblePopcorn now has sizzle()
    }

    private abstract class EdiblePopcorn extends Popcorn {
        // if the sizzle body is always the same, you can declare it here.
        void sizzle();
    }
}
于 2012-12-04T22:54:46.073 に答える