3

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

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

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

a := Abst new.

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

a := Abst class new.

?

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

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

5 回答 5

11

欢迎来到 Smalltalk!Smalltalk 的一大优点是它信任开发人员,他们从这种信任带来的力量中受益。所以像“不能”和“非法”这样的词很少适用。

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

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

两件小事:

  • 类名在 Smalltalk 中大写,所以是 Abst,而不是 abst。
  • 谷歌搜索有很长的路要走。“smalltalk abstract class”的四个顶级链接中的三个就是您所需要的(尤其是这个看起来正确)。

更新:如果你想向你的类的用户发出信号,他们不应该创建实例(就像你在下面的评论中一样),你可以写:

Abstract>>new
    ^ self subclassResponsibility.

然后“Abstract new”-> 错误,但是“AbstractSubclass new”没问题。

尽管仍然不能保证 AbstractSubclass 已经覆盖了抽象方法(不是#new,而是导致您首先想要阻止实例化的方法),但实际上这不会成为问题。如果你真的想要,你可以检查一下,也许在#initialize 中,以确保没有实例的方法调用#subclassResponsibility,但除非你有充分的理由,否则不要打扰。

更新 2:您制作类抽象的实用方法是:

Class>>makeAbstract

    self class compile: 'new
                ^ self subclassResponsibility'.
于 2011-05-02T11:35:15.547 回答
3

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

于 2011-05-02T11:38:01.163 回答
3

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

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

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

method
    self subclassResponsibility

这也意味着子类应该覆盖这个方法并提供一个具体的实现。

如果您看到有关 subclassResponsibility 的错误,您的代码要么调用了抽象类的方法,要么您的子类没有提供该方法的实现。

于 2011-05-02T11:38:59.507 回答
2

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

于 2011-05-02T12:44:02.643 回答
2

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

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

(请注意此处的身份比较,即使您将多个抽象类堆叠在一起也可以使用)

于 2012-11-29T08:24:06.937 回答