Oop 更改对象类的对象的方法称为什么?
假设您有一个Oop 更改对象类的对象的方法称为什么?,oop,Oop,假设您有一个Person对象,它上面有一个方法,promote(),将其转换为Captain对象。这种类型的方法/交互称为什么 这也感觉像是一种颠倒: myCaptain = new Captain(myPerson); 编辑:感谢所有回复。我遇到这种模式(在Perl中,但在任何地方都相关)的原因纯粹是为了方便。在不知道任何实现交易的情况下,您可以说Captain类“有一个”Person(我知道这可能不是最好的示例,但请确保它不是一个子类) 我假设: // this definition on
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?
因此,从字面上说,这只是一种方便的方法,用于构建船长。我只是想知道这种模式是否在野外见过,是否有名字。我猜是的,它并没有真正改变类,而是返回了一个不同的类。但理论上可以,因为我不太在乎原作
Ken++,我喜欢你指出用例的方式。有时候,在内存敏感的环境中适当地更改某些内容真是太棒了。对象的方法不应该更改其类。您应该有一个返回新实例的成员:
myCaptain = myPerson->ToCaptain();
或者使用构造函数,如您的示例所示:
myCaptain = new Captain(myPerson);
我会称之为转换,甚至是强制转换,这取决于您如何使用对象。如果您有一个值对象:
Person person;
您可以使用构造函数方法隐式强制转换:
Captain captain = person;
(假设C++)
< P>一个简单的解决方法可能是使人的属性为秩。我不知道你的数据结构或需求,但是如果你需要一些试图打破语言基础的东西,那么有可能有更好的方法去做。 你可能想考虑“状态模式”,有时也称为“对象状态”模式。它在《设计模式》一书中有定义,但你很容易在谷歌上找到很多关于它的信息
该模式的一个特点是“对象将显示为更改其类。”
以下是一些链接:
每个人似乎都在假设一个类似于C++/Java的对象系统,可能是因为问题中使用的语法,但在运行时用其他语言更改实例的类是很有可能的
Lisp的CLOS允许随时更改实例的类,这是一种定义良好且高效的转换。(术语和结构略有不同:方法不属于CLOS中的类。)
不过,我从来没有听说过这种特定类型的转换的名称。执行此操作的函数称为change class
Richard Gabriel在Kiczales之后提出了“变更类协议”,它将元编程CLOS的许多内部内容形式化为“协议”
人们想知道你为什么要这样做;与创建新实例相比,我看到了两大优势:
myCaptain = myPerson->ToCaptain();
- 更快:更改类可以像更新指针和更新任何不同的插槽一样简单;如果类非常相似,则无需新的内存分配即可完成此操作
- 更简单:如果十几个地方已经有了对旧对象的引用,那么创建一个新实例不会改变它们指向的对象;如果您需要自己更新每一个,这可能会为一个简单的操作增加很多复杂性(2个单词,用Lisp)
这并不是说它总是正确的答案,但是当你想要的时候有能力做到这一点是很好的。“更改实例的类”和“创建与该实例类似的新实例”是非常不同的操作,我希望能够准确地说出我的意思。第一个有趣的部分是要知道:为什么希望/需要对象在运行时更改其类
有多种选择:
- 您希望它对应用程序给定状态的某些方法做出不同的响应
- 您可能希望它具有原始类所没有的新功能
- 其他
Java和C#等静态类型语言不允许这种情况发生,因为在编译时应该知道对象的类型
其他编程语言,如Python和Ruby可能允许这样做(我不确定,但我知道他们可以在运行时添加方法)
对于第一个选项,Charlie Flowers给出的答案是正确的,使用状态模式将允许类的行为不同,但对象将具有相同的接口
对于第二个选项,您仍然需要更改对象类型,并将其指定给具有额外功能的新引用。因此,您需要创建另一个不同的对象,并最终得到两个不同的对象。需要将类更改为OCaptain,以便获得OCaptainmyCaptain@RichB,我不明白你为什么要去奥卡普坦。想解释一下吗?斯特拉格:这是个玩笑。别担心。有人会回滚,Rich可能会让它保持回滚状态。他们说代码不能是诗!;):-/哦,好吧,我想当你花很多时间编辑别人的帖子时就会发生这种情况(myCaptain=Person.ToCaptain()也许?:)+1:我认为简单地允许“Captain”构造函数接受“Person”对象并重新构建它们要干净得多。想象一下,如果你有许多其他职业(“海军上将”等),会发生什么。。。每个类都需要为其他类使用“To*”方法。