Smalltalk-Squeak 中的抽象类。它是什么?
如果我没猜错的话,那么抽象类就是至少有一个抽象方法的类吗?
现在,如果它是抽象的,那么我应该无法创建该类的实例?
就像,说 Abst
是一个抽象类的名称(因为它包含一个抽象方法),这样做:
a := Abst new.
是非法的并且应该弹出错误/异常吗? 或者问题应该出现在这里:
a := Abst class new.
?
更新: 正如所建议的,我已经制作了下一个方法,它不会让用户创建类的实例,但它不起作用:
makeAbstract: aClass
aClass compile: 'new
^ self subclassResponsibility'.
If I got it right so an Abstract Class is one which has at least one abstract method?
Now, if it's abstract so I am supposed to be unable to make instances of that Class?
Like, said Abst
is a name of an abstract class (because it contains an abstract method) so doing:
a := Abst new.
is illegal and should pop-up an error/exception?
or the problem should arise here:
a := Abst class new.
?
UPDATE:
As suggested, I have made the next method which won't let the user to make instances of a Class but it doesn't work:
makeAbstract: aClass
aClass compile: 'new
^ self subclassResponsibility'.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
欢迎来到小聊! Smalltalk 的一大优点是它信任开发人员,开发人员可以从这种信任带来的力量中受益。因此,“无法”和“非法”之类的词很少适用。
与大多数其他事物一样,Smalltalk 中的抽象类更像是建议/指针,而不是严格的法则。您寻找的两条线索是#subclassResponsibility 和#shouldNotImplement。这两个方法是子类化器是否包含特定方法的线索。检查发件人是否有图片中的示例(始终是提问的一个很好的起点)。
由于如上所述的“抽象”实际上是基于每个方法的,因此您的示例不会生成错误(除非从初始化调用 #subclassResponsibility 或 #shouldNotImplement)。
有两件小事:
Smalltalk,所以 Abst,不是 Abst。
在四个最上面的链接中
“smalltalk 抽象类” 全部
你需要(这个尤其看起来很正确)。
更新:如果您想向您的类的用户发出信号,表明他们不应该创建实例(如下面的评论中所示),您可以编写:
然后“Abstract new”->错误,但“AbstractSubclass new”没问题。
虽然仍然不能保证 AbstractSubclass 已经重写了抽象方法(不是#new,而是导致您想要首先阻止实例化的方法),但实际上这不会成为问题。如果您确实想要,您可以进行检查(也许在 #initialize 中),以确保实例的任何方法都不会调用 #subclassResponsibility,但除非您有充分的理由,否则不要打扰。
更新 2:使类抽象的实用方法是:
Welcome to Smalltalk! One of the great things about Smalltalk is that it trusts developers, who benefit from the power that comes with that trust. So words like "unable to" and "illegal" rarely apply.
Like most other things, Abstract classes in Smalltalk are more like a suggestion/pointer than a rigid law. The two clues you look for are #subclassResponsibility and #shouldNotImplement. These two methods are clues to subclassers whether or not to include a particular method. Check senders for examples in the image (always a great starting point for questions).
Since "abstract", as described above, is really on a per-method basis, your examples would not generate an error (unless #subclassResponsibility or #shouldNotImplement is called from initialize.
Two small things:
Smalltalk, so Abst, not abst.
out of the four top links for
"smalltalk abstract class" were all
you need (this one in particular looked right on).
UPDATE: if you want to signal to users of your class that they should not create instances (like in your comment below), you could write:
Then "Abstract new" -> error, but "AbstractSubclass new" is okay.
Although there is still no guarantee that AbstractSubclass has overridden the abstract method (not #new, but the one that caused you to want to prevent instancing in the first place), in practice this will not be a problem. If you really wanted to, you could put a check, maybe in #initialize, that makes sure none of the instance's methods call #subclassResponsibility, but don't bother unless you have good reason.
UPDATE 2: Your utility method to make a class abstract would be:
在 Smalltalk 中,您只需实例化抽象类即可。只要您不调用抽象方法,它就可以工作。您可能想在运行时实现缺少的方法。
In Smalltalk you can just instantiate abstract classes. As long as you do not call abstract methods it just works. You might want to implement missing methods at runtime.
是的,抽象类应该至少有一个抽象方法,但是不,您仍然可以创建该类的实例。
您应该做的是创建从抽象类继承的具体类,您可以创建抽象类的实例并调用其方法。
Smalltalk 中的抽象方法有一个特定的实现,这使得它们和类抽象:
这也意味着子类应该重写此方法并提供具体的实现。
如果您看到有关 subclassResponsibility 的错误,您的代码要么调用了抽象类上的方法,要么您的子类未提供该方法的实现。
Yes, an abstract class should have at least one abstract method, but no, you can still make instances of that class.
What you should do is make concrete classes which inherit from the abstract class which you can make instances of and call methods on.
Abstract methods in Smalltalk have a particular implementation which make them and the class abstract:
This also means that subclasses should override this method and provide a concrete implementation.
If you see an error regarding subclassResponsibility your code has either called a method on the abstract class, or your subclass has not provided an implementation for the method.
我建议您阅读《Pharo By Examples》一书。您可以在这里找到它:http://pharobyexample.org/
你会发现很多有趣的东西。这是一本免费的开放式书籍,您可以下载 pdf 版本。
事实上,您所问的问题已在第 88 页第 5 章中进行了解释。
I recommend you to read the Pharo By Example book. You can find it here: http://pharobyexample.org/
and you will find a lot of interesting stuff. It is an open book, free, and you can download the pdf.
In fact, what you are asking is explained in chapter 5, page 88.
(固定的)“new-blocker”为其具体子类带来了一些不便:它们必须重新定义new,并且不能使用任何继承的超类的new功能。
您可以通过一个小保护来解决这个问题,它检查它是否确实是尝试实例化的抽象类:(
请注意此处的身份比较,即使您将多个抽象类堆叠在一起,它也可以工作)
The (fixed) "new-blocker" introduces a slight inconvenience for its concrete subclasses: they will have to redefine new, and cannot make use of any inherited superclasses' new functionality.
You can get around this with a little guard which checks if it is really the abstract class that is tried to be instantiated:
(notice the identity-compare here, which works even if you have stacked multiple abstract classes on top of each other)