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

use*_*413 2 smalltalk squeak

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

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

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

a := Abst new.
Run Code Online (Sandbox Code Playgroud)

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

a := Abst class new.
Run Code Online (Sandbox Code Playgroud)

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

makeAbstract: aClass    
    aClass compile: 'new
                ^ self subclassResponsibility'.
Run Code Online (Sandbox Code Playgroud)

Sea*_*ris 10

欢迎来到Smalltalk!Smalltalk的一大优点是它信任开发人员,他们从信任带来的力量中获益.所以像"无法"和"非法"这样的词很少适用.

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

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

两件小事:

  • 类名在Smalltalk中大写,因此Abst,而不是abst.
  • 谷歌搜索有很长的路要走."smalltalk抽象类"的四个顶部链接中有三个是你需要的(特别是这一个看起来正确).

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

Abstract>>new
    ^ self subclassResponsibility.
Run Code Online (Sandbox Code Playgroud)

然后"抽象新" - >错误,但"AbstractSubclass new"没问题.

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

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

Class>>makeAbstract

    self class compile: 'new
                ^ self subclassResponsibility'.
Run Code Online (Sandbox Code Playgroud)