Smalltalk-Squeak中的抽象类。它是什么?

时间:2011-05-02 10:12:07

标签: smalltalk squeak

如果我说得对,那么抽象类是至少有一个抽象方法的吗?

现在,如果它是抽象的,那么我应该无法创建该类的实例?

就像说Abst是一个抽象类的名称(因为它包含一个抽象方法)所以这样做:

a := Abst new.

是非法的,应该弹出错误/异常? 或者问题出现在这里:

a := Abst class new.

更新: 正如所建议的那样,我已经制作了下一个方法,它不会让用户创建一个类的实例,但它不起作用:

makeAbstract: aClass    
    aClass compile: 'new
                ^ self subclassResponsibility'.

5 个答案:

答案 0 :(得分:10)

欢迎来到Smalltalk! Smalltalk的一大优点是它信任开发人员,他们从信任带来的力量中获益。因此,“无法”和“非法”之类的词很少适用。

与大多数其他事物一样,Smalltalk中的抽象类更像是建议/指针而不是严格的法则。您寻找的两条线索是#subclassResponsibility和#shouldNotImplement。无论是否包含特定方法,这两种方法都是子类的线索。检查发件人的图像中的示例(始终是问题的一个很好的起点)。

由于“abstract”,如上所述,实际上是基于每个方法,因此您的示例不会生成错误(除非从初始化调用#subclassResponsibility或#shouldNotImplement。

两件小事:

  • 班级名称大写 Smalltalk,所以Abst,而不是abst。
  • 谷歌搜索有很长的路要走。三 在四个顶部链接中 “smalltalk抽象类”都是 你需要(this one特别注意)。

更新:如果你想向你的班级用户发出他们不应该创建实例的信号(比如下面的评论),你可以写:

Abstract>>new
    ^ self subclassResponsibility.

然后“抽象新” - >错误,但“AbstractSubclass new”没关系。

虽然仍然无法保证AbstractSubclass覆盖了抽象方法(不是#new,而是导致你想要首先防止实例化的方法),实际上这不会成为问题。如果真的想要,你可以在#initialize中进行检查,确保实例的方法都不会调用#subclassResponsibility,但除非你有充分的理由,否则不要打扰。

更新2:使类抽象的实用方法是:

Class>>makeAbstract

    self class compile: 'new
                ^ self subclassResponsibility'.

答案 1 :(得分:2)

在Smalltalk中,您可以实例化抽象类。只要你不调用抽象方法就可以了。您可能希望在运行时实现缺少的方法。

答案 2 :(得分:2)

是的,抽象类应该至少有一个抽象方法,但不,你仍然可以创建该类的实例。

你应该做的是制作从抽象类继承的具体类,你可以创建实例并调用方法。

Smalltalk中的抽象方法有一个特殊的实现,使它们和类抽象:

method
    self subclassResponsibility

这也意味着子类应该重写此方法并提供具体的实现。

如果您看到有关subclassResponsibility的错误,您的代码会在抽象类上调用方法,或者您的子类未提供该方法的实现。

答案 3 :(得分:1)

我建议你阅读Pharo By Example书。你可以在这里找到它:http://pharobyexample.org/ 你会发现很多有趣的东西。这是一本免费的开放式书籍,您可以下载pdf。 事实上,您要问的内容将在第88页的第5章中解释。

答案 4 :(得分:1)

(固定)“new-blocker”为其具体的子类带来了轻微的不便:他们必须重新定义 new ,并且不能使用任何继承的超类' new 功能。 你可以通过一个小小的守卫来解决这个问题,它会检查它是否真的是试图实例化的抽象类:

AbstractClass class >> new
    self == AbstractClass ifTrue:[
        ^ self abstractClassInstantiationError
    ].
    ^ super new

(注意这里的身份比较,即使你把多个抽象类叠加在一起,它也能正常工作)