什么时候应该使用“最终”?
我应该在日常编程(网络或其他方式)中将类或方法声明为final 有什么特殊原因吗? 请提供一个应该使用它的真实示例。
顺便说一句,我这么问是因为我正在尝试 选择一个“晦涩”的关键字并掌握它。
Is there any particular reason I should declare a class or a method final in day-to-day programming (web or otherwise)? Please provide a real-world example where it should be used.
BTW, I'm asking because I'm trying to pick an 'obscure' keyword and master it.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(6)
它可以防止其他程序员对您的类执行您不希望他们执行的操作。 因此,与其发表评论说“不要使用此类来执行 XXX”,您可以以这样的方式设计它,使他们不会试图以这种方式覆盖它并滥用它。
编辑:由于要求提供示例,我将描述一种情况,您可能会发现此关键字很方便...假设您有一个类,它定义了两个对象如何相互通信,例如监听者和通知者。 侦听器类显然必须允许继承,但您可能希望将通知器类设置为最终类,以便它必须以“has-a”关系使用。 这样,您可以从侦听器对象中对它们接收的消息的性质做出一些假设。
否则,就有可能从该类继承,做各种疯狂的事情,比如扩展消息等等。 如果您不希望其他程序员这样做,那么您可以将该类设为最终类。 此外,这在广泛使用的公共 API 中可能更有意义,因为它还允许其他程序员轻松理解哪些类可以进行子类化。
另一个例子——假设您有一个基于缓冲区的流处理器,并且在 read()/write() 方法内部,您维护一些有关对象当前状态的数据(即当前字节或其他)。 没有办法保证任何子类化这个类的人都会在处理过程中调用超级方法——并且由于这样的类可能只包含几个方法,所以最好将整个方法定为最终方法,而不是每个方法。 这再次迫使人们使用该类“has-a”,而不是“is-a”,因此可以控制您期望代码的执行方式。
我同意你的观点,让整个类最终可能是你千载难逢的事情,但如果你选择使用PHP,它具有这种功能,这很好。
It prevents other programmers from doing stuff with your classes that you don't intend for them to do. So rather than making a comment saying "don't use this class to do XXX", you can design it in such a way that they won't be tempted to override it and abuse it in that manner.
Edit: Since an example is requested, I'll describe a case where you might find this keyword handy... say you have a class which defines how two objects may communicate with each other, say, a listener and notifier. The listener class must obviously allow inheritance, but you might want to make the notifier class final so that it must be used in a "has-a" relationship. This way, you can make some assumptions from your listener objects about the nature of the messages they are receiving.
Otherwise, it would be possible to inherit from that class, do all sorts of crazy stuff like extend the messages and so on. If you don't want other programmers to do that, then you could make the class final. Also, this might make a lot more sense in a widely-used public API, as it also allows other programmers to readily understand which classes are ok to subclass.
Another example -- say you have a buffer-based stream processor, and inside of your read()/write() method, you maintain some data about the current state of your object (ie, the current byte or whatever). There is no way to guarantee that anyone subclassing this class would call the super's methods during processing -- and since such a class likely only contains a few methods, it's better to just make the whole thing final instead of each method. This again forces people using the class to "has-a", not "is-a", and thus, can control how you expect the code will be executed.
I would agree with you in that making an entire class final is probably something which you'd need to do once in a blue moon, but it's nice that PHP has this capability should you choose to exercise it.
“强制组合优于继承”说得相当简洁。 您可以保证类的某些行为不受其他任何事物的干扰,正如下一节所述,这也可以带来安全好处。
"Enforce Composition over Inheritance" puts it rather succinctly. You guarantee a certain behavior of your class that nothing else can interfere with, which, as the next section explains, can have security benefits as well.
有些人声称您应该将所有类声明为final,除非您特别打算允许它的多态扩展,并且已经检查了它的含义。 我倾向于认为这意味着对使用您的代码的其他人非常不信任,但不幸的是,有时这是有道理的。
Some people claim that you should declare all classes final unless you specifically intend to allow, and have examined the implications of, polymorphic extension of it. I tend to feel this implies a lot of distrust of whoever else is working with your code, but unfortunately, sometimes that's warranted.
在许多语言中,将类声明为 Final 还提供了优化优势,因为它不需要查看 virt 表中的方法。
如果你想强制执行类的意图,并且该意图使得子类化没有意义,那么使用final; 否则,没有显着的优势。
一般来说,它只是一种强制执行意图的机制。
In many languages, declaring a class as final also provides optimization benefits, since it needn't look at the virt table for methods.
If you want to enforce the intent of the class, and the intent is such that it doesn't make sense to subclass, then use final; otherwise, there's no significant advantage.
In general, it's just a mechanism for enforcing intent.
最终类是不能子类化的类,因此您不希望创建派生类。 例如,在 Java 中,Math 类是最终类,因为 Java 不希望您能够重新定义绝对值的含义。
A final class is a class that can not be subclassed, so anything that you don't want to have derivatives created of. For instance in Java, the Math class is final since Java doesn't want you to be able to redefine what Absolute value means.
Final(在 C# 中密封)可以(由类库设计者)用来强制执行类的一些基本行为。
例如强制字符串具有不可变的行为
java中的字符串类被标记为final,而在c#中它被标记为sealed。
所有字符串都是不可变的,并且其行为无法更改。
final (and sealed in c#) could be used (by class library designers) to enforce some basic behaviour of a class.
For instance enforce that the string has immutable behaviour
The string class in java is marked final and in c# it is marked sealed.
All strings are immutable and that behaviour cannot be changed.