假设您有一个Person
对象,并且它上面有一个方法promote()
,可以将其转换为Captain
个对象。你怎么称呼这种方法/互动?
它也感觉像是反转:
myCaptain = new Captain(myPerson);
修改:感谢所有回复。我遇到这种模式的原因(在Perl中,但在任何地方相关)纯粹是为了方便。在不知道任何实现交易的情况下,您可以说Captain
类“有一个”Person
(我意识到这可能不是最好的例子,但请确保它不是子类)。
我假设的实施:
// this definition only matches example A
Person.promote() {
return new Captain(this)
}
personable = new Person;
// A. this is what i'm actually coding
myCaptain = personable.promote();
// B. this is what my original post was implying
personable.promote(); // is magically now a captain?
因此,从字面上看,它只是构建Captain
的便捷方法。我只是想知道这种模式是否在野外被看到并且它是否有名字。而且我猜是的,它并没有真正改变课程,因为它返回了另一个课程。但它理论上可以,因为我并不真正关心原作。
Ken ++,我喜欢你指出一个用例。有时改变某些东西真的很棒,比如一个对记忆敏感的环境。
答案 0 :(得分:5)
对象的方法不应更改其类。您应该拥有一个返回新实例的成员:
myCaptain = myPerson->ToCaptain();
或者使用构造函数,如示例所示:
myCaptain = new Captain(myPerson);
我将其称为转换,甚至是转换,具体取决于您如何使用该对象。如果您有一个值对象:
Person person;
您可以使用构造函数方法隐式转换:
Captain captain = person;
(假设是C ++。)
答案 1 :(得分:5)
更简单的解决方案可能是将排名作为人的财产。我不知道您的数据结构或要求,但如果您需要尝试打破语言基础知识,可能会有更好的方法。
答案 2 :(得分:3)
您可能想要考虑“状态模式”,有时也称为“状态对象”模式。它在“设计模式”一书中定义,但您可以在Google上轻松找到很多相关信息。
模式的一个特征是“对象似乎会改变它的类。”
以下是一些链接:
答案 3 :(得分:1)
每个人似乎都在假设一个类似C ++ / Java的对象系统,可能是因为问题中使用了语法,但很有可能在运行时用其他语言更改实例的类。
Lisp的CLOS允许随时更改实例的类,这是一个定义明确且高效的转换。 (术语和结构略有不同:方法不属于CLOS中的类。)
但是,我从未听说过这种特定类型的转型的名称。执行此操作的功能简称为change-class
。
理查德·加布里埃尔seems to call it之后的“变更类协议”,在Kiczales'AMOP之后,它正式化为CLOS内部许多元协议的“协议”。
人们想知道你为什么要这样做;我认为仅仅创建一个新实例有两大优势:
这并不是说它总是正确的答案,但有能力在你想要的时候做到这一点很好。 “更改实例的类”和“创建一个类似于那个实例的新实例”是非常不同的操作,我希望能够准确地说出我的意思。
答案 4 :(得分:0)
第一个有趣的部分是要知道:为什么你想要/需要一个对象在运行时改变它的类?
有多种选择:
您希望它对应用程序的给定状态的某些方法做出不同的响应。
您可能希望它具有原始类所没有的新功能。
其他......
静态类型语言(如Java和C#)不允许这种情况发生,因为在编译时应该知道对象的类型。
其他编程语言(如Python和Ruby)可能允许这样做(我不确定,但我知道他们可以在运行时添加方法)
对于第一个选项,Charlie Flowers给出的答案是正确的,使用状态模式将允许类表现不同但对象将具有相同的接口。
对于第二个选项,您无论如何都需要更改对象类型,并将其分配给具有额外功能的新引用。因此,您需要创建另一个不同的对象,最终会得到两个不同的对象。