2011-05-11 57 views
2

this post中,勇敢者希望(用C++)將類型爲Base的對象向下轉換爲Derived類型。假設派生類型沒有比Base更多的屬性,那麼可以是有意義的,如果你嫉妒Derived類提供的額外方法。哪些語言允許更改對象的身份(不是強制轉換)?

是否有編程語言允許這樣的事情?

+2

方法是什麼定義類,而不是屬性。 – 2011-05-17 19:06:53

回答

1

實際上,這是在Common Lisp和CLOS(Common Lis Object System)被移植的其他Lisp方言中沒有問題的情況下完成的。您使用change-class通用功能。

CLOS與多種調度方法一起工作,所以一個方法不綁定到一個類或對象,它只是一個函數,在一組類似函數WRT中選擇它的參數的類型(或身份)。當使用change-class時,您可以給出參數,就好像您正在創建新實例一樣,並且已存儲在對象中的數據將保留。下面是展示它是如何工作有點會議:

CL-USER> (defclass base() 
     ((name :initarg :name))) 
#<STANDARD-CLASS BASE> 
CL-USER> (defclass derived (base) 
     ((age :initarg :age :initform 0))) 
#<STANDARD-CLASS DERIVED> 
CL-USER> (defvar foo (make-instance 'base :name "John Doe")) 
FOO 
CL-USER> (change-class foo 'derived :age 27) 
#<DERIVED {100338F2D1}> 
CL-USER> (with-slots (name age) foo 
     (list name age)) 
("John Doe" 27) 
CL-USER> (defvar bar (make-instance 'base :name "Baby Joe")) 
BAR 
CL-USER> (change-class bar 'derived) 
#<DERIVED {10036CF6E1}> 
CL-USER> (with-slots (name age) bar 
     (list name age)) 
("Baby Joe" 0) 
CL-USER> 

如果這個默認的行爲是不夠的,你可以在update-instance-for-different-class定義的方法。

所以是的,有編程語言,允許這樣的事情

+0

Awsome,謝謝! – CharlesB 2011-07-26 10:02:37

+0

如果你想看看Lisp能夠做什麼,那麼有兩種可用的資源。如果你想要一些更實用的東西,那就去Peter Seibel的Practical Common Lisp(http://gigamonkeys.com/book/),如果你至少有點精通數學,並且想深刻理解本質計算機編程,嘗試SICP(http://mitpress.mit.edu/sicp/,並有視頻課程http://groups.csail.mit.edu/mac/classes/6.001/abelson-sussman-lectures/) – 2011-07-26 10:52:24

1

不,但首先這是一種強烈的代碼味道。

一種更好的選擇是使用decorator pattern,這正是它所做的。

+0

當你想說「我不喜歡它」時,不要回答「否」。特別是當「否」實際上是錯誤的時候... – 2011-07-26 09:53:58

0

如果Derived沒有添加任何屬性,那麼它添加的方法必須在從Base得到的狀態下運行。在那種情況下,爲什麼不把這些方法移到Base那裏?

+0

正是因爲@Albus對問題的評論。屬性不定義類,一個類有不同的方法具有不同的身份/功能。 – CharlesB 2011-06-06 07:41:42

+1

這甚至是Haskell中類型類型的概念。如果它實現每個類的功能,相同的對象可以在不同的類型類中。... – 2011-07-26 10:54:23