Oop 返回一个类不是预期类的对象是否正确?

Oop 返回一个类不是预期类的对象是否正确?,oop,smalltalk,Oop,Smalltalk,我希望你能理解我。我有两门课,A和BB是A的子类。它们有相同的公共方法和相同的方法,但是B做的事情有点不同,所以它有额外的方法和属性,只使用它自己。比如说,类A实现了一个方法newFromWizard,该方法以交互方式创建对象。我是否可以根据用户输入,在A的newFromWizard方法中创建对象A或对象B的逻辑。我的意思是,我是否可以从A的方法中创建B对象?或者我需要在其他地方实施?最好的方法是什么?实际上,我可以。但是,它对OOP是正确的吗 顺便说一句,如果这很重要的话,我用的是Smallt

我希望你能理解我。我有两门课,
A
B
B
A
的子类。它们有相同的公共方法和相同的方法,但是B做的事情有点不同,所以它有额外的方法和属性,只使用它自己。比如说,类A实现了一个方法
newFromWizard
,该方法以交互方式创建对象。我是否可以根据用户输入,在A的
newFromWizard
方法中创建对象A或对象B的逻辑。我的意思是,我是否可以从A的方法中创建B对象?或者我需要在其他地方实施?最好的方法是什么?实际上,我可以。但是,它对OOP是正确的吗

顺便说一句,如果这很重要的话,我用的是Smalltalk

public class A{

    public B method(){
        B b = new B();
        return b;
    }
}

class B extends A{

}

如果这就是你所说的,它是有效的。

我想说,这不是一种直观的做事方式。让我们简化一下,假设您只是重新定义了
new
。然后在某一点上,您执行
一个新的
,并获得
B
的一个实例。他们的相似之处使情况并非如此糟糕。但是想象一下,其他人开始使用您的代码。hew知道消息
new
应该导致创建接收方的实例。然后事情就不同了。我认为这在概念上是错误的。为什么现在要实现一些生成器类?有类似的东西吗

createInstanceOfAB
  |className|
  className := "do what you need".
  ^ className asClass new.
这是一个更清晰的方法


您可以再次使用
新建…
方法来执行任何您想要的操作,甚至可以发射焰火,但大多数人都希望它创建同一类的实例

是的,这是OO中众所周知的模式。在Objective-Cocoa库中,您会发现它被系统地应用,称为类集群。结果是Cocoa库比同等的c#或java库更容易理解。它允许在具有返回子类的类端创建方法的抽象类后面隐藏继承层次结构

我认为您不应该太担心返回子类的实例是否是“干净的OO”。它经常被使用和使用,因为它非常有用,并且与somme之类的工厂和东西相比,它使您的代码非常可读

这里我最担心的是你应该仔细命名你的类方法。不要使用#new可能是最重要的规则,但你应该始终使用一个已经说过的名称:现在就给我一个合适的例子


我要说的是,这并不局限于子类,这样的方法甚至可以返回不从类继承的对象。在动态类型语言中,这是可以的。请记住,我们使用的是动态类型语言,因此只要您有多态接口,对象的类对其用户来说并不重要,只要它响应您的消息发送…

OK。但是,我想确定一下。它之所以有效,是因为它是正确的,还是仅仅因为你能做到?这不是一个坏习惯吗?这实际上取决于你的情况和你想要完成的事情。如果这是完成任务的唯一方法,那么就去做。但如果不理解问题的确切背景,就很难判断这有点违反OOP(为什么父类知道它的子类?),但我想说的主要是,为了可读性和可预测性,不要这样做。使用静态工厂方法(或Smalltalk等效方法)。@ChrisHayes on,parent了解子类。只需执行
对象所有子类
并获取系统中的所有子类。另外,由于类负责创建子类,所以它了解子类也没关系