更新時間:2020-10-20 17:57:39 來源:動力節(jié)點 瀏覽1138次
一般情況下,我們創(chuàng)建類和接口的時候都是一個類一個文件,一個接口一個文件,但有時候為了方便或者某些特殊的原因,java并不介意在一個文件中寫多個類和多個接口,于是就需要用到我們今天要講的內(nèi)部類和內(nèi)部接口。
一、內(nèi)部類
先講內(nèi)部類,內(nèi)部類就是在類中定義的類。類中的類可以看做是類的一個屬性,一個屬性可以是static也可以是非static的。而內(nèi)部類也可以定義在類的方法中,再加上匿名類,總共有5種內(nèi)部類。
1.靜態(tài)內(nèi)部類
我們在class內(nèi)部定義一個static的class,如下所示:
@Slf4j
public class StaticInnerClass {
static class Inner {
void print() {
log.info("Inner class is: " + this);
}
}
public static void main(String[] args) {
StaticInnerClass.Inner inner = new StaticInnerClass.Inner();
inner.print();
}
}
因為static變量可以直接根據(jù)類名來存取,所以我們使用new StaticInnerClass.Inner()來實例化內(nèi)部類。
2.非靜態(tài)內(nèi)部類
class中定義的類也可以是非靜態(tài)的,如下所示:
@Slf4j
public class InnerClass {
class Inner {
void print() {
log.info("Inner class is: " + this);
}
}
public static void main(String[] args) {
InnerClass.Inner inner = new InnerClass().new Inner();
inner.print();
}
}
要訪問到類的變量,需要實例化外部內(nèi),然后再實例化內(nèi)部類:new InnerClass().new Inner()。
注意這里我們需要使用到兩個new。
3.靜態(tài)方法內(nèi)部類
我們可以在靜態(tài)方法中定義一個類,這個類其實就相當于方法中的變量,這個變量當然不能是static的。我們看下面的例子:
@Slf4j
public class StaticMethodInnerClass {
private static String x = "static x";
public static void print() {
class MyInner {
public void printOuter() {
log.info("x is " + x);
}
}
MyInner i = new MyInner();
i.printOuter();
}
public static void main(String[] args) {
StaticMethodInnerClass.print();
}
}
方法中的類,我們是無法在外部實例化的。
4.非靜態(tài)方法的內(nèi)部類
同樣的非靜態(tài)方法也可以定義內(nèi)部類:
@Slf4j
public class MethodInnerClass {
private String x = "non static x";
public void print() {
class MyInner {
public void printOuter() {
log.info("x is " + x);
}
}
MyInner i = new MyInner();
i.printOuter();
}
public static void main(String[] args) {
new MethodInnerClass().print();
}
}
5.匿名類
最后一個,匿名類,直接在需要的時候?qū)嵗念?。匿名類我們遇到了很多次了,比如在?gòu)建SortedSet的時候,可以傳入自定義的Comparator,我們可以用匿名類來實現(xiàn),也可以直接使用lambda表達式。
public class AnonymousClass {
public static void main(String[] args) {
SortedSet sortedSet1 = new ConcurrentSkipListSet(new Comparator(){
@Override
public int compare(Object o1, Object o2) {
return 0;
}
});
SortedSet sortedSet2 = new ConcurrentSkipListSet((o1, o2) -> 0);
}
}
二、內(nèi)部接口
Inner Interface是指在接口中定義的接口。最常見的就是Map中的Entry了:
public interface Map
interface Entry
K getKey();
}
這里的內(nèi)部接口一定是static的,因為接口是不能實例化的,所以為了訪問到接口中的接口,必須定義為static。如果不指定,則默認就是static。
我們看一個該內(nèi)部接口的實現(xiàn):
public class MapImpl implements Map.Entry{
@Override
public Object getKey() {
return 0;
}
@Override
public Object getValue() {
return null;
}
@Override
public Object setValue(Object value) {
return null;
}
}
總的來說,內(nèi)部類和內(nèi)部接口其實可以看成一個變量,這樣代入進去方便我們理解。對于內(nèi)部類和內(nèi)部接口,在本站的Java基礎教程中有更加詳細的講解,歡迎小伙伴們前來觀看學習。