1.1、內部類概念
定義在一個類內部中的另一個類,被稱為內部類
特點:
可以直接訪問,內部類的外部類中的,成員屬性和方法(包含-PRivate)
外部類要訪問內部類中的成員和方法,需要先建立內部類對象
1.2、示例
package com.day08.innerclass.demo1;/** * 包含內部類 * @author denny * */public class Outer { //外部類 //private成員 private String name="張三"; private int age=20; private String gender="男"; /** * 內部類 */ class Inner{ private int num=3; public void hello(){ System.out.println("姓名:"+name+"年齡:"+age +"性別:"+gender); } public int getNum() { return num; } public void setNum(int num) { this.num = num; } } /* * 外部類中的方法 */ public void show(){ System.out.println("姓名:"+this.name+"年齡:"+this.age +"性別:"+this.gender); } /* * 調用內部類 */ public void say(){ Inner inner=new Inner(); System.out.println("調用內部類:"+"num="+inner.getNum()+", num="+inner.num); } public String getName() { return name; } public void setName(String name) { this.name = name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } public String getGender() { return gender; } public void setGender(String gender) { this.gender = gender; } }
測試外部類
package com.day08.innerclass.demo1;public class OuterTest { public static void main(String[] args) { //外部類調用內部類 Outer o=new Outer(); o.show(); o.say(); }}結果:
姓名:張三年齡:20性別:男
調用內部類:num=3, num=3
測試內部類
package com.day08.innerclass.demo1;public class InnerTest1 { public static void main(String[] args) { // 聲明內部類中對 象,先聲明外部類,再聲明內部類 Outer.Inner inner = new Outer().new Inner(); inner.hello(); }}姓名:張三年齡:20性別:男
調用內部類:num=3, num=3
1.3、靜態內部類
如果內部類是static修飾的就只能調用父類中static成員
聲明方式,可直接外部類.內部類()來聲明或者調用
package com.day08.innerclass.demo3;public class Outer { //private成員 private String name="張三"; static int age=20; private String gender="男"; /* * 外部類中的方法 */ public void show(){ System.out.println("姓名:"+this.name+"年齡:"+this.age +"性別:"+this.gender); } /** * 內部類 */ static class Inner{ private int num=3; public void hello(){ System.out.println("外部類年齡:"+age +",內部類屬性"+this.num); } } public static void main(String[] args) { //靜態內部類可以直接通過外部類.內部類聲明 Outer.Inner inner=new Outer.Inner(); inner.hello(); }}
外部類年齡:20,內部類屬性3
1.4、內部類成員是static的話
這個內部類必須被static修飾,static只能調用外部類和內部類中的stiatic的成員.
package com.day08.innerclass.demo3;public class Outer { //private成員 private String name="張三"; static int age=20; private String gender="男"; /* * 外部類中的方法 */ public void show(){ System.out.println("姓名:"+this.name+"年齡:"+this.age +"性別:"+this.gender); } /** * 內部類 */ static class Inner{ private static int num=3; public static void hello(){ System.out.println("外部類年齡:"+age +",內部類屬性"+num); } } public static void main(String[] args) { //靜態內部類m成員也是靜態的可以直接調用 Outer.Inner.hello(); }}
結果:外部類年齡:20,內部類屬性3
1.5、聲明在外部類中成員方法中的內部類
聲明成員方法中的,內部類,調用成員方法中的局部變量 時,成員方法中的局部變量 必須為final修飾
package com.day08.innerclass.demo3;public class Outer { // private成員 private String name = "張三"; static int age = 20; private String gender = "男"; /* * 外部類中的方法 */ public void show(int x) { final int y = 5; //System.out.println("姓名:" + this.name + "年齡:" + this.age + "性別:" + this.gender); class Inner { public void hello() { System.out.println("hello-------"+x + " ," + y); } } Inner inner = new Inner(); inner.hello(); } /** * 內部類 */ public static void main(String[] args) { //聲明成員方法中的,內部類,調用成員方法中的局部變量 時,成員方法中的局部變量 必須為final修飾 new Outer().show(8); }}hello-------8 ,5
1.6、為什么內部類能直接訪問外部類中的成員呢?
package com.day08.innerclass.demo4;public class Outer { private int num=3; class Inner{ private int num=4; public void show(){ int num=5; //局部變量 System.out.println(num); //內部類的成員變量 System.out.println(this.num); //外部類的成員變量 System.out.println(Outer.this.num); } } public static void main(String [] args){ new Outer().new Inner().show(); }}2.1、匿名內部類概念
內部類可以繼承或實現一個外部類或者接口。
格式:
new 外部類名或者接口名(){覆蓋類或者接口中的代碼,(也可以自定義內容。)}
簡單理解:
就是建立一個帶內容的外部類或者接口的子類匿名對象。
什么時候使用匿名內部類呢?
通常使用方法是接口類型參數,并且該接口中的方法不超過三個,可以將匿名內部類作為參數傳遞。
好處:
增強閱讀性。
2.2、重寫類中的方法
package com.day08.innerclass.demo5;/** * 抽象類 * @author denny * */public abstract class Person { private String name="張三"; public void show(){ System.out.println(this.name); } public String getName() { return name; } public void setName(String name) { this.name = name; } }
package com.day08.innerclass.demo5;/** * 外部類 * * @author denny 實現有一個方法的抽象類的匿名內部類 * */public class Outer { private int num = 3; public void say() { new Person() {// 匿名內部類 public void show() { //重寫抽象類中的方法,抽象方法,普通方法都可以 System.out.println("..............." + num); } }.show(); //對象創建完成,調用自己 } public static void main(String[] args) { new Outer().say(); }}
結果:
...............3
第二種寫法,適后重寫了多個方法
package com.day08.innerclass.demo5;/** * 外部類 * * @author denny 實現有一個方法的抽象類的匿名內部類 * */public class Outer { private int num = 3; public void say() { Person person=new Person() {// 匿名內部類 public void show() { //重寫抽象類中的方法,抽象方法,普通方法都可以 System.out.println("..............." + num); } }; //對象創建完成 person.show(); } public static void main(String[] args) { new Outer().say(); }}2.3、示例使用接口的方式
package com.day08.innerclass.demo6;/** * 接口 * @author denny * */public interface BirdPro { /** * 2個抽象方法 */ public void shout(); public void accact();}package com.day08.innerclass.demo6;public class Outer { private String name="張三"; public void show(){ int y=3; BirdPro birdPro=new BirdPro(){ //實現接口中的方法 @Override public void shout() { System.out.println(name+","+y); } @Override public void accact() { System.out.println(y+","+name); } }; birdPro.shout(); birdPro.accact(); } public String getName() { return name; } public void setName(String name) { this.name = name; } public static void main(String[] args) { new Outer().show(); }}結果:
張三,3
3,張三
2.4、把匿名內部類做參數傳遞
package com.day08.innerclass.demo6;/** * 接口 * * @author denny * */public interface BirdPro { /** * 2個抽象方法 */ public void shout(); public void accact();}
package com.day08.innerclass.demo6;class InnerDemo { public static void main(String[] args) { // 把接口做參數傳遞 show(new BirdPro() { // 實現接口中的方法 @Override public void shout() { System.out.println("叫聲"); } @Override public void accact() { System.out.println("攻擊"); } }); } public static void show(BirdPro birdPro) {// 做參數 // 調用 birdPro.accact(); birdPro.shout(); }}
2.5、 初始化順序
package com.day08.innerclass.demo2;public class Fu { int num = 9; static{ System.out.println(" static Fu"); } { System.out.println("Fu"); } Fu() { super();// Object // 顯示初始化 // 構造代碼塊初始化 show(); // 構造函數調用方法,如果子類已經重寫了,父類的方法,則執行子類的方法,但這時,成員還沒有初初始化,所以為默認值 } void show() { System.out.println("fu show " + num);// 被覆蓋,運行子類的 }}
package com.day08.innerclass.demo2;public class Zi extends Fu { int num = 8; static{ System.out.println(" static Zi"); } { System.out.println("Zi" ); } Zi(){ super(); //顯示初始化 //構造代碼塊初始化 show(); } void show(){ System.out.println("zi show " + num); }}
package com.day08.innerclass.demo2;public class Test1 { public static void main(String[] args) { new Zi(); }}
結果:
static Fu static ZiFuzi show 0Zizi show 8
新聞熱點
疑難解答