0801-0807 多態 接口

多態:面向對象的第三種表現形式。
定義:可以理解爲事物存在的多種體現形態。

總結:一個規律兩個體現。

舉例:人,分爲男人和女人。動物,貓,狗,老虎。

貓 x = new 貓();

動物 x = new 貓();

以上是多態在對象上的體現。

多態還可以在函數中體現,當虛函數被重載、覆蓋時,既可以理解爲是多態。

重點講對象的多態。

0.多態的體現
1.多態的前提
2.多態到底有什麼好處
3.多態如何應用
------------------------------------------------------------------------------------------------------------------
需求:
對貓狗進行分 別描述。

抽取:
abstract class Animal 
{
public abstract void eat();
}

class Cat extends Animal
{
public void eat()
{
System.out.println("eat fish");
}

public void catchMouse()
{
System.out.println("catch");
}
}

class Dog extends Animal
{
public void eat()
{
System.out.println("eat bones");
}
public void watchHome()
{
System.out.println("watch Home");
}
}

class DuoTaiDemo
{
public static void main(String[] args)
{
Cat c = new Cat();
c.eat();

Cat c1 = new Cat();
c1.eat();
Dog d = new Dog();
d.eat();
function(new Cat());
}

public static void function(Animal c)
{
c.eat();
}//提高代碼複用性
}

class Pig extends Animal
{
public void eat()
{
System.out.println("siliao");
}
public void gongDi()
{
System.out.println("gong di");
}
}

1.多態的體現
父類的引用指向了自己的子類對象。父類的引用也可以接收自己的子類對象。
2. 多態的前提:
必須是雷雨類之間有關係,要麼繼承,要麼實現。
通常還有一個前提:就是存在覆蓋。(共同的成員方法,在某些函數裏面實現,才實現了後期拓展性。)
3.多態的好處
多態有利於增強代碼的拓展性。
4.多態的弊端:(侷限性)
提高了拓展性,但是隻能使用父類提供的共同的方法和變量。
------------------------------------------------------------------------------------------------------------------

class DuoTaiDemo
{
public static void main(String[] args)
{
Animal a = new Cat();//類型提升。回想當年,byte提升到int 的時候。。。(向上轉型,轉成父類 //型)

Animal a = new Cat();
a.eat();

Cat c = (Cat)a;//強制類型轉換
c.catchMouth
}
}

既然能向上轉型,就也有向下轉型。
如果想調用貓的特有方法,如何操作?
強制將父類的引用轉成子類類型。

Animal a = new Cat();
a.eat();

Cat c = (Cat)a;//強制類型轉換
c.catchMouth();

小心。慎用向下轉型(丟失精度的轉型),這樣可能不會得到預期的效果。如將一直貓轉化爲一隻動物。

不要將父類對象轉換成子類類型。可以將父類的引用轉換成子類類型。
當父類的引用指向了自己子類的對象時,改因用可以被提升,也可以被轉換。
Animal a = new Cat();//這就是父類引用指向子類對象。

Animal a = new Animal();這樣的時候,就不能被提升也不能被轉化。

多態自始至終都是子類對象再作變化。子類可以向上變化也可以向下變化。

舉例:老師的例子。
畢老師和畢姥爺。

畢老師的父親也會講課(工商管理)
畢老師講課(java)

有人來找畢姥爺講課,畢姥爺不在家,畢老師在家。畢老師遍化裝成畢姥爺的父親,這是轉型(提升)。

有人來拜訪,看到轉型之後的畢老師,會看到畢姥爺(提升後的畢老師)。


代碼:
畢姥爺 x = new 畢老師();
x.講課();

畢老師的講課方法(java)複寫了畢姥爺的講課方法(工商管理)。

講完課回家。畢老師的朋友來找畢老師看電影。

一進屋,看見了畢老爺。

x.看電影();//肯定不行,因爲畢老師換裝成了畢姥爺,沒有看電影的方法。

所以需要轉換。

畢老師 y = (畢老師)x;
//向下轉型
自始至終都是畢老師(子類對象)在變化。

public static void function(Animal a)
{
a.eat();

Cat c = (Cat)a;
c.catchMouse();
}

如果傳一個狗到a的位置,會編譯成功,在運行的時候出現類型轉換錯誤的提示。
public static void function(Animal a)
{
a.eat();
if (a instanceof Cat)
{
Cat c = (Cat)a;
c.catchMouse();
}

else if (a instanceof Dog)
{
Dog c = (Dog)a;
c.kanjia();
}
}

------------------------------------------------------------------------------------------------------------------
6.多態的出現代碼中的特點(使用的注意事項)

需求:預熱班 和 就業班的學員 都有學習 和 睡覺 的功能


class Student
{
abstract void study();
public void sleep()
{
System.out.println("lying sleep");
}
}

class baseStudent extends Student
{
public void study()
{
System.out.println(" base study");
}


public void sleep()
{
System.out.println("level2 sleep");
}
}

class advStudent extends Student{
public void study(){
System.out.println("study advanced");
}
}
class DuoTaiDemo3
{
public static void main(String[] args)
{
BaseStudent bs = new BaseStudent();
bs.study();
bs.sleep();

DoStudent ds = new DoStudent();
ds.doSome(new BaseStudent());//使用單獨封裝的類對學生進行操作
//也可以傳advstu
}


}

class DoStudent
{//單獨封裝
public void doSome(Student stu)
{
stu.study();
stu.sleep();//已經提升了複用性
}
}

多態將對象調用變得簡單了,使得原先需要挨個調用的對象變爲批量操作。 
-記得將工具類抽取出來-
------------------------------------------------------------------------------------------------------------------
多態中成員的特點

class Fu
{
void method1()
{
System.out.println("fu method1");
}
void method2()
{
System.out.println("fu method2");
}
}

class Zi extends Fu{
void method1(){
System.out.println("zi method1");
}
void method3(){
System.out.println("zi method3");
}
}

錯誤示例:Fu  f = new Zi();
在多態中成員函數的特點:
在編譯時期,參閱引用型變量所屬的類中是否有調用的方法。如果有,編譯通過,如果沒有則編譯失敗。
在運行時,殘月對象所屬的類中是否有調用的方法。
簡單總結就是:成員變量在多態調用時,編譯看左邊,運行看右邊。

以上是  非 靜 態 成員函數的特點(有重寫特點)
面試題1
FU 中num = 5 
zi中num = 8

Fu f = new Zi(); 5
Zi z = new Zi(); 8

爲什麼父類引用指向子類對象,還是5?

在多態中,成員變量的特點:無論編譯還是運行,都參考左邊(引用變量所屬的類)
面試題2

Fu中有Method4
Zi中有static method4 內容不一樣

Fu f = new Zi();
f.method4();

運行結果:fu method4
在多態中,靜態成員函數的特點,無論編譯和運行,都參考左邊。

從內存上解釋,static會首先加載,單獨存在於一片區域當中,並非動態創建,不屬於某一個確切的對象。



總結:


非靜態成員函數在多態時的特點:(父類引用指向子類對象)
編譯的時候,左邊是最小需求。如果左邊有的右邊都有,那麼就可以通過。
運行的時候,右邊是最小需求。如果右邊調用的左邊沒有,則運行出錯。

非靜態成員變量在多態時的特點:
無論編譯還是運行,都參考左邊(引用變量所屬的類)

靜態成員函數在多態時的特點:
無論是編譯還是運行都參考左邊。
------------------------------------------------------------------------------------------------------------------
需求:
電腦運行實例
電腦運行基於主板。


class MainBoard
{
public void run()
{
System.out.println("main board run");
}
}

class DuoTaiDemo5
{
publi static void main(String[] args)
{
MainBoard mb = new MainBoard();
mb.run();
}
}

以上的程序拓展性差。想上網上不了,想聽音樂聽不了。

class MainBoard
{
public void run()
{
System.out.println("main board run");
}
public void useNetCard(NetCard c)
{
c.open();
}
}

class NetCard
{
public void open()
{
System.out.println("net open");
}
public void close()
{
System.out.println("net closed");
}
}

class DuoTaiDemo5
{
publi static void main(String[] args)
{
MainBoard mb = new MainBoard();
mb.useNetCard(new NetCard());
}
}
更新之後的設計思想:

0801-0807 <wbr>多態 <wbr>接口

interface PCI
{
public void open();
public void close();
}

class MainBoard
{
public void run()
{
System.out.println("mainBoard run");
}

public void usePCI(PCI P)
{
if( p != null)
{
p.open();
p.close();
}
}
}

class DuoTaiDemo5
{
public static void main(String[] args)
{
MainBoard mb = new MainBoard();
mb.run();
mb.usePCI(null);
mb.usePCI(new NetCard());
}
}

class NetCard implements PCI
{
public void open()
{
System.out.println("net open");
}
public void close()
{
System.out.println("net closed");
}
}

PCI p = new NetCard()//接口類型引用指向自己的子類。
------------------------------------------------------------------------------------------------------------------
多態的拓展示例

需求:數據庫的操作。
數據:用戶信息
1.連接數據庫 JDBC Hibernate(框架連接)
2.操作數據庫
C R U D create read update delete
3、關閉數據庫連接

interface UserInfoDao
{
public void add(User user);
public void delete(User user);
}
class UserInfoByJDBC implements UserInfoDao{
public  void add(User user)
{
1.連接數據庫
2.使用 sql進行操作
3.關閉連接
}
public  void delete(User user)
{
1.連接數據庫
2.使用 sql進行操作
3.關閉連接
}
public  void update(User user)
{
1.連接數據庫
2.使用 sql進行操作
3.關閉連接
} public  void delete(User user)
{
1.連接數據庫
2.使用 sql進行操作
3.關閉連接
}
}

class
{
public static void main(String[] args)
{
UserInfoByJDBC ui = new UserInfoByJDBC();
{
ui.add(user);
ui.delete(user);
}
}
}

class DBOperate
{
public static void main(String[] args)
{
}
}

//接口可以對於程序內部屏蔽外界的改變,方便開發,降低了程序之間的耦合性。
0801-0807 <wbr>多態 <wbr>接口


左邊隨時改,右邊不用變、。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章