上一次在
使用Java開始面向對象的編程
這篇文章中
我們學習了一個編程語言要真正成為面向對象的
它應該支持信息隱藏/封裝
多態
繼承和動態綁定
另外
我們知道了Java完全支持這些功能
而且知道了因為Java是一種解釋性的語言並運行在虛擬機的內部
所以由Java寫成的任何程序都可以在任何支持 Java虛擬機(JVM)的操作系統上運行
我們還明白了對象是代表現實生活中事物的軟件
編程模型以及對象是由它們的狀態和行為定義的
最後
我們知道了Java中除了原始數據對象以外一切都是對象
因為這種程序設計風格中的這許多內容都和對象以及類有關
我們將在下面進一步的考察它們
對象詳論 使用對象的一個關鍵是當你在浏覽系統分析文檔或者設計文檔的時候如何來確定它們
因為對象一般代表人
地方或者事物
所以一個確定對象的基本的方法就是找出句子中所使用的名詞
這裡有一個簡單的例子
在句子
一個顧客可以擁有多於一個的銀行帳號
我們就確定了兩個對象
客戶和帳號
在句子
小貓喵喵叫
中
我們能夠確定一個對象
貓
類詳論 前面
我們學習了一個類是定義了對象如何動作以及當對象創建或者說實例化的時候應該包含些什麼的實體
在對動物的討論中
我們可以說
狗兒汪汪叫
貓喵喵叫
鴨子嘎嘎叫
確定句子中的對象我們就得到了狗
貓和鴨子
至於汪汪叫
喵喵叫
嘎嘎叫
那都是我們對象發出的行為動作
要實現這些對象
我們需要創建三個對象分別叫Dog
Cat和Duck
要實現它們的行為
我們可以為每一個這些對象創建代表每個對象發出的聲音的方法
而且我們把這個方法叫做speak或者
如果我們發揮想象力的話還可以把這個方法叫做sayHello
在程序的上下文中為了演示這些概念
讓我們修改上篇文章中的HelloWorld程序
添加這三個新對象並給它們中的每一個添加sayHello方法
如下所示:
public class HelloWorld
{
public static void main(String[] args)
{
Dog animal
= new Dog();
Cat animal
= new Cat();
Duck animal
= new Duck();
animal
sayHello();
animal
sayHello();
animal
sayHello();
}
}
class Dog
{
public void sayHello()
{
System
out
println(
Bark
);
}
}
class Cat
{
public void sayHello()
{
System
out
println(
Meow
);
}
}
class Duck
{
public void sayHello()
{
System
out
println(
Quack
);
}
}
在編譯並運行了這個程序以後
輸出應該如下:
Bark
Meow
Quack
看看我們的程序
我們馬上就注意到了一些事情:每個對象代表了一種動物
而每個對象實現了一個相同的方法
sayHello
假設我們想要給對象更多的功能以及用來代表對象所指的動物的方法和屬性
比方說
我們可以添加一個方法來確定一個動物是不是哺乳類的
或者我們添加一個方法來確定一個動物是不是肉食性的
我們可以通過給每一個對象添加這兩種方法來實現或者我們也能夠使用OOP的兩個最強大的功能:繼承和多態
因為所有的對象都代表一個對象
所以我們將創建一個被稱為
基類
或是
超類
的類
它的名字是Animal
我們然後可以讓我們的對象從Animal類繼承相同的特點並強制每個對象只實現與Animal類不同的功能
Java用extends關鍵字指明一個類從另一個繼承
讓我們利用繼承和多態的概念獲得代碼重用的好處來重建我們的程序並使得每個對象只實現與基類Animal不同的功能:
public class HelloWorld
{
public static void main(String[] args)
{
Dog animal
= new Dog();
Cat animal
= new Cat();
Duck animal
= new Duck();
System
out
println(
A dog says
+animal
getHello()
+
is carnivorous:
+animal
isCarnivorous()
+
is a mammal:
+animal
isAMammal());
System
out
println(
A cat says
+animal
getHello()
+
is carnivorous:
+animal
isCarnivorous()
+
is a mammal:
+animal
isAMammal());
System
out
println(
A duck says
+animal
getHello()
+
is carnivorous:
+animal
isCarnivorous()
+
is a mammal:
+animal
isAMammal());
}
}
abstract class Animal
{
public boolean isAMammal()
{
return(true);
}
public boolean isCarnivorous()
{
return(true);
}
abstract public String getHello();
}
class Dog extends Animal
{
public String getHello()
{
return(
Bark
);
}
}
class Cat extends Animal
{
public String getHello()
{
return(
Meow
);
}
}
class Duck extends Animal
{
public boolean isAMammal()
{
return(false);
}
public boolean isCarnivorous()
{
return(false);
}
public String getHello()
{
return(
Quack
);
}
}
在編譯並運行我們的程序以後
輸出應該如下:
A dog says Bark
is carnivorous: true
is a mammal: true
A cat says Meow
is carnivorous: true
is a mammal: true
A duck says Quack
is carnivorous: false
is a mammal: false
看看我們的例子
你將發現我們定義了一個叫做Animal的新類
它定義了三個方法:isAMammal
isCarnivorous
和 getHello
你一概還注意到了
我們在每個現存的類申明的前面都添加了extends Animal這個語句
這個語句告訴編譯器這些對象是Animal類的子類
因為方法isAMammal 和 isCarnivorous 都返回 true
所以Dog和Cat類用不著重新實現
即
重載
這兩個方法
但是鴨子既不是哺乳動物又不是肉食性的
所以Duck類需要重載這兩種方法來返回正確的值
我們所有的對象都以自己獨特的方式說
hello
所以它們都需要重載getHello方法
因為每種動物說
hello
的方式都不同
所以我們在基類中將getHello方法申明為抽象的
而且我們沒有給這個方法一個函數體
這就迫使Animal的每一個子類重載getHello方法並根據每一個特定動物的需要來定義它
因為我們將getHello方法申明為虛擬的
我們就不能直接實例化Animal對象
因此
我們需要將Animal類也申明為抽象的
我們通過在Animal類定義的開始行添加abstract關鍵字來實現這一點
子類重載它們基類的方法的能力就是多態
多態使得子類能夠使用基類的方法或是在這些方法不足的時候重載它們
這就實現了代碼重用
加快了代碼的實現過程
而且它還隔離和程序中的bug
使得程序的維護更容易
總結 在本文中
我們學習了如何確定潛在的對象
我們還學習了如何使用繼承和多態來加快我們的代碼實現過程並隔離錯誤
這使得代碼的維護過程更加容易
下一次
我們將展開討論多態和繼承的概念並開始我們對動態綁定的討論
From:http://tw.wingwit.com/Article/program/Java/hx/201311/26732.html