java基礎14 多態(及關鍵字:instanceof)

面向對象的三大特徵:  

1.封裝   (將一類屬性封裝起來,並提供set()和get()方法給其餘對象設置和獲取值。或者是將一個運算方法封裝起來,其餘對象須要此種作運算時,給此對象調用)
html

2.繼承   (繼承關係經過extends關鍵字體現)
java

3.多態   (父類的引用指向子類的對象,或者接口的引用類型變量指向接口實現類的對象)函數


一、多態的含義

    父類的引用指向子類的對象,或者接口的引用類型變量指向接口實現類的對象大數據

二、多態的應用

    1.多態應用於形式參數的時候,能夠接收更多類型的數據.
    2.多態用於返回值時,能夠返回更多類型的數據.this

三、多態的好處

    提升了代碼的拓展性.spa

四、多態的弊端

    雖然提升了擴展性,可是隻能使用父類引用指向父類成員。code

五、多態的前提

    類與類之間有關係,繼承或者實現htm

六、多態體現

    1:父類引用變量指向了子類的對象
    2:父類引用也能夠接受本身的子類對象對象

七、類型轉換場景的問題

java.lang.ClassCaseException.類型轉換失敗   blog

八、附錄

若是須要訪問子類特有的成員,那麼須要進行強制類型轉換 一、基本數據類型轉換:   小數據類型------>大數據類型 自動轉換   大數據類型------>轉小數據類型 強制類型轉換 二、引用類型轉換:   小數據類型------->大數據類型 自動轉換   大數據類型------->轉小數據類型 強制類型轉換

九、實現關係下的多態

接口的引用類型變量指向接口實現類的對象
格式: 接口 變量
= new 接口實現類的對象

例子:

 1 interface Dao {  //接口的方法所有都是非靜態的方法
 2     public void add();  3     public void delete();  4 }  5 
 6 //接口的實現類
 7 class UserDao implements Dao{  8     public void add(){  9         System.out.println("添加員工!!!"); 10  } 11     public void delete(){ 12         System.out.println("刪除員工"); 13  } 14 } 15 
16 class Demo2 { 17     public static void main(String[] args) { 18         //實現關係下的多態
19         Dao d=new UserDao(); //接口的引用類型變量指向接口的實現類的對象
20  d.add(); 21  d.delete(); 22  } 23 }

十、實例

例子1:

/* 1:Father類 1:非靜態成員變量x 2:靜態成員變量y 3:非靜態方法eat,方法體輸出父類信息 4:靜態方法speak();方法體輸出父類信息 2:Son類 1:非靜態成員變量x 2:靜態成員變量y 3:非靜態方法eat,方法體輸出子類信息 4:靜態方法speak();方法體輸出子類信息 */
class Father { int x = 1; static int y = 2; void eat() { System.out.println("開吃"); } static void speak() { System.out.println("小頭爸爸"); } } class Son extends Father { int x = 3; static int y = 4; void eat() { System.out.println("大頭兒子很能吃"); } static void speak() { System.out.println("大頭兒子。"); } } class Demo10 { public static void main(String[] args) { Father f = new Son(); // 父類引用指向了子類對象。
        System.out.println(f.x); //返回結果:1
        System.out.println(f.y); //返回結果:2
 f.eat(); // 輸出的是子類的方法
        f.speak(); // 輸出的是父類的方法
 } }

解析:子類(Son)繼承父類(Father

1:建立Father f=new Son();
1:這就是父類引用指向了子類對象。
2:問f.x=?(非靜態)
3:問f.y=?(靜態)
4:問f.eat()輸出的是子類仍是父類信息?(非靜態)
5:問f.speak()輸出的是子類仍是父類信息?(靜態)

總結:

1:當父類和子類具備相同的非靜態成員變量,那麼在多態下訪問的是父類的成員變量
2:當父類和子類具備相同的靜態成員變量,那麼在多態下訪問的是父類的靜態成員變量     因此:父類和子類有相同的成員變量,多態下訪問的都是父類的成員變量。
3:當父類和子類具備相同的非靜態方法(就是子類重寫父類方法),多態下訪問的是子類的成員方法。
4:當父類和子類具備相同的靜態方法(就是子類重寫父類靜態方法),多態下訪問的是父類的靜態方法。

例子2:

 1 //動物類
 2 abstract class Animal{  3  String name;  4     public Animal(String name){  5         this.name=name;  6  }  7 
 8     public abstract void run(); //抽象方法  9 } 10 //老鼠類
11 class Mouse extends Animal{ 12     public Mouse(String name){ //調用父類構造器,目的:獲取成員變量name中的值 13         super(name); 14  } 15     public void run(){ //重寫父類的抽象方法 16         System.out.println(name+"四條腿慢慢走"); 17  } 18 
19     public void dig(){//Mouse子類特有的方法 20         System.out.println(name+"老打洞..."); 21 
22  } 23 } 24 //魚類
25 class Fish extends Animal{ 26     public Fish(String name){ 27         super(name); 28  } 29     public void run(){ //重寫父類的抽象方法 30         System.out.println(name+"搖着尾巴游啊遊..."); 31  } 32     public void bubble(){ //Fish子類特有的方法 33         System.out.println(name+"吹泡泡...."); 34  } 35 } 36 
37 class Demo6 { 38     public static void main(String[] args) { 39         Animal a=new Mouse("米老鼠");//多態,父類的引用指向子類的對象
40  a.run(); 41         //a.dig(); //報錯 42         
43         Mouse m=(Mouse)a;//強制類型轉換 
44         m.dig(); //若是直接用a.dig()的話,會報錯,由於是多態(父類中沒有dig()方法),因此要強制轉換類型
45 
46         Animal a1=new Fish("金槍魚"); 47         Fish f=(Fish)a1; 48  print(f); 49  } 50 
51     //需求,定義一個函數能夠接收任意類型的動物對象,在函數的內部要調用到動物特有的方法 52     //instanceof
53     public static void print(Animal a){//Animal a=new Fish();
54         if(a instanceof Fish){ 55              Fish f=(Fish)a; 56  f.bubble(); 57         }else if(a instanceof Mouse){ 58             Mouse m=(Mouse)a; 59  m.dig(); 60         }else{ 61             System.out.println("輸入錯誤"); 62  } 63  } 64 }

例子3:instanceof關鍵字(在末尾)

 1 //形狀類
 2 abstract class MyShape{//抽象類  3     public abstract void getLength(); //抽象方法  4     public abstract void getArea(); //抽象方法  5 }  6 //圓形
 7 class Circle extends MyShape{  8     public final static double PI=3.14; //常量  9     double r; 10     public Circle(double r){ 11         this.r=r; 12  } 13 
14     public void getLength(){ 15         System.out.println("這是圓形的周長"+2*PI*r); 16  } 17     public void getArea(){ 18         System.out.println("這是圓形的面積"+PI*r*r); 19     
20  } 21 } 22 //矩形
23 class Rect extends MyShape{ 24     int width; 25     int height; 26 
27     public Rect(int width,int height){ 28         this.width=width; 29         this.height=height; 30  } 31     public void getLength(){ 32         System.out.println("這是矩形的周長"+2*(width+height)); 33  } 34     public void getArea(){ 35         System.out.println("這是矩形的面積"+width*height); 36  } 37     public void t(){ 38         System.out.println("來咬我啊!!!"); 39  } 40 } 41 
42 class Demo5 { 43     public static void main(String[] args) {    
44 MyShape mp=new Circle(3.0);//多態,父類的引用指向了子類的對象 45 mp.getLength(); 46 mp.getArea();
47     //方法2
48     Circle c = new Circle(3.0);
49 Rect r = new Rect(5,8); 50 MyShape m = new Rect(8,3); 51 //m.t(); //報錯,此處須要強制類型轉換 52 print(r); 53 print(c);//new Circle(3.0) 54 } 55 56 //需求1.定義一個函數能夠接收任意類型的對象,而且打印圖形的面積與周長 57 public static void print(MyShape s){//至關於:MyShape s=new Circle(3.0) 58 s.getLength(); 59 s.getArea(); 60 MyShape m = getShape(1); 61 } 62 63 //需求2:定義一個函數能夠返回任意類型的圖形對象. 64 public static MyShape getShape(int i){ 65 66 if(i == 1){ 67 return new Circle(2.0); 68 }else if(i == 0){ 69 return new Rect(6,9); 70 }else{ 71 return null; 72 } 73 } 74 }

 

 

 

 

 

原創做者:DSHORE

做者主頁:http://www.cnblogs.com/dshore123/

原文出自:http://www.cnblogs.com/dshore123/p/8891998.html

歡迎轉載,轉載務必說明出處。(若是本文對您有幫助,能夠點擊一下右下角的 推薦,或評論,謝謝!

相關文章
相關標籤/搜索