Java 接口和多態

接口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("紅米打電話");
    }
}
相關文章
相關標籤/搜索