本文共6150字,大約閱讀8分鐘
內部類及Lambda表達式
內部類
- 概念
在一個類的內部,定義了一個完整的類,稱作內部類
//外部類
class Outer{
//內部類
class Inner{
}
}
- 內部類編譯之後會生成獨立的 .class 文件,.class文件命名方式爲
外部類類名$內部類類名.class
- 內部類可以直接訪問外部類的成員;
通常將內部類作爲外部類的組件構成 - 內部類的分類
成員內部類、靜態內部類、局部內部類、匿名內部類
成員內部類(類比於 實例變量)
- 位置
定義在類以內,方法以外 - 成員內部類對象的創建
成員內部類對象的創建,必須依賴於外部類的對象而創建
Outer o = new Outer(); //創建外部類的對象
Outer.Inner i = o.new Inner(); //創建成員內部類的對象
- 成員內部類可以直接訪問外部類的屬性和方法(私有的也可以訪問)
- 外部類的當前對象
外部類類名.this
外部類類名.this.屬性名 //訪問外部類的屬性
外部類類名.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;
}
}
}
靜態內部類(類比於 靜態變量)
- 位置
定義在類以內,方法以外,被static修飾的內部類 - 靜態內部類可以定義實例變量和靜態變量(方法同)
- 創建靜態內部類的對象
外部類類名.靜態內部類的類名.引用名 = new 外部類類名.靜態內部類類名(); - 訪問靜態內部類的靜態成員
可以直接通過類名訪問
外部類類名.靜態內部類類名.靜態屬性 //訪問靜態內部類的靜態屬性
外部類類名.靜態內部類類名.靜態方法(實參) //訪問靜態內部類的靜態方法
- 靜態內部類只能直接訪問外部類靜態成員(靜態屬性和靜態方法)
靜態內部類中不能直接訪問外部類的非靜態成員
靜態內部類案例
public class TestStaticInner {
public static void main(String[] args) {
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("靜態內部類的靜態方法");
}
}
}
打印結果↓↓↓
2
靜態內部類的靜態方法
局部內部類(類比於 局部變量)
- 位置
定義在函數、方法以內 - 創建局部內部類的對象,需要在定義它的方法內部完成對象的創建,同時創建對象應該在類定義以後位置(先定義類,再創建對象)
注意
局部內部類既可以定義在成員方法,也可以定義在靜態方法 - 局部內部類可以直接訪問外部類的成員(靜態成員+非靜態成員)
注意
局部內部類可以訪問定義它的方法內部的局部變量,但是局部變量必須被final修飾,才能被局部內部類訪問
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);
//System.out.println("f="+f);
//局部內部類
class Inner {
int a=1;
public void inner_method() {
System.out.println("局部內部類的成員方法");
System.out.println("n="+n);
//System.out.println("f="+f);
System.out.println("m="+m);
}
}
//創建局部內部類的對象
Inner i=new Inner();
System.out.println(i.a);
i.inner_method();
}
}
打印結果↓↓↓
外部類的成員方法
m=6
1
局部內部類的成員方法
n=3
m=6
匿名內部類
- 匿名內部類
是一種特殊的局部內部類 - 特點
- 匿名內部類的定義必須繼承一個父類或是嫌一個接口
- 基於一個匿名內部類只能創建該類的一個對象,並且匿名內部類的定義和對象的創建一起完成
- 語法
接口名 引用名 = new 接口名(){
// 接口中需要實現的方法 };
- 匿名內部類的優缺點
- 優點:減小代碼量,讓編程思路連貫
- 缺點:可讀性低
匿名內部類案例1
interface IA{ //定義接口IA
void m1(); //接口中的方法
}
public class Test{
public static void main(String[] args){
IA ia = new IA(){
public void m1(){}
};
}
}
匿名內部類案例2
public class Test {
public static void main(String[] args) {
MyClass mc =new MyClass(){
public void method(){
System.out.println("子類覆蓋後的方法。。。");
}
};
mc.method();
}
}
class MyClass{
public void method(){
System.out.println("父類中method方法/...");
}
}
匿名內部類案例3
public class TestAnonymousInner {
public static void main(String[] args) {
IB ib = new IB() {
public void m2() {
System.out.println("m2方法實現");
}
public void m3() {
System.out.println("m3方法實現");
}
};
ib.m2();
ib.m3();
test(new IB() {
public void m2() {
System.out.println("m2方法實現");
}
public void m3() {
System.out.println("m3方法實現");
}
});
}
public static void test(IB ib) {
ib.m2();
}
}
interface IB {
void m2();
void m3();
}
打印結果如下↓↓↓
m2方法實現
m3方法實現
m2方法實現
匿名內部類實戰
1.匿名內部類實現接口:功能:判斷兩數之和是否大於100,是true 否false;
2.匿名內部類實現接口:功能:判斷a-b是否大於0,是true 否false;
要求:調用接口方法,打印結果
public class TestAnonymousInner2 {
public static void main(String[] args) {
// 1.匿名內部類實現接口:功能:判斷兩數之和是否大於100,是true 否false
// 調用接口方法,打印結果
Toolable ta = new Toolable() {
public boolean isAccord(int a, int b) {
if (a + b > 100) {
return true;
} else {
return false;
}
}
};
System.out.println(ta.isAccord(5, 99));
// 2.匿名內部類實現接口:功能:判斷a-b是否大於0,是true 否false
// 調用接口方法,打印結果
Toolable ta1 = new Toolable() {
public boolean isAccord(int a, int b) {
if (a - b > 0) {
return true;
} else {
return false;
}
}
};
System.out.println(ta.isAccord(5, 99));
}
}
interface Toolable {
boolean isAccord(int a, int b);
}
打印結果如下↓↓↓
true
false
Lambda表達式
- 功能
實現函數式接口並完成對象的創建,是匿名內部類簡化形式 - 應用場景
當接口中只有一個抽象方法時(靜態方法、默認方法不在其中) - 語法
接口名 引用 = (形參列表) ->{ //方法實現部分 };
- 語法解釋
-> 是JDK8新引入的一個語法符號
-> 左側:Lambda表達式參數,即接口方法中形參部分
-> 右側:指Lambda表達式執行功能部分,即接口方法實現部分
- 語法解釋
- 具體使用
- 無參數,無返回值
語法結構
接口名 引用 = () ->{ //方法實現部分 };
當{}中只有一行語句時,{}可略,但不建議 - 帶有參數無返回值
語法結構
接口名 引用 = (數據類型 變量名,數據類型 變量名) -> { //方法實現 }
注意:Lambda表達式形參列表的數據類型可以省略,編譯器自行推斷 - 帶有參數有返回值
語法結構
接口名 引用 = (形參列表) -> { return xxx; }
注意:如果{}中只有一條 return 語句,return語句和{}可 以省略(一 起)
- 無參數,無返回值
Lambda表達式案例
public class TestAnonymousInner3 {
public static void main(String[] args) {
// 無參無返回值方法的打印語法
IE ie = () -> System.out.println("aaa");
ie.ma();
// 有參無返回值方法的打印語法
IF If = (int a) -> {
System.out.println(a);
};
If.mf(3);
// 有參有返回值方法的打印方法
IG ig = (int a, int b) -> {
return a + b;
};
System.out.println(ig.mg(4, 5));
}
}
interface IE {
// 無參無返回值方法
void ma();
}
interface IF {
// 有參無返回值方法
void mf(int a);
}
interface IG {
// 有參有返回值方法
int mg(int a, int b);
}
打印結果如下↓↓↓
aaa
3
9
Lambda表達式在實際問題中的使用
1.匿名內部類實現接口:功能:判斷兩數之和是否大於100,是true 否false;
2.匿名內部類實現接口:功能:判斷a-b是否大於0,是true 否false;
要求:調用接口方法,打印結果
public class TestAnonymousInner2 {
public static void main(String[] args) {
// 1.匿名內部類實現接口:功能:判斷兩數之和是否大於100,是true 否false
// 調用接口方法,打印結果
// lambda簡化
Toolable ta1 = (int a, int b) -> a + b > 100;
System.out.println(ta1.isAccord(2, 67));
// lambda 三目
Toolable ta2 = (int a, int b) -> a + b > 100 ? true : false;
System.out.println(ta2.isAccord(2, 67));
// lambda 條件判斷
Toolable ta3 = (int a, int b) -> {
if (a + b > 100) {
return true;
} else
{
return false;
}
};
System.out.println(ta3.isAccord(2, 67));
System.out.println("+++++");
// 2.匿名內部類實現接口:功能:判斷a-b是否大於0,是true 否false
// 調用接口方法,打印結果
// lambda簡化
Toolable ta4 = (int a, int b) -> a - b > 0;
System.out.println(ta4.isAccord(87, 67));
// lambda 三目
Toolable ta5 = (int a, int b) -> a + b > 100 ? true : false;
System.out.println(ta5.isAccord(2, 67));
// lambda 條件判斷
Toolable ta6 = (int a, int b) -> {
if (a + b > 100) {
return true;
} else
{
return false;
}
};
System.out.println(ta6.isAccord(2, 67));
}
}
interface Toolable {
boolean isAccord(int a, int b);
}
打印結果如下↓↓↓
false
false
false
+++++
true
false
false
整理不易,喜歡請點個贊!
編者微信:1014961803,添加時請備註"CSDN"