單態:這個對象只有惟一的一種狀態java
Student s = new Student();數組
多態:這個對象存在多種狀態。 是指同一行爲,具備多個不一樣表現形式。ide
1)要有繼承或者實現的關係測試
2)方法的重寫(若是沒有方法重寫,格式不會報錯,這樣的多態是沒有任何意義)ui
3)父類的引用指向子類對象(父new子)或者父接口的引用指向實現類對象(父接口new實現類)this
父類類型 變量名 = new 子類對象(); 變量名.方法名(); eg: Animal dog = new Dog(); dog.eat();
對象被什麼數據類型所修飾,這個變量就會調用誰的實例變量code
//父類:SuperClass public class SuperClass { int num = 10; }
//子類:SubClass public class SubClass extends SuperClass { int num = 20; }
//測試類:PolyDemo02 public class PolyDemo02 { public static void main(String[] args) { //父new父 SuperClass superC = new SuperClass(); System.out.println(superC.num);//10 //子new子 SubClass subC = new SubClass(); System.out.println(subC.num);//20 System.out.println("==================="); //利用多態建立對象 SuperClass sc = new SubClass(); System.out.println(sc);//com.atguigu.poly.demo02.SubClass@15db9742 子類地址值 System.out.println(sc.num);//10 } }
先看父類中是否有這個方法,若是有,執行子類重寫後的方法;若是沒有,編譯報錯對象
//父類:SuperClass public class SuperClass { public void method () { System.out.println("父類的實例方法"); } }
//子類:SubClass public class SubClass extends SuperClass { public void method () { System.out.println("子類重寫後的實例方法"); } }
//測試類:PolyDemo04 public class PolyDemo04 { public static void main(String[] args) { //父new父 SuperClass superC = new SuperClass(); System.out.println(superC); //com.atguigu.poly.demo04.SuperClass@15db9742 superC.method();//父類的實例方法 System.out.println("=============="); //子new子 SubClass subC = new SubClass(); System.out.println(subC);//com.atguigu.poly.demo04.SubClass@6d06d69c subC.method();//父類的實例方法 System.out.println("=============="); //父new子 SuperClass sc = new SubClass(); System.out.println(sc);//com.atguigu.poly.demo04.SubClass@7852e922 sc.method();//父類的實例方法 } }
和原來同樣繼承
//父類:SuperClass public class SuperClass { public SuperClass () { System.out.println("父類的構造器"); } }
//子類:SubClass public class SubClass extends SuperClass { public SubClass(){ //super(); 此處隱藏了JVM提供的super() System.out.println("子類的構造器"); } }
//測試類PolyDemo03 public class PolyDemo03 { public static void main(String[] args) { //父new父 SuperClass superC = new SuperClass();//父類的構造器 System.out.println("================"); //子new子 SubClass subC = new SubClass();//父類的構造器 子類的構造器 System.out.println("================"); // 父new子 SuperClass sc = new SubClass();//父類的構造器 子類的構造器 System.out.println(sc); //com.atguigu.poly.demo03.SubClass@15db9742 } }
//Student類 public class Student { private String name; private int age; public String getName() { return name; } public void setName(String name) { this.name = name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } //設置滿參構造器 public Student(String name, int age) { super(); this.name = name; this.age = age; } //重寫系統中自帶的toString方法 @Override public String toString() { return "Student [name=" + name + ", age=" + age + "]"; } }
//測試類:PolyDemo05 public class PolyDemo05 { public static void main(String[] args) { Student s1 = new Student("張三",18); Student s2 = new Student("李四",23); Student s3 = new Student("錢五",43); Student s4 = new Student("孫六",23); //對象數組 Student[] arr = {s1,s2,s3,s4}; printArr(arr); } //object爲頂級父類,將其放置形參 private static void printArr(Object[] arr) { for (int i = 0; i < arr.length; i++) { Object obj = arr[i]; System.out.println(obj); } } }
//運行結果 Student [name=張三, age=18] Student [name=李四, age=23] Student [name=錢五, age=43] Student [name=孫六, age=23]
在多態的狀況下,對象沒法調用本身的特有方法,只能調用子類改寫父類的方法。接口
解決多態的弊端,引用數據類型的類型轉換
類型轉換名稱 | 類型轉換方向 |
---|---|
向上轉型(默認轉換方式) | 將子類的對象或者實現類的對象轉換爲父類的類型或者父接口類型(多態) |
向下轉型(強制類型轉換) | 將父類類型或者父接口類型轉換爲子類類型或者實現類類型 |
子類類型 對象名 = (子類類型)父類類型的對象; eg: Animal cat = new Cat(); //多態 Dog dog = (Dog)cat; //強轉
引用數據類型強制類型轉換時注意事項:
可能會發生ClassCastException:類型轉換異常
強制轉換時易發生類型轉換異常,使用instanceof給引用變量作類型的校驗
變量名 instanceof 數據類型 eg: c instanceof Cat
instanceof返回值
instanceof爲關係運算符,若是變量屬於該數據類型,返回true;若是變量不屬於該數據類型,返回false。
1.定義動物類 屬性:年齡,顏色 行爲:eat(String something)方法(無具體行爲,不一樣動物吃的方式和東西不同, something表示吃的東西)生成空參有參構造,set和get方法 2.定義狗類繼承動物類 行爲:eat(String something)方法,看家lookHome方法(無參數) 3.定義貓類繼承動物類 行爲:eat(String something)方法,逮老鼠catchMouse方法(無參數) 4.定義Person類 屬性:姓名,年齡 行爲:keepPet(Dog dog,String something)方法 功能:餵養寵物狗,something表示餵養的東西 行爲:keepPet(Cat cat,String something)方法 功能:餵養寵物貓,something表示餵養的東西 實現以上兩種行爲,思考如何只寫一個方法? 生成空參有參構造,set和get方法 5.測試以上方法 使用多態、強轉、instanceof等
//Animal類 public abstract class Animal { private int age; private String color; //設置set()、get()方法 public int getAge() { return age; } public void setAge(int age) { this.age = age; } public String getColor() { return color; } public void setColor(String color) { this.color = color; } //設置無參構造器和滿參構造器 public Animal(int age, String color) { super(); this.age = age; this.color = color; } public Animal() { super(); } //設置動物類的抽象方法 public abstract void eat(String something); }
//Cat類 繼承 Animal類 public class Cat extends Animal{ //重寫父類eat方法 public void eat(String something) { System.out.println(getAge() + "歲" + getColor() + "色的小貓正在吃" + something); } //逮老鼠方法 public void catchMouse () { System.out.println(getAge() + "歲" + getColor() + "色的小貓正在逮老鼠"); } //設置構造器 public Cat() { super(); } public Cat(int age, String color) { super(age, color); } }
//Dog類 繼承 Animal類 public class Dog extends Animal{ //重寫父類抽象方法 @Override public void eat(String something) { System.out.println(getAge() + "歲" + getColor() + "色的小狗正在吃" + something); } public void lookHome(){ System.out.println(getAge() + "歲" + getColor() + "色的小狗正在看家"); } //設置構造器 public Dog() { super(); } public Dog(int age, String color) { super(age, color); } }
//Person類 public class Person { //餵養狗和餵養貓的方法爲方法的重載,能夠直接使用多態的好處一:聲明方法時,再也不將形參寫具體的引用數據類型,直接寫父類的類型或者父類接口的類型 /*// 餵養狗的方法 public void keepPet(Dog dog,String something) { dog.eat(something); } // 餵養貓的方法 public void keepPet(Cat cat,String something) { cat.eat(something); }*/ public void keepPet (Animal a,String something) { a.eat(something); } }
//測試類: public class PolyDemo06 { public static void main(String[] args) { //建立貓對象 Animal cat = new Cat(2,"白"); //建立狗的對象 Animal dog = new Dog(3,"黑"); //建立人對象 Person p = new Person(); // 調用飼養員的餵養貓的方法 p.keepPet(cat, "魚"); // 將多態形式的對象進行向下轉型 if (cat instanceof Cat) { Cat c = (Cat)cat; c.catchMouse(); } //cat對象不屬於Dog,判斷返回false if (cat instanceof Dog) { Dog d = (Dog)cat; d.lookHome(); } //Cat c = (Cat)dog; //c.catchMouse(); System.out.println("=================="); // 調用飼養員餵養狗的方法 p.keepPet(dog, "骨頭"); } }