我可以使用面向对象的语言更改setter中的类类型吗?

时间:2010-03-09 03:41:39

标签: language-agnostic oop

以下是问题陈述:在对象上调用setter会导致对象更改为其他类的对象,哪种语言可以支持? 防爆。我有一个名为“Man”(父类)的班级,以及两个孩子,即“幼儿”和“老人”,他们是孩子,因为他们覆盖了Man中称为walk的行为。 (即蹒跚学步者有时走路时用双手和双腿跪下,老人用棍子支撑自己)。

Man类有一个名为age的属性,我在Man上有一个setter,比如setAge(int ageValue)。我有3个物品,2个幼儿,1个老人。 (系统启动并运行,我想当我们说对象很明显时)。我会打这个电话,toddler.setAge(80),我希望小孩改成一个老人类型的对象。这可能吗?请建议。

谢谢,

8 个答案:

答案 0 :(得分:2)

这听起来像模特错了。您所拥有的是Person,其相对时间分组和某些特定行为随着年龄而变化。

也许你需要一个名为getAgeGroup()的方法,它返回一个合适的枚举,取决于当前的年龄。您还需要一个内部状态对象,它封装了您的Person委托行为随年龄变化的状态特定行为。

也就是说,动态更改实例化对象的类型可能只适用于动态类型语言;当然,它在Java中是不可行的,并且可能在C#和大多数其他静态类型语言中都不可行。

答案 1 :(得分:1)

这是一个常见问题,您可以使用OO建模和设计模式的组合来解决。

您将按照Toddler和OldMan从Man基类继承的方式对类进行建模。您需要引入一个Proxy(参见GoF设计模式)类作为您对Man类的访问。在内部,代理将一个man对象/指针/引用保存到Toddler或OldMan。代理将公开Man类公开的所有接口,以便您可以按原样使用它,在您的场景中,您将实现类似于以下伪代码的setAge:

public void setAge(int age)
{
   if( age > TODDLER_MAX && myMan is Toddler)
     myMan = new OldMan();
   else 
    .....
   myMan.setAge(age);   
}

答案 2 :(得分:1)

如果您的语言不支持在运行时更改classtype,请查看decoratorstrategy模式。

答案 3 :(得分:0)

Python中的对象可以通过设置__class__属性来更改其类。否则,请使用策略模式。

答案 4 :(得分:0)

我想知道子类化是否真的是最好的解决方案。可能具有不同类型的人作为其可能值的属性(可能是枚举)是一种替代方案。或者,就此而言,派生属性或方法根据年龄告诉您人员的类型。

答案 5 :(得分:0)

Javascript可以做到这一点。您可以随时获取现有对象并向其添加新方法,或更改其现有方法。这可以在单个对象级别完成。

道格拉斯·克罗克福德在Classical Inheritance in JavaScript中写道:

  

类增强

     

JavaScript的动态允许我们添加   或替换现有的方法   类。我们可以调用方法方法   在任何时候,所有在场和   未来的班级实例会   有那种方法。我们可以字面意思   随时扩展课程。   继承具有追溯性。我们   称此类增强为避免   与Java的混淆延伸,其中   意味着别的东西。

     

对象扩充

     

在静态面向对象中   语言,如果你想要一个对象   与另一个略有不同   对象,你需要定义一个新的   类。在JavaScript中,您可以添加   没有的单个对象的方法   需要额外的课程。这个   因为你可以拥有巨大的力量   写得少得多的课程和   你写的课程可以很多   简单。回想一下JavaScript   对象就像哈希表。您   可以随时添加新值。如果   value是一个函数,然后它变成了一个函数   方法

答案 6 :(得分:0)

Common Lisp可以:使用通用函数CHANGE-CLASS

答案 7 :(得分:0)

我很惊讶到目前为止似乎没有人注意到这是State design pattern的确切情况(尽管@Fadrian实际上非常精确地描述了模式的核心思想 - 但没有提到它的名字)。

  

状态模式是一种行为软件设计模式,也称为   状态模式的对象。此模式用于计算机   编程以表示对象的状态。这是一个干净的方式   object在运行时部分更改其类型。

引用的页面提供了Java和Python中的示例。显然,它也可以用其他强类型语言实现。 (OTOH弱类型语言不需要State,因为它们开箱即用。)

相关问题