热门问题
时间线
聊天
视角
委託 (物件導向程序設計)
来自维基百科,自由的百科全书
Remove ads
物件導向程序設計中的委託是指使用另一個對象(發送者)的上下文,對一個對象(接收者)的成員(屬性或方法)求值。通過把發送者對象傳遞給接收者對象,任何物件導向語言都可以做顯式的委託。如果語言特性支持成員查詢規則,則可以做隱式的委託。隱式委託是基於原型編程中行為重用的基本方法,對應於基於類編程的繼承。支持委託的最知名語言是Self和JavaScript。
術語委託在兩個對象之間還有別的用法。見委託 (編程)。最容易混淆的是在接收者的上下文中,與發送者成員對應的接收者成員被求值,精確地說這是轉發(即包裝者對象(wrapper object)並不把自身傳遞給被包裝對象(wrapped object))。[1][2][a]簡單地使用另一個對象,這是對象聚合 。委託模式是軟體設計模式中實現委託的一種套路。
概述
1986年,MIT計算機科學與人工智慧實驗室的亨利·利伯曼首創發表了基於原型編程、利用方法查詢規則的物件導向的委託等技術和概念。[3]
委託依賴於動態綁定,因為它需要一個給定的方法可以在不同的運行時上下文中被調用。這可以用於作業系統提供單獨一個類管理各個窗口。例如,當用戶點擊close box, 窗口管理器發送委託:windowShouldClose調用;如果根據窗口的上下文有未保存數據,委託會延遲關閉這個窗口。
... messages sent to the
self
(orthis
) variable in the parent will "come back" to the object that originally received the message.
也就是說,接收對象的一個方法定義中的self
並不是靜態綁定到定義時的那個對象,而是在求值時才綁定到「最初」的對象。
有觀點認為委託優於繼承,使程序代碼更為可多、可理解。[5]有觀點認為委託和繼承是等價的,但也有認為一個是另一個特例。[6]
Remove ads
語言支持
class A {
public void foo() {
// "this" also known under the names "current", "me" and "self" in other languages
this.bar();
}
void bar() {
Console.WriteLine("a.bar");
}
};
class B {
private delegate A a; // delegation link
public B(A a) {
this.a = a;
}
public void foo() {
a.foo(); // call foo() on the a-instance
}
public void bar() {
Console.WriteLine("b.bar");
}
};
a = new A();
b = new B(a); // establish delegation between two objects
b.foo();
b.bar();
調用b.foo()
將列印b.bar, 因為在a
的上下文中this
引用到最初的接收者對象b
。this
的結果的二義性被稱作object schizophrenia。
把隱式的this
翻譯為顯式參數,調用(在B
中, a
是個委託) a.foo()
翻譯為A.foo(b)
,使用a
類型做方法的查詢解析, 但調用委託的對象b
作為this
實參。
使用繼承,類似代碼為:
class A {
void foo() {
this.bar();
}
void bar() {
print("A.bar");
}
};
class B extends A {
public B() {}
void foo() {
super.foo(); // call foo() of the superclass (A)
}
void bar() {
print("B.bar");
}
};
b = new B();
調用b.foo()
的結果為B.bar. 其中this.bar()
解析為子類的方法.
Remove ads
注釋
參考文獻
外部連結
Wikiwand - on
Seamless Wikipedia browsing. On steroids.
Remove ads