動態編譯類型 - 同一方法能夠根據發送對象的不一樣而採用多種不一樣的行爲方式。java
一個對象的實際類型是肯定的,但能夠指向對象的引用的類型有不少。ide
注意:多態是方法的多態,屬性沒有多態性oop
instanceof測試
一個對象的實際類型是肯定的code
new Student();對象
new Person();繼承
可是,能夠指向的引用類型就不肯定了編譯器
子類重寫了父類的方法,就執行子類的方法io
沒法被重寫的方法(修飾符):編譯
static 靜態方法 - 方法,屬於類,而不屬於實例
final 常量
private 私有方法也不能被重寫
被這三個修飾符修飾的方法沒法被重寫,因此也沒法實現多態
若是沒有「重寫Override」,不能重複方法/方法名
package oop.Demo06; public class Person { public void run(){ System.out.println("run"); } }
package oop.Demo06; public class Student extends Person { //重寫在父類Person的run方法,今後父類子類都執行此處的方法 @Override public void run() { System.out.println("son"); } //父類Person沒有這個方法-eat,所以在測試裏,父類Person沒法調用此方法 public void eat(){ System.out.println("eat"); } }
package oop; import oop.Demo05.A; import oop.Demo05.B; import oop.Demo06.Person; import oop.Demo06.Student; public class Application { public static void main(String[] args) { //一個對象的實際類型是肯定的 //new Student(); //new Person(); new Person/Student後就是new Person/Student //可是,能夠指向的引用類型就不肯定了: 父親的引用指向子類 // 也就是 y與x, 多個x能夠獲得相同的y值 //子類"Student"能執行的方法都是本身的或是繼承父類的! Student s1 = new Student(); // 子類指向的引用 //父類Person能夠指向子類"Student",可是不能夠調用子類獨有的方法 Person s2 = new Student(); // 父類指向的引用 Object s3 = new Student(); //由於Person是student的父類,Object是默認的父類因此,能夠newStudent以這三種形式 //對象能執行那些方法,主要看對象左邊的類型(父類、子類),和右邊關係不大 s2.run(); // 父類Person //s2.eat(); 沒法調用 s1.run(); //Student 類 s1.eat();//子類能夠調用本身的方法eat //輸出結果爲 //son //son //都變成了son,經歷過Override, 子類重寫了父類的方法,就執行子類的方法 } }
instanceof (類型轉換)
經過instanceof能夠判斷一個對象是什麼類型
經過instanceof能夠判斷兩個類之間是否存在父子關係
總結爲公式:
System.out.println(x instanceof y); 編譯器可否經過取決於x與y是否有父子類關係
怎麼使用instanceof判斷類與類之間的關係:
package oop; import oop.Demo05.A; import oop.Demo05.B; import oop.Demo06.Person; import oop.Demo06.Student; import oop.Demo06.Teacher; public class Application { public static void main(String[] args) { //Object > Person > Student//Teacher //Object > Person > Teacher //Object > String Object object = new Student(); //Object是Person的父類,Person是"Student"的父類 //使用new在object和 Student 創建了這種關係,那麼使用instanceof驗證一下 System.out.println(object instanceof Student); // True System.out.println(object instanceof Person); // True System.out.println(object instanceof Object); // True System.out.println(object instanceof Teacher); // False System.out.println(object instanceof String); // False System.out.println("========================"); Person person = new Student(); System.out.println(person instanceof Student); // True System.out.println(person instanceof Person); // True System.out.println(person instanceof Object); // True System.out.println(person instanceof Teacher); // False //System.out.println(person instanceof String); // False Person和String是平行關係,同級關係 !!編譯器報錯!! System.out.println("========================"); Student student = new Student(); System.out.println(student instanceof Student); // True System.out.println(student instanceof Person); // True System.out.println(student instanceof Object); // True //System.out.println(student instanceof Teacher); // False Student和Teacher是同級關係 !!編譯器報錯!! //System.out.println(student instanceof String); // False String和Student沒有關係 !!編譯器報錯!! // 總結爲公式: //System.out.println(x instanceof y); 編譯器可否經過取決於x與y是否有父子類關係 } }
類型之間的轉換
低轉高是慢慢長大,高轉低是返老還童,會失憶
//高 低 Person student = new Student(); //子類Student這個對象被new成父類Person, 低轉高 OK //student.go(); //可是此時,student沒法使用"Student"de方法go //student[父類Person]將這個對象轉換爲Student[子類Student],我麼就可使用"Student"類型的方法了 Student student1 = (Student) student; //高轉低, Person student -- Student student1 強制轉換 ((Student) student).go(); //通過強制轉換就可使用 更低一層-子類 的方法了 //子類轉換爲父類,可能會丟失一些本身的方法 /* 栗子: Object example = new Student(); //低轉高 Student example2 = (Student) example; // ((Student) example).go(); */