早期 OO 語言(Simula)類型與實現混合。現代語言(Modula-3、Java、C#)引入 對象類型:僅聲明屬性簽名與方法簽名,無實現。例如:
class cell {
var contents: Integer := 0;
method get(): Integer { return self.contents; }
method set(n: Integer) { self.contents := n; }
}
subclass reCell of cell {
var backup: Integer := 0;
override set(n: Integer) {
self.backup := self.contents;
super.set(n);
}
method restore() { self.contents := self.backup; }
}
// 對應的對象類型
ObjectType Cell {
var contents: Integer;
method get(): Integer;
method set(n: Integer);
}
ObjectType ReCell {
var contents: Integer;
var backup: Integer;
method get(): Integer;
method set(n: Integer);
method restore();
}
無關類可實現同一類型,使用者面向類型編程,實現 接口與實現分離。
O' <: O 若 O' 擁有 O 所有成員(可更多)。支持多重子類型:ReCell <: Cell 且 ReCell <: ReInteger。
Subclassing ⇒ Subtyping(子類化蘊含子類型)。subclassing-implies-subtyping。素食者吃蔬菜,人吃食物。Vegetarian <: Person 但 eat(Food) 參數反協變,直接繼承導致素食者可吃肉(類型不安全)。
ObjectOperator PersonEating[F <: Food] {
method eat(food: F);
}
ObjectOperator VegetarianEating[F <: Vegetable] {
method eat(food: F);
}
對任意 F <: Vegetable,VegetarianEating[F] <: PersonEating[F]。具體化:Vegetarian = VegetarianEating[Vegetable] <: PersonEating[Vegetable],正確表達「素食者是吃蔬菜的人」。
ObjectType Person {
Type F <: Food;
var lunch: F;
method eat(food: F);
}
ObjectType Vegetarian {
Type F <: Vegetable;
var lunch: F;
method eat(food: F);
}
創建時綁定具體 F(如 Dessert)。局限:只能吃自帶午餐,無法動態傳入食物。