內(nèi)部類有很多用法慨蓝,比如設(shè)置匿名內(nèi)部類來完成監(jiān)聽器的功能秸滴,比如使用一個內(nèi)部類來進(jìn)行一些有利自己編碼的設(shè)計雹嗦,外部類采用內(nèi)部類的實例對象來進(jìn)行操作啥酱。
我們都知道外部類只能設(shè)計成public或者default冠跷,不能修飾為private和protected南誊。但是內(nèi)部類則不同,內(nèi)部類可以被protected和private修飾蜜托,而也正因為如此抄囚,內(nèi)部類有了更高級的用法
private修飾的內(nèi)部類
public class A {
String name;
private class B{
long identityId;
public void testB(){
System.out.println("I am B");
}
}
public B getB(){
return new B();
}
}
我們在A中創(chuàng)建了一個private內(nèi)部類B,添加了一個方法getB()想去嘗試獲取這個B類橄务,如下
class test{
public static void main(String[] args) {
A a = new A();
A.B ab = a.getB(); //can't get A.B because of private
}
}
很可惜幔托,我們在另一個類test中,創(chuàng)建一個A的實例蜂挪,然后去調(diào)用getB()重挑,但是我們無法獲取A.B,也就無法使用B中的testB方法了棠涮。
是不是我們真的無法在別的類中獲取這個B的實例谬哀,無法調(diào)用B的方法呢?
不然
我們可以借助向上轉(zhuǎn)型严肪,先創(chuàng)建一個接口C
interface C{
void testB();
}
然后讓內(nèi)部類B去實現(xiàn)它
public class A {
String name;
private class B implements C{ //changes here. Implements C
long identityId;
public void testB(){
System.out.println("I am B");
}
}
public B getB(){
return new B();
}
}
那么現(xiàn)在我們在回去修改test類里的代碼史煎、
class test{
public static void main(String[] args) {
A a = new A();
C ab = a.getB(); //we get a C
ab.testB(); //use testB
}
}
小結(jié)
我們通過一個接口C谦屑,然后private內(nèi)部類去實現(xiàn)它,從而讓我們可以借助向上轉(zhuǎn)型獲取到內(nèi)部類B的一個引用劲室。但是仍有一個問題伦仍,獲取到后可以調(diào)用B實現(xiàn)接口C的那些方法结窘,但是我們?nèi)匀徊恢繠中的具體細(xì)節(jié)很洋,
優(yōu)點:這就體現(xiàn)了一種很好的封裝,也完全阻止了任何依賴于類型的編碼隧枫。
protected修飾的內(nèi)部類
這種情況比較簡單喉磁,就是如果內(nèi)部類B的修飾是protected,那么A類的所有子類是可以任意獲取到A的內(nèi)部類B的官脓,但是其它類不行协怒。
讀者可以根據(jù)上面的例子,自行嘗試卑笨,這里不贅述孕暇。
總結(jié)
本節(jié)主要記錄了內(nèi)部類的一種設(shè)計方法,可以通過給內(nèi)部類private修飾赤兴,完全隱藏實現(xiàn)的細(xì)節(jié)妖滔,只提供一個外部接口,同時因為使用的是接口桶良,所以也完全阻止任何依賴于類型的編碼