內部類 其實並不是什麼地方都能用上,但是我們爲什麼還要學習它呢,下面我們從語法和作用上去慢慢的瞭解他們
語法: 類中定義類
class A{
class B{ /*
可能在剛開始學習類的時候也這樣寫過,當時可能是沒有注意縮進格式
B就是A的內部類 編譯之後會生成兩個class文件 A.class A$B.class 說明內部類只是在編譯期有效
到運行期 A和B是沒有包含關係 是兩個相互獨立的類 所以內部類僅僅是一個編譯期的語法
*/
}
}
分類 ---
成員內部類 和成員屬性定義位置一樣 可以訪問外部類的私有成員,創建成員內部類必須先創建外部類對象,
語法: 外部類對象.new 內部類對象();
成員內部類中不能有靜態成員
如果在內部類定義和外部類同名屬性 在內部類調用的時候用 外部類.this.屬性名 -->外部類.this 指向外部類的當前對象
public class 內部類 {
public static void main(String[] args) {
//我想在主方法中創建一個inner對象調用打印方法
// Outer.Inner in=new Outer.Inner();
// in.print();
/*
a是outer裏邊的私有屬性整個屬性是什麼時候創建的 ?-->是在Outer創建對象的時候纔有的 你現在沒有創建對象呢
a是不存在的能進行打印嗎,
由於成員內部類能訪問外部類的私有屬性,這句話潛意識的就是在說 你的先創建一個外部類對象 然後通過外部類對象
創建內部類對象
*/
Outer o1=new Outer(100);
Outer o2=new Outer(200);
Outer.Inner in = o2.new Inner(); //語法有點奇怪
in.print();
//如果我給內部定義靜態屬性
// 在內部類定義和外部類同名屬性
//調用 System.out.println(Outer.this.a);
}
}
class Outer{
private int a=100;
public Outer(int a){
this.a=a;
}
class Inner{//這個inner就是outer類的成員內部類 它的定義位置是Outer類的成員位置上 可以用private public修飾
//裏邊和正常定義類一樣
int a=20;
public void print(){
/*
那能不能打印a a的作用範圍是整個Outer類 所以是可以打印的 inner在Outer類的封裝範圍內
*/
System.out.println(a);
System.out.println(Outer.this.a);
}
//static int b=10; //內部類不能有靜態成員
}
}
靜態內部類 和靜態成員定義位置一樣 靜態內部類只能訪問外部類的靜態成員 所以不再需要先創建外部類對象
語法: new 外部類.內部類
public class 內部類 {
public static void main(String[] args) {
Outer.Inner inner = new Outer.Inner();
inner.print();
}
}
class Outer{
private int a=10;
private static int b=20;
static class Inner{
public void print(){
System.out.println(a);//靜態內部類只能訪問外部類的靜態成員
System.out.println(b);
}
}
}
局部內部類 使用範圍等同於局部變量 局部內部類不僅可以訪問外部類的私有成員 還可以訪問外部類的局部變量
被內部類訪問的局部變量會被拷貝一份到內部類中,即Inner中存在一個成員變量,用於記錄局部變量a的值。
若局部變量不是final的,其取值就可以被修改,而Inner對象中保存的是其原來的值,這就會出現數據不同步的問題。
Java爲了避免數據不同步的問題,做出了內部類只可以訪問final的局部變量的限制。
在java8中,可以不使用final,如果局部變量被內部類訪問,那麼該局部變量相當於自動使用了final修飾。
public class 內部類 {
public static void main(String[] args) {
Outer out=new Outer();
out.method(10);
}
}
class Outer{
private int a=10;
public void method(int b){
int c=20;
class Inner{//作用範圍就是method方法內部
public void print(){//我想調用這個方法怎麼弄 只能抓緊在method方法內部做 出了這個方法就不能用了
System.out.println("hehe");
System.out.println(a);
System.out.println(b);
System.out.println(c);
}
}
Inner in=new Inner();
in.print();
}
}
匿名內部類:
1)特殊的局部內部類
2)繼承一個類或者是實現一個接口
3)只會創建該類的一個對象
4)只能用默認的構造方法
class School{
public static Teacher getTeacher(int i){
/* class CangTeacher implements Teacher{
public void Teacher(){
System.out.println("Cang teachers");
}
}
class DaTeacher implements Teacher{
public void Teacher(){
System.out.println("Da teachers");
}
}
if(i%2==0)return new CangTeacher();
else return new DaTeacher();*/
if(i%2==0)return new Teacher() {
@Override
public void Teacher() {
System.out.println("蒼老師teacher");
}
} ;
else return new Teacher() {
@Override
public void Teacher() {
System.out.println("大老師講課");
}
};
/*
無論是蒼老師 還是大老師 我都只創建了一次 所以當三個條件滿足之後 我就能把這個局部內部類改造成爲匿名內部類
改造方式
new 接口(){
實現這個接口中的方法
}
其實我要new的不是接口 我需要的是一個對象把接口實現了 {} 這就是一個類的隱含的實現接口, 這個類叫什麼不知道
匿名內部類是把 定義類,實現接口 new對象和在一起了
其實匿名內部了類的語法完全可以用局部內部類代替 匿名代碼少寫一行 丟掉的是程序的可讀性
它的應用很廣泛 很多程序員都在使用,
可以讓人在編程的時候思路不斷
匿名內部類能定義構造方法嗎? 沒名字不能
*/
}
}
interface Teacher{
public void Teacher();
}
內部類是一個編譯期的語法 在運行的時候是兩個獨立的類 那爲什麼還要讓一個類成爲另一個類的內部類
1 內部類可以訪問外部類的私有成員而不破壞封裝
2 接口公開 接口的實現類作爲內部類隱藏起來 強制弱耦合
public class 內部類 {
public static void main(String[] args) {
//學生寫的主方法 我們這樣設計希望 學生這樣寫代碼 它和老師之間是弱耦合的 如果換個老師是對學生之間是沒有影響的
//只要學校去改動getTeacher()代碼
Teacher t = School.getTeacher(0);
t.Teacher();
//但是學生還可以這樣寫
CangTeacher c=new CangTeacher();
c.Teacher();
/*
上邊也是調用蒼老師的方法 下邊也是調用蒼老師的方法 但是如果把代碼寫成下面的樣子我們的一番苦心就白費了
上來繞開接口和學校,直接找了蒼老師 ---->這是可以的,但是我們利用接口實現弱耦合辦不到了,
這事情如果是學生們都要求蒼老師講課程,學校就應該着急了,
所以爲了杜絕學生這樣寫代碼
需要從新改造
把兩個老師 只能在學校的getTeacher()中使用, 所以把這兩個做成局部內部類 只能學校使用,
站在學生角度只能看到 老師接口 還有學校
*/
}
}
/*class CangTeacher implements Teacher{
public void Teacher(){
System.out.println("Cang teachers");
}
}
class DaTeacher implements Teacher{
public void Teacher(){
System.out.println("Da teachers");
}
}*/
class School{ //
public static Teacher getTeacher(int i){
class CangTeacher implements Teacher{
public void Teacher(){
System.out.println("Cang teachers");
}
}
class DaTeacher implements Teacher{
public void Teacher(){
System.out.println("Da teachers");
}
}
if(i%2==0)return new CangTeacher();
else return new DaTeacher();
}
}
interface Teacher{
public void Teacher();
}
內部類的詳細解釋和用法
內部類的詳細解釋和用法
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.