JAVA物件導向的三大特性 多態,java物件導向
多態 指的是對象的多種形態繼承是多態的實現基礎,別忘了子父類要有繼承關係.多態特性:一、引用多態1.父類引用可以指向本類對象 Animal obj1 = new Animal();2.父類引用可以指向子類對象 Animal obj2 = new Dog();但是我們不能用子類的引用指向父類對象Dog obj3 = new Animal();//錯 二、方法多態建立本類對象時,調用的方法為本類方法。建立子類對象時,調用的方法為子類重寫的方法或者繼承的方法。 1.在父類Animal中定義一個eat()方法,輸出一個語句(動物有吃的能力); 在子類Dog中重寫eat()方法,輸出一個語句(狗是吃肉的); 那麼我們在測試類別main函數裡面,如果obj1.eat() ,那麼調用的是父類的方法. 若用obj2調用eat()方法,那麼調用的是子類的方法.2.還有一種情況,比如建立一個繼承父類Animal的子類Cat ,但是Cat裡並不重寫繼承的eat()方法. 然後,我們在測試類別main函數裡建立一個子類對象, Animal obj3 = new Cat(); 然後調用 obj3.eat(); 那麼,結果調用的則是子類繼承父類的方法. (輸出結果:動物有吃的能力)3.最後一種特殊情況,多態的特性是不能使用的. 若在子類添加一個專屬的方法 public void watchDoor() ,含有一句輸出語句(狗具有看門的能力); 那麼我們在測試類別的main函數當中(得先定義好對象Animal obj2 = new Dog() ),就不能用obj2.watchDoor(),即不能通過父類的引用調用子類的方法
1 public class Animal { 2 public void eat(){ 3 System.out.println("動物有吃的能力"); 4 } 5 } 6 7 public class Dog extends Animal { 8 public void eat(){ 9 System.out.println("狗是吃肉的");10 }11 public static void main(String[] args) {12 Animal obj1 = new Animal();13 Animal obj2 = new Dog();14 obj1.eat();15 obj2.eat();16 }17 }
參考型別轉換:1.向上類型轉換(隱式/自動類型轉換),是小類型到大類型的轉換。 如:Dog dog=new Dog();Animal animal=dog;//正確,自動型別提升,向上類型轉換2.向下類型轉換(強制類型轉換),是大類型到小類型的轉換(存在風險,溢出) 如:Dog dog1=(Dog)animal;//向下類型轉換3.instanceof運算子,來解決引用對象的類型,避免類型轉換的安全性問題。如: Dog dog=new Dog(); Animal animal=dog; Cat cat=(Cat)animal;//編譯時間不會出錯(按Cat類型進行編譯),但運行時會報錯,因為它開闢的是Dog類型的空間,而(無法將參考型別進行轉換)無法將dog對象轉換成Cat類型,並且此方法對程式的安全性有影響。此時應該利用instanceof和if語句結合使用,進行驗證,以保證程式的安全性,如:if(animal instanceof Cat){//判斷animal類中是否包含Cat類型的元素,若包含則進行轉換,instanceof傳回值為布爾類型
1 if (dog instanceof cat){2 Dog l1 = (Dog)cat;3 }else{4 System.out.println("無法進行類型轉換!");5 }
抽象類別1 文法定義:類前使用abstract關鍵字修飾,則該類為抽象類別2 應用情境:a.在某些情況下,某個父類只是知道其子類應該包含怎樣的方法, 但無法準確知道這些子類如何?這些方法。抽象類別約束子類必須有這些方法,而並不關注子類如何?。b.從多個具有相同特徵的類中抽象出一個抽象類別,以這個抽象類別作為子類的模板,從而避免了子類設計的隨意性。3 作用:限制規定了子類必須實現某些方法,但不關注實現細節4使用規則:a.abstract定義抽象類別b.abstract定義抽象方法,只有聲明,不需要具體實現。c.包含抽象方法的是抽象類別(如果在類前不適用abstract關鍵字,會出錯)d.抽象類別中可以包含普通的方法,也可以沒有抽象方法。e.抽象類別不能直接建立對象,可以定義引用變數,指向一個子類的對象
介面:1.介面可以理解為一種特殊的類,由全域常量和公用抽象方法組成如果說類是一種具體實現體,而介面定義了某一批類所需要遵守的規範,介面不關心這些類的內部資料,也不關心這些類裡方法的具體實現細節,它只規定這些類裡必須提供某些方法 2.介面的定義:和類定義不同,定義介面不再使用class關鍵字,而是使用interface關鍵字.基本文法:[修飾符] interface 介面名[extends 父介面1,父介面2.......]{零個到多個常量定義...零個到多個抽象方法定義...}介面就是用來繼承,被實現,修飾符一般建議用public注意:不能夠使用private和protected修飾介面 3 介面定義:常量介面中的屬性是常量,即使定義時不添加public static final修飾符,系統也會自動加上方法:介面中的方法只能是抽象方法,即使定義時不添加public abstract字元修飾,系統也會自動加上 4實現:一個類可以實現一個或多個介面,實現介面使用implements關鍵字。java中一個類只能繼承一個父類,是不夠靈活的,通過實現多個介面可以做補充,java中一個類可以實現一個或者多個介面。 繼承父類實現介面的文法:[修飾符] class 類名 extends 父類 implements介面1 ,介面2......{類體部分//如果繼承了抽象類別,需要實現繼承的抽象方法//要實現介面中的抽象方法}如果要繼承父類,繼承父類必須在實現介面之前 5 實現時可以利用介面的引用指向實現了介面的對象,調用其方法,如 :IPlay ip1=new Psp();ip1.playGame();Telphone抽象類別只提供打電話,發簡訊的方法,沒有提供玩遊戲的功能,怎麼在不改變抽象方法的情況下,讓智能手機擁有玩遊戲的功能?這就用到了我們的介面我們想描述Psp呢?Psp只能玩遊戲不能發簡訊和打電話
1 public interface IplayGame { 2 public void playGame(); 3 } 4 5 public abstract class Telphone { 6 public abstract void call(); 7 public abstract void message(); 8 } 9 10 public class SmartPhone extends Telphone implements IplayGame {11 12 @Override13 public void call() {14 // TODO Auto-generated method stub15 System.out.println("智能手機能打電話!");16 }17 18 @Override19 public void message() {20 // TODO Auto-generated method stub21 System.out.println("智能手機能夠發簡訊!");22 }23 24 @Override25 public void playGame() {26 // TODO Auto-generated method stub27 System.out.println("智能手機能夠玩遊戲!");28 }29 }30 31 public class Psp implements IplayGame{32 @Override33 public void playGame() {34 // TODO Auto-generated method stub35 System.out.println("psp能夠玩遊戲!");36 }37 }38 39 public class Cellphone extends Telphone {40 41 @Override42 public void call() {43 // TODO Auto-generated method stub44 System.out.println("普通手機能夠打電話!");45 }46 47 @Override48 public void message() {49 // TODO Auto-generated method stub50 System.out.println("普通手機能夠發簡訊!");51 }52 }53 54 public class Ceshi {55 public static void main(String[] args) {56 IplayGame smp = new SmartPhone();57 smp.playGame();58 Telphone t1 = new SmartPhone();59 t1.call();60 t1.message();61 IplayGame ip = new Psp();62 ip.playGame();63 }64 }View Code 6介面在使用過程中,還經常與匿名內部類配合使用匿名內部類就是沒有名字的內部類,多用於關注實現而不關注實作類別的名字
public class Nmnbl { IplayGame ip1 = new IplayGame() { public void playGame() { System.out.println("我是匿名內部類實現介面!"); }; }; public static void main(String[] args) { new IplayGame() { @Override public void playGame() { // TODO Auto-generated method stub System.out.println("使用第二中匿名內部類實現介面!"); } }.playGame(); }}View Code我們在命名一個介面時,在首字母加I來區分普通類和介面