接口是一組行為的規范、定義。接口是面向對象編程體系中的思想精髓之一,使用接口可以讓我們的程序更加利於變化。
接口的格式:
interface 接口名稱{
全局變量;
抽象方法;
}
接口中的成員修飾符是固定的,成員常量用public static final修飾;成員函數用public abstract修飾,接口的出現將“多繼承”通過多實現來體現。接口的使用也有一定的規則:接口可以繼承多個接口,一個類中可以實現接口和多接口,抽象類實現接口可以不實現方法;接口中的所有實現方法的訪問權限都是public;接口中定義的屬性都是常量。java中用interface關鍵字來修飾接口。當一個抽象類中的方法都是抽象的時候,就可以將該類用另一種方式表現出來,就是接口。
interface Demo{ public static final x=9; public abstract void show(); }
注意:類與類之間是繼承關系,類與接口是實現關系。接口不可以實例化:只能由實現了接口的子類並覆蓋接口中的所有方法後,該子類才可以實例化,否則,該子類是一個抽象類。
interface Animal{ String name; String age; public void eat(); public void speak(); } class Cat{ public void eat(){ System.out.println("我愛吃魚!"); } public void speak(){ System.out.println("喵喵~~~·"); } }
接口的四大特點:1、接口是對外暴露的規則;2、接口是編程的功能擴展;3、接口的出現降低了耦合性;4、接口可以用來多實現。
抽象類與接口的異同點:
相同點:都是不斷向上抽取而來的。
不同點:抽象類需要被繼承,而且只能單繼承,接口需要被實現,可以多實現 ;抽象類中可以定義抽象方法和非抽象方法,而接口中只能定義抽象方法,必須由子類去實現;抽象類的繼承,是is a關系,定義體系基本共性內容,而接口的實現是like a 關系,定義體系額外功能。
什麼叫接口回調?
可以把實現某一接口的類創建的對象的引用賦給該接口聲明的接口變量中,那麼該接口變量就可以調用被類實現的接口中的方法。
多態性:多態是面向對象的三大特性之一,多肽主要體現在兩個方面:一是方法的重載與重寫。二是對象的多態性。多態就是某一類事物的多種存在形態。
例如:動物,貓,狗
1、貓這個對象對應的類型是貓類型。
貓 X = new 貓 ();
2、 貓也是動物的一種,也可以把貓稱為動物。
動物 Y = new 貓 ();
父類型的引用指向了子類對象。一個對象,兩種形態;貓這類事物即具備著貓的形態,又具備著動物的形態。這就是對象的多態性。簡單來說就是一個對象對應著不同類型。那麼使用多態有什麼利弊呢?使用多態不僅提高了代碼的擴展性,前期定義的代碼可以使用後期的內容。當然,使用多態在前期定義的內容不能使用(調用)後期子類特有的內容。
當然,使用多態也有著前提:代碼中必須有關系,即繼承或者實現;二是要有覆蓋(只發生在函數上,成員變量沒有)。
對象的多態性:對象的多態性是從繼承關系中的多個類而來。
向上轉型:將子類實例轉化為父類實例
格式:父類 父類對象 = 子類實例 ; ------>自動轉化
如:int i='a'; 因為char的容量比int小,所以可以自動完成。
向下轉型:將父類實例轉化為子類實例;
格式:子類 子類對象=(子類)父類實例; -------->強制轉換
如:char c=(char)97; 因為整形4個字節比char2個字節大,所以要強制轉換。
//例如 Animal a=new Cat(); //自動提升,特有功能無法訪問 Cat c= (Cat) a; //向下轉型的目的是為了使用子類中的特有功能。
多態的特點:
1)、成員變量:
編譯時,參考引用型變量所屬的類中是否有調用的成員變量,有通過,沒有則失敗;運行時,參考引用型變量所屬的類中是否有調用的成員變量,並運行所屬類中的的成員變量。
簡單來說:編譯和運行都參考等號的左邊。
2)、成員函數:
編譯時,參考引用型變量所屬的類中是否有調用的成員變量,有通過,沒有則失敗;運行時,參考的是對象所屬的類中是否有調用的函數。
簡單來說:編譯看左邊,運行看右邊。
3)、靜態函數:
編譯時,參考引用型變量所屬的類中是否用調用的靜態函數。運行時,參考引用型變量所屬的類中是否用調用的靜態函數。
簡單來說:編譯和運行都看左邊。其實對於靜態方法不需要對象的,直接類名調用即可。
在多態中,還有個關鍵字需要注意:instanceof關鍵字。
語法格式:對象 instanceof 類型------返回的是Boolean類型值
該語句一般用於判斷一個對象是否為某一個類的實例,是返回true,否則返回false。
使用instanceof關鍵字的父類的設計法則:
通過instanceof關鍵字,我們可以檢查對象的類型,但是如果一個父類中的子類過多,判斷繁瑣,那麼如何設優計父類呢?
1)、父類通常設計為抽象類或者接口,其中優先考慮接口,接口不能滿足才考慮抽象類。
2)、一個集體的類盡可能不去繼承另一個具體的類,這樣的好處是無需檢查對象是否為父類的對象。
public static void method(Animal a){ a.eat(); if(a instance Cat){ //instance用於判斷對象的具體類型 //通常在向下轉型用於健壯性的判斷。 Cat c=(Cat) a; c.catchMouch(); } }
內部類:將一個類定義在另一個類的裡面,裡面的那個類就稱為內部類(內置類,嵌套類)。內部類訪問的特點:內部類可以直接訪問外部類中的成員,包括私有成員;而外部類要訪問內部類的成員,必須要建立內部類的對象。可以在外部創建內部類對象:內部類除了可以在外部類中產生實例化對象,也可以在外部類的外部來實例化。
方法內部類:內部類可以作為一個類的成員外,還可以把類放在方法內定義。
成員內部類的格式:
class Quter{ public void print(){ //在外部類實例化內部類對象,並調用方法 Inner inner = new Inner(“成員內部類”); inner。print(); } class Inner{} }
注意:
1)、方法內部類只能在定義該內部類的方法內實例化,不可以在此方法外對其實例化。
2)、方法內部類對象不能使用該內部類的所在的方法的非final局部變量。內部類只能訪問局部中被final修飾的局部變量。
靜態內部類:
靜態的含義是該內部類可以像其他靜態成員一樣,沒有外部類對象的時候,,也能夠訪問它,靜態嵌套類僅能訪問外部類的的靜態成員和方法。
class Quter{ static class Inner{ } } class Test{ public static void main(String[] args){ Quter.Inner n=new Quter.Inner(); } }
內部類訪問的特點:
1、內部類可以直接訪問外部類的成員。那是因為內部類持有了外部類的引用。
2、外部類要訪問內部類,要建立內部類對象
在分析事物時,發現該事務在描述上還有事物,而且該事物還在訪問被描述事物的內容,這是還有的事物就定義為內部類。
class Quter{ private String name; public void show(){} public static void method(){} class Inner{ int age; public void add(int a,int b){} } static class Nner{ public void shou(){} static void function(){} } } class Test{ public static void main(String[] args){ //直接訪問外部類中的成員 Quter out=new Quter(); out.show(); System.out.println(out.name); //直接訪問外部類中的內部類的中的成員 Quter.Inner in=new Quter().new Inner(); in.show(); //如果內部類是靜態的,相當於一個外部類 Quter.Nner inn=new Quter.Nner(); inn.shou(); //如果內部類是靜態的,成員也是靜態的 Quter.Nner.function(); } }
匿名內部類:
匿名內部類就是沒有名字的內部類,一般分為三種情況:1)繼承式的匿名內部類。2)接口式的匿名內部類 。3)參數式的匿名內部類
//繼承式的匿名內部類
new Thread() {
public void run() {
for (int i = 1; i <= 5; i++) {
System.out.print(i + " ");
}
}
}.start();
//接口式的匿名內部類 public void print2(){ Child c=new Child(){ public void desc(){ System.out.println("接口式匿名內部類"); } } } //參數式的匿名內部類 outer.print3(new Child(){ public void desc(){ System.out.println(“參數式的匿名內部類”); } });
匿名內部類是內部類的簡寫格式,所有一些規則:即是內部類必須繼承或者實現一個外部類或者接口。
使用個匿名內部類的規則:內部類中不能有構造函數,只有一個實例;不能定義任何靜態成員,靜態方法;修飾詞不能式public,protected,private,static;內部類一定是在new後面,用其隱含實現一個接口或者實現一個類;匿名內部類都是局部的,所以局部內部類的所有權限都生效。
匿名內部類的作用:每個內部類都能獨立的繼承自一個接口的實現,所以無論外部類是否已經繼承了某個(接口的)實現,對於內部類都沒有影響。內部類提供可以繼承多個具體的或抽象的類的能力,內部類使能多重繼承的方案變得完整。接口解決了部分問題,內部類有效的解決了多重繼承的問題。
匿名內部類的使用場景之一:當函數參數是接口類型時,而且接口中的方法不超過三個,可以用匿名內部類作為實際參數進行傳遞。
public void method(){ Inner in=new Inner(){ public void show1(){} public void show2(){} } in.show1(); in.show2(); }