序文
Javaの、いくつかのクラスが他のクラスの内側に存在している、他のクラス内に存在するいくつかのクラスがあります。いわゆる内部クラスのクラスカテゴリに定義され、カテゴリは、クラス内に含まれる外部クラス。
内部クラスのメンバー、ローカル内部クラス、匿名内部クラスと静的内部クラス:そして、クラス変数やインテリアのと同様のオブジェクトが場所と有効性に応じて、カテゴリに分かれて
アップしてみましょう合計:
内部クラスのメンバー
クラスのメンバ内部クラスが表示されます、その範囲とメンバー変数は非常に似ています。
内部クラスのメンバーとクラスを書きます:
class OuterClass
{
private int num = 0;
public void f()
{
System.out.print("Hello World!!");
}
class InnerClass
{
public void doSomething()
{
f();
System.out.println(num);
}
}
}
メソッドと変数と外のクラス
外側のクラスで、互いから両方の変数とメソッドが使用され、クラスおよびメソッドの内部メンバーは、クラス外部からアクセスすることができ、外部のクラスを介して内部クラスオブジェクトクラス及びメソッドの内部メンバーにアクセスします。メソッドのさえメンバーは、プライベートまたは変更されています。
外部クラスの外で内部クラスのオブジェクトを介して、民間の内部クラス、および外部とのこのクラスにアクセスすることはできません。
さて、あなたがお互いを呼び出すことができるので、我々は競合を命名の問題に直面するだろう、名前の競合が含まれている内部クラスローカル変数、内部クラスのメンバ変数、外部クラスのメンバ変数の間の競合を。この問題を解決するために、メカニズムやソリューションは、紛争のローカル変数とメンバ変数によって採用されたJavaクラスのメソッドを解決するために:使用して、このキーワードクラスと外部コールを。
具体的には、クラス内のメソッドでは、(非常に短いいくつかのケースを3つの変数の競合があると仮定した場合)の名前の重複をすれば、私たちは次のことができます。
- 変数名を直接使用するには、クラス内のローカル変数にアクセスします
- 使用この内部クラスのメンバ変数にアクセスするためのキーワードを
- 使用する外部クラス名.Thisを外部クラスのメンバ変数にアクセスするには、
次のコードを参照することができます:
class Outer
{
private int x;
class Inner
{
private int x;
public void doSomething(int x)
{
x = 1;
this.x = 2;
Outer.this.x = 3;
}
}
}
例内部クラス
外部クラス外:
オブジェクトの内部クラスは、クラス外部のオブジェクトに依存しなければなりません!!
オブジェクトの内部クラスは、クラス外部のオブジェクトに依存しなければなりません!!
オブジェクトの内部クラスは、クラス外部のオブジェクトに依存しなければなりません!!
(三回言うべき重要なこと)
すでに存在している外部のオブジェクトが存在しない場合はそれはクラス内のそのメンバーが表示されるターゲットにすることは不可能である、です。
例として内部クラスのオブジェクトの構文は次のとおりです。
外部类.内部类 对象名 = 外部类对象.new 内部类();
コードが書かれました:
OuterClass out = new OuterClass();
OuterClass.InnerClass in = out.new InnerClass();
最初の文の例および外部オブジェクト、その後、外側のクラスの内部クラスオブジェクトのオブジェクトインスタンスで新しいキーワード。
クラス外では、あなたが直接外部クラスのオブジェクトを作成することができます。
したがって、また、クラスオブジェクトを提供することができる方法は、それにより、このメソッドを呼び出すことにより、内部のクラスオブジェクトを取得し、外側のクラスの内部で作成されています。
例えば、この方法は、外側のクラスに追加されました。
public InnerClass getInner()
{
return new InnerClass();
}
そして、内部クラスをインスタンス化するために、このメソッドを呼び出します。
OuterClass oc = new OuterClass();
OuterClass.InnerClass ic = oc.getInner();
しかし、仕方のこの定義は、まだメソッドを呼び出すために、クラスの外の物体の存在を必要とすることに留意すべきです。
何?あなたは、その方法は、静的クラスは、それによって呼び出すことができる書かないでと言いましたか?
静的メソッドでロードされたが、この質問に答えるだけクラスの内容を注意することは、ロードされているが、それはインタプリタがそれを認識しないと、エラーを促すメッセージが表示されますときに、この方法にチェックインし、クラス内の積載量のメンバーではありません。あなたが見ることができると信じてはいけない:
エラーメッセージ:
何?静的な内部クラスは、まだ十分に変更されていませんか?EMM、あなたは正しいですが、それは内部クラスのAH /元首のメンバーではありません。これは、最後の部分で詳述する内部クラスの静的内部クラスのメンバーではありません。
最後に、口を挿入するために、同じ内部クラスとメンバ変数のメンバーにも適用範囲を指定することができ、あなたがそれにアクセスできる場所を決定します。変更がプライベートである場合には、それだけクラスの外部の物体によって内部使用または方法のためのクラスの外側を得ることができ、また、なお、非公開内部クラスは、外部クラス外部クラス名に外部のクラス名によるアクセスに限定されるものではありません:これに類似:
内部クラス・カテゴリーへの外部からのアクセススルーを与えられています。
部分的な内部クラス
塔内寝具のメンバーと、ローカル内部クラスを理解することが容易になります。
まず、内部ローカルクラス定義内部に定義された任意のクラスに適用されたクラスやメソッドの外に定義されているので、クラススコープの外部から得ることが、おおよそ外側クラスのクラスメソッドに移動内部クラスとして理解することができますそれはとてもローカル内部クラスの名前、ローカルメソッド内のメンバーになります。
使用時には、に注意を払うの必要性は、あなたがちょうど言ったようなものです。このクラスはメソッドではなく、外側のクラスの一部の一部です。
また、留意すべきであるローカル内部クラスのみ、最終修正方法は定数でアクセスすることができ、その値を変更することはできません。
それはこのように書かれている場合:
class Outer
{
public void doSomethingOut(final int x,int y)
{
class Inner
{
private int a = x;
private int b = y;
}
}
}
Yの訪問は不正なレポートになります。
匿名内部クラス
接着来介绍一个比较特殊的类,这个类有些惨,他们总是被一次性使用,也因此没有自己的类名,成全了别的类,自己却不留功与名。
那么这个类从那里来的呢,还得从接口实例化对象说起。众所周知,接口是一种抽象类,而一个抽象类是无法实例化自身类的对象的,除非下转型为子类的对象。这个性质对于接口来讲,想要给一个接口类型的变量实例化对象,就必须实例化一个实现了该接口的类。
有时候,实例化一个接口对象只是希望这个对象能够纯粹的实现接口中的方法,可以选择写一个类来实现这个接口并重写这些方法,但又不太需要一直保留这个类,毕竟它占着一个命名。
所以java提供了匿名内部类这种类,可以在实现接口时临时为接口编写一次性的实现接口的类,而由于是一次性的使用,这样的类没有命名,于是成为匿名内部类。
具体的语法如下:
接口名 变量 = new 接口(){
匿名内部类内容
};
需要注意的有两点:
- 接口变量引用的,是匿名内部类的对象而非接口的对象
- 在实现内部类后,不要忘记写分号
举个例子:
interface A
{
public void doSomething();
}
public class Main {
public static void main(String[] args)
{
A a = new A(){
public void doSomething()
{
System.out.print("hello world");
}
};
}
}
当然,也可以选择在继承了某个接口的类中实现一个通过匿名内部类获得接口对象的方法。
例如:
class aClass implements Comparator<Integer>
{
public int compare(Integer o1, Integer o2) {
return o1 - o2;
}
static public Comparator<Integer> getComparator()
{
return new Comparator<Integer>(){
public int compare(Integer o1,Integer o2)
{
return o1 - o2;
}
};
}
}
public class Main {
public static void main(String[] args)
{
Comparator<Integer> judge = aClass.getComparator();
}
}
静态内部类
最后,让我们来分析一下这个在一开始就提到的内部类。
在内部类前面添加修饰符static,我们就得到了一个静态内部类。
由于它是静态的,导致了它在表现出的性质上与其他内部类存在不同,不同之处有:
- 静态内部类可以声明静态成员,而非静态内部类不可以
- 静态内部类不可以访问外部类的非静态成员
- 创建静态内部类对象不需要外部类对象
可参考下图: