1.コンセプト
-
内部クラス:クラス内では、完全なクラスが定義されます。
classOuter {//外部クラス
classInner {} //内部クラス
}
-
内部クラスがコンパイルされた後、別の.classファイルが生成されます。.classファイルの命名方法は次のとおりです。
外側のクラスのクラス名$内側のclass.classのクラス名
-
内部クラスは外部クラスのメンバーに直接アクセスできます。通常、内部クラスは外部クラスのコンポーネントとして構成されます。
-
内部クラスの分類:メンバー内部クラス、静的内部クラス、ローカル内部クラス、匿名内部クラス
2.メンバーの内部クラス(インスタンス変数に類似)[理解:ソースコードを読み取るときに認識します]
-
場所:クラス内、メソッド外で定義
-
メンバーの内部クラスオブジェクトの作成:外部クラスに依存するオブジェクトの作成:
Outer o = new Outer(); //外部クラスのオブジェクトを作成します
Outer.Inner i = o.new Inner(); //メンバー内部クラスのオブジェクトを作成します
-
メンバーの内部クラスは、外部クラスのプロパティとメソッドに直接アクセスできます(プライベートにもアクセスできます)
-
外部クラスのクラス名。これは、現在の外部クラスのオブジェクトを表します。
外部クラスのクラス名。this.attribute:外部クラスのプロパティにアクセスします。
外部クラスのクラス名。This。メンバーメソッド(実際のパラメーター);:外部クラスのメンバーメソッドへのアクセス
-
メンバー内部クラスは静的メンバー(静的プロパティ、静的メソッド、静的コードブロック)を定義できません
public class TestInner {
public static void main(String[] args) {
Outer o = new Outer();
// 创建成员内部类的对象:必须依赖于 外部类的对象而创建
Outer.Inner i = o.new Inner();
System.out.println(i.n);
i.inner_method();
System.out.println(o.a);
}
}
// 外部类
class Outer{
int a = 3; // 实例变量
// 成员方法
public void outer_method() {
System.out.println("外部类的成员方法....");
}
// 成员内部类(类比于实例变量)
class Inner{
int n = 7;
int a = 6; // 成员内部类中属性
//static int m = 2;
public Inner() {
}
public void inner_method() {
int a = 8;// 局部变量
System.out.println("内部类中成员方法....");
System.out.println("a="+a);
System.out.println("this.a="+this.a); System.out.println("Outer.this.a="
+Outer.this.a);
Outer.this.a = 10;
}
}
}
3つの静的内部クラス(類似:静的変数)[理解:基礎となるソースコードを読み取るとき]
-
場所:クラス内、メソッド外で定義され、静的によって変更された内部クラス
-
インスタンス変数と静的変数は静的内部クラスで定義できます(メソッドにも同じことが言えます)
-
静的内部クラスのオブジェクトを作成します。
外部クラスクラス名。静的内部クラスクラス名参照名=新しい外部クラスクラス名。静的内部クラス名();
-
静的内部クラスの静的メンバーへのアクセス:クラス名から直接アクセスできます
外部クラスクラス名。静的内部クラスクラス名。静的プロパティ:静的内部クラスの静的プロパティへのアクセス
外部クラスクラス名。静的内部クラスクラス名。静的メソッド(実際のパラメーター);静的内部クラスにアクセスするメソッド。
-
静的内部クラスは、外部クラスの静的メンバー(静的プロパティと静的メソッド)にのみ直接アクセスできます。
外部クラスの非静的メンバーは、静的内部クラスで直接アクセスすることはできません。
public class TestStaticInner { public static void main(String[] args) { // 创建静态内部类的对象 /* * MyClass.Inner i = new MyClass.Inner(); * * System.out.println(i.m); i.inner_method(); */ //i.inner_static_method(); System.out.println(MyClass.Inner.n); MyClass.Inner.inner_static_method(); } } class MyClass{ int a = 2; // 实例变量 static int b = 5; // 静态变量 public void outer_method() { System.out.println("外部类的成员方法..."); } public static void outer_static_method() { System.out.println("外部类的静态方法...."); System.out.println("b="+b); } // 静态内部类 static class Inner{ int m = 1;// 实例变量 static int n = 2; // 静态变量 public void inner_method() { System.out.println("静态内部类中成员方法...."); System.out.println("b="+b); } public static void inner_static_method() { System.out.println("静态内部类的静态方法..."); } } }
第4に、ローカル内部クラス(ローカル変数に類似)[時折ソースコードを参照、移行使用]
-
場所:関数とメソッドで定義
-
ローカル内部クラスのオブジェクトを作成するには、それを定義するメソッド内でオブジェクトの作成を完了する必要があり、オブジェクトはクラス定義の後に作成する必要があります(最初にクラスを定義し、次にオブジェクトを作成します)
-
注:ローカル内部クラスは、メンバーメソッドまたは静的メソッドで定義できます。
-
ローカル内部クラスは、外部クラスメンバー(静的メンバー+非静的メンバー)に直接アクセスできます。
注:現時点では、内部クラスはメンバーメソッドで定義されています。
-
ローカル内部クラスは、それを定義するメソッド内のローカル変数にアクセスできますが、ローカル内部クラスがアクセスする前に、ローカル変数を最終的に変更する必要があります。
JDK8.0バージョン以降では、メソッド内のローカル変数がこのメソッド内のローカル内部クラスメソッドであることをJVMが検出した場合、jvmはデフォルトでこのローカル変数の前にfinalを追加します。この構文は、シンタックスシュガーと呼ばれます。
public class TestLocalInner {
public static void main(String[] args) {
ClassA ca = new ClassA();
ca.outer_method();
}
}
class ClassA{
int n = 3;// 实例变量
static int f = 8;
public void outer_method() {
System.out.println("外部类的成员方法....");
int m = 6; // 局部变量
System.out.println("m="+m);
// 局部内部类
class Inner{
int a = 1;
public void inner_method() {
System.out.println("局部内部类的成员方法...");
System.out.println("n="+n);
System.out.println("m="+m); // final
}
}
// 局部内部类的对象
Inner i =new Inner();
System.out.println(i.a);
i.inner_method();
}
public void test() {
// System.out.println("m="+m);
}
}
5.匿名内部クラス[独自の能力に応じたオプションのコンテンツ-簡略化されたコード]
-
匿名内部クラス:特別なローカル内部クラスです
-
特徴:
(1)匿名内部クラスの定義は、親クラスを継承するか、インターフェースを実装する必要があります
(2)匿名内部クラスの定義は、オブジェクトの作成で完了し、匿名内部クラスに基づいています。
このクラスのオブジェクトは1つしか作成できません
-
文法:
interface IA{ void m1(); void m2(); } // 匿名内部类实现一个接口 IA ia = new IA(){ public void m1(){ // 方法实现的部分 } public void m2(){ // 方法实现的部分 } };
-
匿名内部クラスの長所と短所:
(1)短所:読みやすさが悪い
(2)利点:コードの量を減らし、コーディング効率を向上させる
public class TestAnonymousInner {
public static void main(String[] args) {
// 匿名内部类
IA ia=new IA() {
public void m1() {
System.out.println("匿名内部类覆盖了m1方法");
}
};
ia.m1();
ia.m1();
// 继承一个父类定义一个匿名内部类
ClassD cd = new ClassD() {
public void m1() {
System.out.println("子类覆盖了m1方法.....");
}
};
cd.m1();
cd.m2();
test(new IA(){
public void m1(){
System.out.println("实现部分...");
}
});
}
public static void test(IA ia){
ia.m1();
}
}
interface IA{
void m1();
}
class ClassD{
public void m1() {
System.out.println("父类中m1方法");
}
public void m2() {
System.out.println("父类中m2方法....");
}
}
6.ラムダ式(JDK8.0以降のアプリケーション)[このコンテンツは、独自の機能に応じてオプションです]
- ラムダ式:関数型インターフェースを実装し、オブジェクトの作成を完了する匿名内部クラスの簡略化された形式です。
-
アプリケーションシナリオ:インターフェイスに抽象メソッドが1つしかない場合(静的メソッドとデフォルトメソッドは含まれていません)
-
文法:
接口名 引用 = (形参列表) -> { // 方法实现部分 }; 语法解释: -> 是JDK8.0新引入一个语法符号 -> 左侧:Lambda表达式参数,即接口方法中形参部分 -> 右侧:指定Lambda表达式执行功能部分,即接口方法中实现部分
(1)パラメータなし、戻り値なし
a。文法構造:インターフェース名参照=()-> {//メソッド実装部分};
b。注:{}に1行しかない場合、{}は省略できますが、お勧めしません。
public class TestAnonymousInner3 { public static void main(String[] args) { IC ic = () -> { System.out.println("这是方法实现部分..."); }; ic.mc(); } } interface IC{ void mc(); }
(2)パラメータあり、戻り値なし
a。構文構造:インターフェイス名参照=(データ型変数名、データ型変数)-> {//メソッド実装部分);
b。注:Lambda式のパラメーターリストのデータ型は省略でき、コンパイラーはそれを自動的に推測します。
public class TestAnonymousInner3 { public static void main(String[] args) { ID id = (a, s) ->{ System.out.println("a="+a); System.out.println("s="+s); }; id.md(2, "小龙"); } } interface ID{ void md(int a,String str); }
(3)戻り値あり:
a。構文構造:インターフェース名参照名=(パラメーターリスト)-> {return xxx;};
b。注:{}にreturnステートメントが1つしかない場合は、returnステートメントと{}を(一緒に)省略できます。
public class TestAnonymousInner3 { public static void main(String[] args) { IE ie = (int a,int b) -> { return a+b; }; System.out.println(ie.me(3, 5)); // 如果Lambda{}实现中只有 return 语句 IE ie2 = (int a,int b) -> a+b; System.out.println(ie2.me(3, 5)); } } interface IE{ int me(int a,int b); }