接口java
1.1 接口的概述ide
接口是功能的集合,一樣可看作是一種數據類型,是比抽象類更爲抽象的」類」。模塊化
接口只描述所應該具有的方法,並無具體實現,具體的實現由接口的實現類(至關於接口的子類)來完成。這樣將功能的定義與實現分離,優化了程序設計。學習
1.2 接口的格式&使用優化
1.2.1 接口的格式this
與定義類的class不一樣,接口定義時須要使用interface關鍵字。spa
定義接口所在的仍爲.java文件,雖然聲明時使用的爲interface關鍵字的編譯後仍然會產生.class文件。這點可讓咱們將接口看作是一種只包含了功能聲明的特殊類。設計
定義格式:code
public interface 接口名 { 抽象方法1; 抽象方法2; 抽象方法3; }
1.2.2 接口的使用模塊化開發
接口中的方法全是抽象方法,直接new接口來調用方法沒有意義,Java也不容許這樣幹
類與接口的關係爲實現關係,即類實現接口。實現的動做相似繼承,只是關鍵字不一樣,實現使用implements
其餘類(實現類)實現接口後,就至關於聲明:」我應該具有這個接口中的功能」。實現類仍然須要重寫方法以實現具體的功能。
格式:
class 類 implements 接口 { 重寫接口中方法 }
在類實現接口後,該類就會將接口中的抽象方法繼承過來,此時該類須要重寫該抽象方法,完成具體的邏輯。
1.2.3 案例代碼一
package com.gao_01; /* * Java語言的繼承是單一繼承,一個子類只能有一個父類(一個兒子只能有一個親爹) * Java語言給咱們提供了一種機制,用於處理繼承單一的侷限性的,接口 * * 接口:接口是一個比抽象類還抽象的類,接口裏全部的方法全是抽象方法,接口和類的關係是實現,implements * interface * * 格式: * interface 接口名 { * * } * */ public class InterfaceDemo { public static void main(String[] args) { BillGates gates = new BillGates(); gates.code(); } } class Boss { public void manage() { System.out.println("管理公司"); } } class Programmer { public void code() { System.out.println("敲代碼"); } } //比爾蓋茨 class BillGates extends Programmer { }
1.3 接口中成員的特色
一、接口中能夠定義變量,可是變量必須有固定的修飾符修飾,public static final 因此接口中的變量也稱之爲常量,其值不能改變。後面咱們會講解fnal關鍵字
二、接口中能夠定義方法,方法也有固定的修飾符,public abstract
三、接口不能夠建立對象。
四、子類必須覆蓋掉接口中全部的抽象方法後,子類才能夠實例化。不然子類是一個抽象類。
1.3.1 案例代碼二
package com.gao_01; /* * 接口的成員特色: * 只能有抽象方法 * 只能有常量 * 默認使用public&abstract修飾方法 * 只能使用public&abstract修飾方法 * 默認使用public static final來修飾成員變量 * * 建議:建議你們手動的給上默認修飾符 * * 注意: * 接口不能建立對象(不能實例化) * 類與接口的關係是實現關係,一個類實現一個接口必須實現它全部的方法 */ public class InterfaceDemo2 { public static void main(String[] args) { //Animal a = new Animal(); //Animal.num; } } interface Animal { public static final int num = 10; public abstract void eat(); } class Cat implements Animal { public void eat() { } }
1.4 接口和類的關係
A:類與類之間:繼承關係,一個類只能直接繼承一個父類,可是支持多重繼承
B:類與接口之間:只有實現關係,一個類能夠實現多個接口
C:接口與接口之間:只有繼承關係,一個接口能夠繼承多個接口
1.4.1 案例代碼三
package com.gao_01; /* * * 類與類:繼承關係,單一繼承,多層繼承 * 類與接口:實現關係,多實現 * 接口與接口的關係:繼承關係,多繼承 */ public class InterfaceDemo3 { public static void main(String[] args) { } } interface InterA extends InterB { public abstract void method(); } interface InterB { public abstract void function(); } interface InterC extends InterA { } class Demo implements InterC { @Override public void method() { // TODO Auto-generated method stub } @Override public void function() { // TODO Auto-generated method stub } }
1.5 接口的思想
前面學習了接口的代碼體現,如今來學習接口的思想,接下里從生活中的例子進行說明。
舉例:咱們都知道電腦上留有不少個插口,而這些插口能夠插入相應的設備,這些設備爲何能插在上面呢?主要緣由是這些設備在生產的時候符合了這個插口的使用規則,不然將沒法插入接口中,更沒法使用。發現這個插口的出現讓咱們使用更多的設備。
接口的出現方便後期使用和維護,一方是在使用接口(如電腦),一方在實現接口(插在插口上的設備)。例如:筆記本使用這個規則(接口),電腦外圍設備實現這個規則(接口)。
集合體系中大量使用接口
Collection接口
List接口
ArrayList實現類
LinkedList實現類
Set接口
1.6 接口優勢
1.類與接口的關係,實現關係,並且是多實現,一個類能夠實現多個接口,類與類之間是繼承關係,java中的繼承是單一繼承,一個類只能有一個父類,打破了繼承的侷限性。
2.對外提供規則(USB接口)
3.下降了程序的耦合性(能夠實現模塊化開發,定義好規則,每一個人實現本身的模塊,提升了開發的效率)
1.7 接口和抽象類的區別
1.共性:
不斷的進行抽取,抽取出抽象的,沒有具體實現的方法,都不能實例化(不能建立對象)
2.區別1: 與類的關係
(1)類與接口是實現關係,並且是多實現,一個類能夠實現多個接口,類與抽象類是繼承關係,Java中的繼承是單一繼承,多層繼承,一個類只能繼承一個父類,可是能夠有爺爺類
(2)區別2: 成員
a.成員變量
抽象類能夠有成員變量,也能夠有常量
接口只能有常量,默認修飾符public static final
b.成員方法
抽象類能夠有抽象方法,也能夠有非抽象方法
接口只能有抽象方法,默認修飾符 public abstract
c.構造方法
抽象類有構造方法,爲子類提供
接口沒有構造方法
1.8 運動員案例
1.8.1 案例代碼四
package com.gao_02; /* * 籃球運動員和教練 乒乓球運動員和教練 如今籃球運動員和教練要出國訪問,須要學習英語 請根據你所學的知識,分析出來哪些是類,哪些是抽象類,哪些是接口 */ public class InterfaceTest { public static void main(String[] args) { //建立籃球運動員對象 BasketBallPlayer bbp = new BasketBallPlayer(); bbp.name = "女兆月日"; bbp.age = 35; bbp.gender = "男"; bbp.sleep(); bbp.study(); bbp.speak(); System.out.println("-------------"); //建立乒乓球教練對象 PingpangCoach ppc = new PingpangCoach(); ppc.name = "劉胖子"; ppc.age = 40; ppc.gender = "男"; ppc.sleep(); ppc.teach(); //ppc.speak(); } } class Person { String name;//姓名 int age;//年齡 String gender;//性別 //無參構造 public Person() {} //有參構造 public Person(String name,int age,String gender) { this.name = name; this.age = age; this.gender = gender; } //吃 public void eat() { System.out.println("吃飯"); } //睡 public void sleep() { System.out.println("睡覺"); } } //學習說英語 interface SpeakEnglish { public abstract void speak(); } //運動員 abstract class Player extends Person { //學習 public abstract void study(); } //教練 abstract class Coach extends Person { //教 public abstract void teach(); } //籃球運動員 class BasketBallPlayer extends Player implements SpeakEnglish{ @Override public void study() { System.out.println("學扣籃"); } @Override public void speak() { System.out.println("說英語"); } } //乒乓球運動員 class PingpangPlayer extends Player { @Override public void study() { System.out.println("學抽球"); } } //籃球教練 class BasketBallCoach extends Coach implements SpeakEnglish { @Override public void teach() { System.out.println("教扣籃"); } @Override public void speak() { System.out.println("說英語"); } } //乒乓球教練 class PingpangCoach extends Coach { @Override public void teach() { System.out.println("教抽球"); } }
多態
2.1 多態概述
多態是繼封裝、繼承以後,面向對象的第三大特性。
現實事物常常會體現出多種形態,如學生,學生是人的一種,則一個具體的同窗張三既是學生也是人,即出現兩種形態。
Java做爲面向對象的語言,一樣能夠描述一個事物的多種形態。如Student類繼承了Person類,一個Student的對象便既是Student,又是Person。
2.2 多態的定義與使用格式
多態的定義格式:及時就是父類的引用變量指向子類對象
父類類型 變量名 = new 子類類型(); 變量名.方法名();
A:普通類多態定義的格式
父類 變量名 = new 子類(); 如: class Fu {} class Zi extends Fu {} //類的多態使用 Fu f = new Zi();
B:抽象類多態定義的格式
抽象類 變量名 = new 抽象類子類(); 如: abstract class Fu { public abstract void method(); } class Zi extends Fu { public void method(){ System.out.println(「重寫父類抽象方法」); } } //類的多態使用 Fu fu= new Zi();
C:接口多態定義的格式
接口 變量名 = new 接口實現類(); 如: interface Fu { public abstract void method(); } class Zi implements Fu { public void method(){ System.out.println(「重寫接口抽象方法」); } } //接口的多態使用 Fu fu = new Zi();
2.2.1 案例代碼
package com.gao_01; /* * 多態的前提: * 子父類的繼承關係 * 方法的重寫 * 父類引用指向子類對象 * * 動態綁定:運行期間調用的方法,是根據其具體的類型 * * * * */ public class PoymorphicDemo { public static void main(String[] args) { /*Cat c = new Cat(); c.eat();*/ //父類引用 Animal a //指向 = //子類對象 new Cat() Animal a = new Cat(); a.eat(); } } class Animal { public void eat() { System.out.println("吃東西"); } } class Cat extends Animal { public void eat() { System.out.println("貓吃魚"); } }
2.3 多態成員的特色
A:多態成員變量
當子父類中出現同名的成員變量時,多態調用該變量時:
編譯時期:參考的是引用型變量所屬的類中是否有被調用的成員變量。沒有,編譯失敗。
運行時期:也是調用引用型變量所屬的類中的成員變量。
簡單記:編譯和運行都參考等號的左邊。編譯運行看左邊。
B:多態成員方法
編譯時期:參考引用變量所屬的類,若是沒有類中沒有調用的方法,編譯失敗。
運行時期:參考引用變量所指的對象所屬的類,並運行對象所屬類中的成員方法。
簡而言之:編譯看左邊,運行看右邊
2.3.1 案例代碼六
package com.gao_01; /* * * 多態的成員特色: * 成員變量 編譯時看的是左邊,運行時看的左邊 * 成員方法 編譯時看的是左邊,運行時看右邊 * 靜態方法 編譯時看的是左邊,運行時看的也是左邊 * * * 編譯時看的都是左邊,運行時成員方法看的是右邊,其餘(成員變量和靜態的方法)看的都是左邊 * */ public class PoymorphicDemo2 { public static void main(String[] args) { Dad d = new Kid(); //System.out.println(d.num); //d.method(); d.function();//使用變量去調用靜態方法,其實至關於用變量類型的類名去調用 } } class Dad { int num = 20; public void method() { System.out.println("我是父類方法"); } public static void function() { System.out.println("我是父類靜態方法"); } } class Kid extends Dad { int num = 10; public void method() { System.out.println("我是子類方法"); } public static void function() { System.out.println("我是子類靜態方法"); } }
2.4 多態中向上轉型與向下轉型
多態的轉型分爲向上轉型與向下轉型兩種:
A:向上轉型:當有子類對象賦值給一個父類引用時,即是向上轉型,多態自己就是向上轉型的過程。
使用格式:
父類類型 變量名 = new 子類類型();
如:Person p = new Student();
B:向下轉型:一個已經向上轉型的子類對象可使用強制類型轉換的格式,將父類引用轉爲子類引用,這個過程是向下轉型。若是是直接建立父類對象,是沒法向下轉型的
使用格式:
子類類型 變量名 = (子類類型) 父類類型的變量;
如:Student stu = (Student) p; //變量p 實際上指向Student對象
package com.gao_01; /* * * 多態中的向上轉型和向下轉型: * * 引用類型之間的轉換 * 向上轉型 * 由小到大(子類型轉換成父類型) * 向下轉型 * 由大到小 * 基本數據類型的轉換 * 自動類型轉換 * 由小到大 * byte short char --- int --- long --- float --- double * 強制類型轉換 * 由大到小 * * * */ public class PoymorphicDemo3 { public static void main(String[] args) { Animal2 a = new Dog();//向上轉型 //a.eat(); Dog d = (Dog)a;//向下轉型 d.swim(); } } class Animal2 { public void eat() { System.out.println("吃東西"); } } class Dog extends Animal2 { public void eat() { System.out.println("啃骨頭"); } public void swim() { System.out.println("狗刨"); } }
2.5 多態的優缺點
package com.gao_01; /* * * 多態的優缺點 * 優勢:能夠提升可維護性(多態前提所保證的),提升代碼的可擴展性 缺點:沒法直接訪問子類特有的成員 */ public class PoymorphicDemo4 { public static void main(String[] args) { MiFactory factory = new MiFactory(); factory.createPhone(new MiNote()); factory.createPhone(new RedMi()); } } class MiFactory { /*public void createPhone(MiNote mi) { mi.call(); } public void createPhone(RedMi mi) { mi.call(); }*/ public void createPhone(Phone p) { p.call(); } } interface Phone { public void call(); } //小米Note class MiNote implements Phone{ public void call() { System.out.println("小米Note打電話"); } } //紅米 class RedMi implements Phone { public void call() { System.out.println("紅米打電話"); } }