1 單一職責原則 : 功能職責單一,只擁抱一種變化
2 裡氏替換原則 : 所有在使用父類別的情況下,都可以使用子類替換
3 依賴倒置 : 通過高層的抽象依賴底層,細節依賴抽象
4 介面隔離原則
5 迪米特原則
6 開閉原則 : 對擴充套件開放,對修改關閉
有繼承關係
1 區域性變數/成員變數 : 宣告的時候 使用父類別宣告,賦值的時候,使用子類物件
2 實參/形參 : 參數列表使用父類別宣告變數,方法呼叫時傳入子類物件
3 返回值 : 返回值型別使用父類別宣告,return的時候 返回子類物件
**多型發生在賦值的時候**
Animal a ; // 宣告一個變數,不是多型
a = new Animal(); 父類別參照指向父類別物件,不是多型
a= new Cat(); : 父類別參照指向子類物件,多型
丟失子類特有的屬性
參照 : 參照型別變數
指向 : 就是通過這個參照型別的變數儲存的記憶體地址,可以找到誰
子類物件 : 就是使用子類建立的物件
使用父類別型別宣告一個變數,這個變數儲存子類物件的記憶體地址,
哪裏 有變數,哪裏就能發生多型
父類別 變數名 = new 子類()
1 如果父類別沒有,不管子類有沒有,不管什麼屬性,都存取不了,報錯
2 如果父類別有的成員方法,子類也有的成員方法,執行子類,因爲覆寫
3 如果父類別有的成員方法,子類沒有,執行父類別
4 如果父類別有的非成員方法,不管子類有沒有,都執行父類別
public class Poly_01 {
public static void main(String[] args) {
Sup sup = null;
sup.m1();
System.out.println(sup.i);
// System.out.println(sup.a);
}
}
class Sup{
int i = 10;
public void m1() {
System.out.println("父類別成員方法");
}
}
class Sub extends Sup{
int i = 20;
int a = 1;
public void m1() {
System.out.println("子類成員方法");
}
}
參數使用父類別宣告,可以接收所有子類物件
後續想要進行功能擴充套件的時候,不需要改動原始碼
public class Poly_02 {
public static void main(String[] args) {
Cat c = new Cat();
Dog d = new Dog();
eat(c);
eat(d);
Animal a = new Cat();
}
public static void eat(Animal animal) {
//判斷animal是否由cat範例化而來
if(animal instanceof Cat) {
//向下轉型
Cat c1 = (Cat) animal;
//TODO 可以存取特有屬性了
}else if(animal instanceof Dog){
Dog d1 = (Dog)animal;
}
animal.eat();
}
}
class Animal{
public void eat() {
System.out.println("動物吃東西");
}
}
class Cat extends Animal{
public static final int age = 1;
public void eat() {
System.out.println("貓吃魚");
}
}
class Dog extends Animal{
public static final int age = 1;
public void eat() {
System.out.println("狗吃肉");
}
}
自動型別轉換:
1 基本型別 : 低精度到高精度
2 參照型別 : 子類到父類別
instanceof 運算子 : 判斷某個物件是否由某個類範例化而來,可以避免強制型別轉換異常
public class Poly_03 {
public static void main(String[] args) {
Animal animal = new Cat();
//多型丟失子類特有屬性
//System.out.println(animal.age);
//需要先向下轉型
Cat c = (Cat) animal;
System.out.println(c.age);
//如果把Cat轉換爲Dog型別 會報錯
Dog d = (Dog)animal;
//判斷之後名可以避免型別轉換異常
if (animal instanceof Cat) {
Cat c1 = (Cat) animal;
System.out.println(c1.age);
}else if ( animal instanceof Dog) {
Dog d1 = (Dog) animal;
System.out.println(d1.age);
}
}
}
通過子類,呼叫父類別的方法的時候,父類別的這個方法中的上下文環境 就會發生多型(屬於父類別空間,子類物件)
public class Poly_04 {
public static void main(String[] args) {
SubClass sub = new SubClass();
System.out.println(sub);
// System.out.println(sub.i);
sub.m1();
}
}
class SupClass{
int i = 10;
int asdasdacxz12 = 2;
public void m1() {
/**
* this:儲存當前類物件的記憶體地址,並且是一個成員物件,那麼this的數據型別是什麼?
*
* 當前類:this在那個類體中,那個就是就是當前類
*
* 當this的數據型別是什麼的時候,可以儲存當前類物件的記憶體地址?
* 1 當前類型別
* 2 父類別型別
*
* 如果是父類別型別,會發生多型,丟失子類特有的屬性,經過測試,可以使用this呼叫當前類中
* 特有的屬性,所以this的型別一定是當前類型別
*
* SupClss this;
*
* 誰呼叫的這個方法,this就指向誰
*
* 這個m1方法是誰呼叫的?
* 如果是當前類物件呼叫的,this就指向當前類物件
* 但是如果是子類物件呼叫,this就指向子類物件
* 結合起來 就成了
* SupClass this = new SubClass(); 發生多型
*
*/
// System.out.println(this.asdjhaskhdask123123bdkas);
System.out.println(this);
System.out.println(this.i);
//呼叫不了
// System.out.println(this.b);
m2();
}
public void m2() {
System.out.println("父類別m2執行");
}
}
class SubClass extends SupClass{
int i = 33;
int b = 2;
public void m2() {}
}