內(nèi)部類
把類定義在其他類的內(nèi)部,這個(gè)類就被稱為內(nèi)部類朱嘴。
內(nèi)部類可以直接訪問(wèn)外部類的成員倾鲫,
內(nèi)部類編譯生成的.class文件是Outer$Inner.class
內(nèi)部類具有延遲加載的功能
成員內(nèi)部類
在類的成員位置的內(nèi)部類,就是成員內(nèi)部類
訪問(wèn)
public class InnerClassDome {
public static void main(String[] args) {
Outer.Inner i = new Outer().new Inner(); //不需要導(dǎo)包直接使用
i.show();
Inner i2 = new Outer().new Inner(); //需要導(dǎo)包import com.leex.interClass.Outer.Inner;
Inner i3 = new Outer().getInner(); //如果Inner是私有的類萍嬉,private class Innter{}
Outer.Inner i4 = new Outer().getInner();
}
}
class Outer {
private int num = 10;
class Inner {
public void show() {
System.out.println(num);
}
}
public Inner getInner() { //這樣寫還可以給訪問(wèn)加限制,并用private修飾Inner,提高內(nèi)部類的安全性
return new Inner();
}
}
普通的類只能被public和默認(rèn)修飾乌昔,內(nèi)部類可以被public,protected壤追,默認(rèn)磕道,private
靜態(tài)內(nèi)部類
靜態(tài)內(nèi)部類可以理解成外部類的靜態(tài)成員
- 普通的類不能被static修飾,而內(nèi)部類可以
- 靜態(tài)內(nèi)部類只能訪問(wèn)外部?jī)?nèi)的靜態(tài)屬性行冰,不能訪問(wèn)非靜態(tài)的屬性數(shù)
訪問(wèn)
成員內(nèi)部類被靜態(tài)修飾后的訪問(wèn)
public class InnerClassDome2 {
public static void main(String[] args) {
Outer2.Inner i = new Outer2.Inner();
Inner i1 = new Inner(); //要導(dǎo)包溺蕉,一般不這樣寫伶丐,代碼可讀性差
}
}
class Outer2 {
private static int num = 10;
static class Inner {
public void show() {
System.out.println(num);
}
}
public Inner getInner() { //同樣可以用方法訪問(wèn),但是失去了static的意義
return new Inner();
}
}
內(nèi)部類為了方便訪問(wèn)加static焙贷,為了安全加private
注意
內(nèi)部類和外部類沒(méi)有繼承關(guān)系
/*
面試題:
要求請(qǐng)?zhí)羁辗謩e輸出30撵割,20,10辙芍。
注意:
1:內(nèi)部類和外部類沒(méi)有繼承關(guān)系啡彬。
2:通過(guò)外部類名限定this對(duì)象
Outer.this
*/
class Outer {
public int num = 10;
class Inner {
public int num = 20;
public void show() {
int num = 30;
System.out.println(num);
System.out.println(this.num);
//System.out.println()
//System.out.println(new Outer().num); //也可以
System.out.println(Outer.this.num);
}
}
}
class InnerClassTest {
public static void main(String[] args) {
Outer.Inner oi = new Outer().new Inner();
oi.show();
}
}
局部?jī)?nèi)部類
1.7之前只能訪問(wèn)final修飾的局部變量
1.8之后可以訪問(wèn)非final修飾的局部變量
public class InnerClassDome2 {
public static void main(String[] args) {
new Outer2().mothed();
}
}
class Outer2 {
private int num = 10;
public void mothed() {
class Inner {
private int num2 = 20;
public void show() {
System.out.println(num); //10
System.out.println(num2); //20
}
}
Inner i = new Inner();
i.show();
}
}
匿名內(nèi)部類
- 匿名內(nèi)部類
- 就是內(nèi)部類的簡(jiǎn)化寫法。
- 前提:存在一個(gè)類或者接口
- 這里的類可以是具體類也可以是抽象類故硅。
- 本質(zhì)是一個(gè)繼承了該類或者實(shí)現(xiàn)了該接口的子類匿名對(duì)象庶灿。
class Outer2 {
Inner3 i3 = new Inner3() { //在外部類的成員位置,必須要有變量接收對(duì)象(多態(tài))
@Override
public void show() {
System.out.println("Inner3");
}
};
public void mothed() {
new Inner() { //在局部位置吃衅,可以接收也可以接收
@Override
public void show() {
System.out.println("Inner");
}
}.show(); //直接調(diào)用方法往踢,只能用一次
Inner2 i = new Inner2() { //多態(tài)
@Override
public void show() {
System.out.println("Inner2");
}
};
i.show(); //獲取后調(diào)用
i3.show();
}
}
interface Inner{
public void show();
}
abstract class Inner2{
public abstract void show();
}
abstract class Inner3{
public abstract void show();
}
應(yīng)用
當(dāng)一個(gè)方法的形參是一個(gè)接口或抽象類時(shí),傳入的應(yīng)該是一個(gè)該接口或抽象類的具體子類的對(duì)象徘层,所以可以使用匿名內(nèi)部類
/*
匿名內(nèi)部類在開(kāi)發(fā)中的使用
*/
interface Person {
public abstract void study();
}
class PersonDemo {
//接口名作為形式參數(shù)
//其實(shí)這里需要的不是接口峻呕,而是該接口的實(shí)現(xiàn)類的對(duì)象
public void method(Person p) {
p.study();
}
}
//實(shí)現(xiàn)類
class Student implements Person {
public void study() {
System.out.println("好好學(xué)習(xí),天天向上");
}
}
class InnerClassTest2 {
public static void main(String[] args) {
//測(cè)試
PersonDemo pd = new PersonDemo();
Person p = new Student();
pd.method(p);
System.out.println("--------------------");
//匿名內(nèi)部類在開(kāi)發(fā)中的使用
//匿名內(nèi)部類的本質(zhì)是繼承類或者實(shí)現(xiàn)了接口的子類匿名對(duì)象
pd.method(new Person(){
public void study() {
System.out.println("好好學(xué)習(xí),天天向上");
}
});
}
}