物件導向學習三 (介面、多型)

2020-08-14 19:09:35

介面

介面是一種約定規範,是多個抽象方法的集合,僅僅只是定義了有哪些功能,本身不實現功能。
作用:
爲了制定規範,體現了規範和事項相分離的思想,也體現了元件之間低耦合的特點。
耦合:各個部分之間的距離
內聚:各個部分內部的凝聚度

注意:

  • 介面可以被認爲是一種特殊的類,定義類的時候使用class關鍵字,定義介面的時候使用的是interface關鍵字。介面名一般以I開頭
    語法:
public interface 介面名{
	//抽象方法1
	//抽象方法2
	//抽象方法3
	.....
}
  • 介面中的方法都是公共的抽象方法從Java8開始, Java支援在介面中定義有實現的方法
public interface Iwalkable{
	void walk();
}
//等價於
public interface Iwalkable{
	public abstract void walk();
}
public interface IWalkable {
	public abstract void walk();//抽象方法
    
    default void defaultMethod(){
        System.out.println("有預設實現的方法, 屬於物件");
    }
    static void defaultMethod(){
        System.out.println("有預設實現的方法, 屬於類");
    }
}
  • 類可以繼承,但是不能多繼承。介面可以繼承,而且可以繼承多個介面,也就是說一個介面可以同時繼承多個介面
public interface IAmphibiable  extends IWalkable,ISwimable{
}

介面實現類

和抽象物件一樣,介面也是不能建立物件的,必須要定義一個類去實現介面,並覆蓋這個方法,這個類稱爲實現類,類和介面之間的關係稱爲實現關係(implements)

public class 類名 implements 介面名{
	//覆蓋介面中的方法
}

根據方法覆蓋原則:子類方法的存取修飾符必須大於等於父類別方法的存取修飾符,介面中的方法都是public修飾的,所以實現類中的方法只能使用public修飾。

如果是建立實現類物件,此時要面對介面程式設計:

介面名 變數名 = new 實現類();

如果既有繼承又要實現介面,應該把繼承寫在前面。

public class 類名 extends 父類別 implements 介面名...{

}

多型

public class Animal{}
public class Dog extends Animal{}
public class Cat extends Animal{}
public static void main(String[] args){
        Dog dog = new Dog();
        dog.eat();

        //多型的體現
        //Animal:編譯型別
        //Dog:執行型別
        Animal d = new Dog();
        //編譯時期看Animal中是否有呼叫的方法
        //如果有,編譯通過

        //在執行時期,先找Dog中是否存在方法,有就執行,如果沒有就去父類別中找方法
        d.eat();
    }

當編譯型別和執行型別不一致的時候,多型就產生了。
注意:編譯型別必須是執行型別的父類別或者介面

所謂多型,就是一個物件可以有多種形態:

Animal	a = null;
a   =  new    Dog();	//	a此時表示Dog型別的形態
a   =  new    Cat();	//	a此時表示Cat型別的形態
操作繼承關係

父類別參照變數指向於子類物件,呼叫方法時實際呼叫的是子類的方法

介面 變數名 = new 實現類();
變數名.方法();

public class Animal{}
public class Dog extends Animal{}
public class Cat extends Animal{}
public class AnimalDemo {
	public static void main(String[] args) {
		// 建立Cat物件
		Animal a = new Cat();
		a.shout();
		// 建立Dog物件
		a = new Dog();
		a.shout();
	}
}
操作實現關係

介面 變數名 = new 實現類();
變數名.方法();

多型時方法呼叫的問題

在这里插入图片描述
可以看出,此時通過多型的方法不能存取到父類別不存在但是子類存在的方法,那麼就引出了下面 下麪的問題

型別轉換和instanceof運算子

  • 自動型別轉換:把子類物件賦給父類別變數
  • 強制型別轉換:把父類別型別物件賦給子類型別變數(ClassCastException型別轉換異常:當把一個物件轉換一個型別不匹配的物件時)
public class Dog extends Animal{
    public void eat(){
        System.out.println("吃屎");
    }
    public void sleep(){
        System.out.println("睡覺");
    }
}

        Animal a = new Dog();
        a.eat();
        //在這裏我們需要存取子類中特有的方法
        //需要將Animal型別的變數a轉換成Cat型別的變數
        Dog d1 =(Dog) a;
        d1.sleep();

instanseof:

 Cat c = (Cat)a;
        //執行報錯:ClassCastException 型別轉換異常。
        //當把一個物件轉換成一個型別不匹配的物件的時候就會報錯

        //instanceof判斷物件是否時某一個類的範例
        //語法:物件A   instanceof  類B;
        // 判斷 A物件是否是 B類的範例?如果是,返回true
        System.out.println(a instanceof Dog); //true
        System.out.println(a instanceof Animal);//true
        System.out.println(a instanceof Object); //true
        System.out.println(a instanceof Cat); //false

        if(a instanceof Cat){
            Cat c = (Cat)a;
        }

多型的好處

把實現類物件賦給介面型別變數,遮蔽了不同實現類之間的實現差異,從而做到通用程式設計

小結

  • 介面和抽象類的區別:
    1.介面可以多實現,抽象類可以不能多繼承
    2.介面裏邊的方法都是抽象方法,抽象類中即可以有抽象方法也可以有普通方法
  • 介面和抽象類的相同點
    都可以實現約束規範
  • 介面和介面實現類定義的語法
    介面: public interface 介面名{}
    一般來說,介面名以I開頭
    介面實現類:public class 類名 (extends 父類別名) implements 介面名 (,介面名){}
  • 實現類在實現一個介面的時候需要注意的地方