物件導向程式大綱
物件導向程式大綱
前言
物件導向程式設計中的每一個物件都應該能夠接受資料、處理資料並將資料傳達給其它物件,因此它們都可以被看作一個小型的「機器」,即物件。目前已經被證實的是,物件導向程式 設計推廣了程式的靈活性和可維護性,並且在大型專案設計中廣為應用。
含有物件導向的程式語言
Common Lisp、Python、C++、Objective-C、Smalltalk、Delphi、Java、Swift、C#、Perl、Ruby 與 PHP等。
歷史
物件導向的雛型,早在1960 Simmula 語言即可發現,當時程式設計面臨一種危機,在軟硬體環境複雜的情況下,軟體如何得到良好的維護,物件導向設計通過可重複性解決了這一個問題。
- 1963年代 Simula 據說是為了模擬船隻而設計這種語言,並對不同船隻屬性的相互影響感興趣,他們家不同的船隻歸納為不同的類別,而每一個物件,可以它的屬性和行為。
- 1980年代 C++ C語言的擴充版, GUI(圖形化使用者介面)日漸崛起的情況下,物件導向設計很好地適應潮流。
- Mac OS X是由Objective-C語言寫成的,這一語言是一個仿Smalltalk的C語言擴充版。物件導向程式設計的思想也使事件處理式的程式設計更加廣泛被應用(雖然這一概念並非僅存在於物件導向程式設計)。一種說法是,GUI的引入極大地推動了物件導向程式設計的發展。
- 過去的幾年中,Java語言成為了廣為應用的語言,除了它與C和C++語法上的近似性。Java的可移植性是它的成功中不可磨滅的一步,因為這一特性,已吸引了龐大的程式設計師群的投入。
物件和類別 (Class && Object)
類別(class) : 定義一件事物的抽象特點,類別包含 資料的形式 和 資料的操作。
物件(Object): class 的實例
類別 狗
開始
公有成員:
吠叫():
私有成員:
毛皮顏色:
孕育:
結束
定義萊絲是狗
萊絲.毛皮顏色:棕白色
萊絲.吠叫()
三大特色 封裝 繼承 多型
封裝姓(Encapsulation)
定義: 封裝是為了隱藏一些外界不必要的資訊 封裝是為了隱藏/保護實作的細節 public protected private
/* 一個程序導向的程式會這樣寫: */
定義萊絲
萊絲.設定音調(5)
萊絲.吸氣()
萊絲.吐氣()/* 而當狗的吠叫被封裝到類別中,任何人都可以簡單地使用: */
定義萊絲是狗
萊絲.吠叫()
繼承Inheritance)
繼承者可以擁有被繼承者的特性
例如 狗 class 他的子類別 有 牧羊犬 或 吉娃娃
在這種情況下,子類別會繼承 狗的的行為和屬性 ,這樣狗的method 只要寫一次就可以了
類別吉娃娃犬:繼承狗
開始
公有成員:
顫抖()
結束類別牧羊犬:繼承狗定義萊絲是牧羊犬
萊絲.顫抖() /* 錯誤:顫抖是吉娃娃犬的成員方法。只能繼承狗的class,不可以多重繼承 */
多型(Polymorphism)
是指由繼承而產生的相關的不同的類別,其物件對同一訊息會做出不同的回應。 例如,狗和雞都有「叫()」這一方法,但是呼叫狗的「叫()」,狗會吠叫;呼叫雞的「叫()」,雞則會啼叫。 我們將它體現在虛擬碼上:
類別狗
開始
公有成員:
叫()
開始
吠叫()
結束
結束 類別雞
開始
公有成員:
叫()
開始
啼叫()
結束
結束 定義萊絲是狗
定義魯斯特是雞
萊絲.叫()
魯斯特.叫()
多行補充
- Overloading
簡單的來說就是,明明有很多個函式,但函式名稱卻能一樣,而系統如何判斷這些有相同名稱的函式該呼叫誰呢,主要就是用parameter list傳入的數量跟型別不同而定。
void print(int i) {…}void print(double d) {…}void print(char c) {...}
這三者都叫做print,但由於參數串列的型態不同所以系統可以自動區別出,當不同型別進來時各自要呼叫哪一個函式。所以對user而言,不管要印出整數、浮點數跟字元,所需做的動作都一樣,例如:print(100)、print(3.5)、print(‘a’)
- Overriding 『子類別將父類別函式重新定義以符合自身所需』
假如說今天有一個父類別 Person 一個子類別 Superman
但試想今天若Person中有一個運作叫做iam()裡面定義了印出Person的動作,此時若Superman繼承他的時後,iam()也會被繼承下去,如此當別人呼叫Superman的iam()時也會印出Person。試想若你是超人你會希望只印出Person嗎,應該很不甘心吧,好不容易成為超人,當然希望能大聲說出”i am superman!!
Overriding最終的目的,當然是希望利用父類別來動態操作子類別的函式,以達多型的效果。
EX1 : 父類別 Animal 子類別 Cat Bird
class Person { public void iam() {System.out.println(“I am a person.”);}}
class Superman extends Person { public void iam() {System.out.println(“I am a Superman.”);}}
EX2 : 父類別 Animal 子類別 Cat Bird
public abstract class Animal {
private int age = 0;
private String name = "Animal";
protected abstract void skill(); public int getAge() {
return age;
}
public void setAge(int age) {
if (age > 0) this.age = age;
else this.age = 0;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
public class Cat extends Animal{
@Override
protected void skill() {
System.out.println("裝可愛");
}
}public class Bird extends Animal{ @Override
protected void skill() {
System.out.println("飛");
}
}
主程式
public static void main(String[] args) {
Animal cat = new Cat();
Animal bird = new Bird(); cat.setAge(5);
cat.setName("Cat");
cat.skill(); bird.setAge(10);
bird.setName("bird");
bird.skill();}
EX3 :定義 Behavior 介面 eat & sleep 兩個方法,人會吃跟睡比較有規律,豬也會吃跟睡比較沒有規律。 (Overridng用法)
介面 Behavior 類別 People Pig
public interface Behavior {
void eat();
void sleep();
}public class People implements Behavior{ @Override
public void eat() {
System.out.println("吃三餐");
} @Override
public void sleep() {
System.out.println("睡八小時");
}
}public class Pig implements Behavior{ @Override
public void eat() {
System.out.println("睡飽吃");
} @Override
public void sleep() {
System.out.println("吃飽睡");
}
}
主程式
public static void main(String[] args) {
Behavior people = new People();
Behavior pig = new Pig(); people.eat();
people.sleep(); pig.eat();
people.sleep();}
結論 Overriding && Overloading
Overloading 注重的是不同式子共用相同的函式名稱。
Overriding 多型重視的是相同的function在不同的Class中會有不同的function name 會有不同的行為反應,並且在runtime才決定所需呼叫的行為反應。