匿名クラスは名前を持たないクラスなので参照できません。これらは、作成時に新しいステートメントの一部として宣言する必要があります。これには、以下に示すように、別の形式の new ステートメントが必要です: new
Java コード
interface pr { void print1(); } public class noNameClass { public pr dest() { return new pr(){ public void print1() { System.out.println("Hello world!!"); } }; } public static void main(String args[]) { noNameClass c = new noNameClass(); pr hw=c.dest(); hw.print1(); } }
pr もクラスにすることができますが、外部から呼び出すメソッドはクラスまたはインターフェイスで宣言する必要があります。
おそらく、内部匿名クラスとして最も一般的に使用される場所です。 JavaはListnerにあり、Frameに追加されています。
次のように:
Java コード
import java.awt.*; import java.awt.event.*; public class QFrame extends Frame { public QFrame() { this.setTitle(\"my application\"); addWindowListener(new WindowAdapter() { public void windowClosing(WindowEvent e) { dispose(); System.exit(0); } }); this.setBounds(10,10,200,200); } }
内部匿名クラスは内部クラスを作成しますが、名前が付けられていません。つまり、インスタンスを参照する変数がありません。
new WindowAdapter() { public void windowClosing(WindowEvent e) { dispose(); System.exit(0); } }
new は、WindowAdapter オブジェクトを作成することです。次の {} は、括弧内の操作がこのデフォルト オブジェクトに作用することを示し、上記の Java プログラムの後に関数本体が続きます。
この使用法の目的は、オブジェクトのインスタンスを作成し、その関数の 1 つをオーバーライドすることです。 WindowAdapter コードを開くと、これを見つけることができます。抽象クラスです。これは、WindowListener インターフェイスの実装です。 Frame.addWindowListner(); のパラメータは WindowListner であり、実装は WindowAdapter から派生した匿名クラスを渡します。
1. 匿名クラスの存在を確認するには?名前が見えません。親クラスから new で作成されたオブジェクトのように感じます。また、匿名クラスには名前がありません。
最初に疑似コードを見てみましょう
abstract class Father(){ .... } public class Test{ Father f1 = new Father(){ .... } //这里就是有个匿名内部类 }
一般的に、オブジェクトを new するときは、括弧の後にセミコロンが必要です。つまり、オブジェクトが終了するときに new のステートメントが続きます。
ただし、匿名の内部クラスが括弧の後にあり、その括弧の中に新しいオブジェクトの特定の実装メソッドが含まれる場合は異なります。
抽象クラスを直接 new することはできないことがわかっているため、実装クラスを new する前に、まず実装クラスを作成する必要があります。
上記の疑似コードは、new が Father の実装クラスであることを意味します。この実装クラスは匿名の内部クラスです。
実際、上記の匿名内部クラスを分割すると、
class SonOne extends Father{ ...//这里的代码和上面匿名内部类,大括号中的代码是一样的 } public class Test{ Father f1 = new SonOne() ; }
2. 匿名内部クラスに関する注意事項
匿名クラスの宣言はコンパイル時に行われ、インスタンス化は実行時に行われることに注意してください。これは、for ループ内の新しいステートメントが、複数の異なる匿名クラスの 1 つのインスタンスを作成するのではなく、同じ匿名クラスの複数のインスタンスを作成することを意味します。
匿名内部クラスを使用する場合は、次の原則に注意してください:
・匿名内部クラスはコンストラクターを持つことができません。
・匿名内部クラスは静的メンバー、メソッド、クラスを定義できません。
・匿名の内部クラスは、パブリック、プロテクト、プライベート、または静的にすることはできません。
・匿名内部クラスのインスタンスは1つだけ作成できます。
· 匿名内部クラスは new の背後にある必要があり、暗黙的にインターフェイスを実装したり、クラスを実装したりするために使用されます。
・匿名内部クラスはローカル内部クラスであるため、ローカル内部クラスに対するすべての制限がそれらに影響します。
· 内部クラスは、外部クラスの静的変数または静的メソッドにのみアクセスできます。
匿名クラスと内部クラスのこれ:
場合によっては、いくつかの内部クラスと匿名クラスを使用します。匿名クラスでこれを使用する場合、これは匿名クラスまたは内部クラス自体を指します。このとき、外部クラスのメソッドと変数を使用したい場合は、外部クラスのクラス名を追加する必要があります
3. 匿名内部クラスの役割
Java の内部クラスは、C++ のネストされたクラスとは本質的に異なります。 C++ のネストされたクラスには、ラッパー クラスへのハンドルがありません。これはカプセル化の概念を表現しているだけですが、Java の内部クラスは異なり、パッケージ化クラスのメンバーにアクセスできます (つまり、パッケージ化クラスへのハンドルを持っています)。
匿名内部クラスは内部クラスの簡略化された書き方です: return new Wrapper {
...
};
以下と同等: Wrapped extends Wrapper {
...
}
return new Wrapped();クラスの役割はこれだけですか?
次のケースを考えてみましょう:
interface ICount { int count(); } class Parent { int i = 0; int count() { return i++; } }
class Child extends Parent { ICount getCount() { return new ICount { int i = 0; int count() { return (i *= 2); } } } }
public static void main(String[] args) { theApp = new Analyzer(); SwingUtilities.invokeLater(new Runnable() { // Anonymous Runnable class // object public void run() { // Run method executed in thread theApp.creatGUI(); // Call static GUI creator } }); } public static void main(String[] args) { theApp = new Analyzer(); // 创建一个对象 SwingUtilities.invokeLater(new Runnable() { // Anonymous Runnable class // 一个匿名内部类,他实现了一个线程 // 原本这个方法是传一个Runnable类型参数 // 这里可以通过这种匿名类的方式来实现 // object public void run() { // Run method executed in thread theApp.creatGUI(); // Call static GUI creator } }); }