什么时候在 PHP 中使用 Final?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/4248021/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
When to use Final in PHP?
提问by Inga Johansson
I know what the definition is of a Final class, but I want to know how and when final is really needed.
我知道 Final 类的定义是什么,但我想知道真正需要 final 的方式和时间。
<?php
final class Foo extends Bar
{
public function()
{
echo 'John Doe';
}
}
If I understand it correctly, 'final' enables it to extend 'Foo'.
如果我理解正确,'final' 使它能够扩展 'Foo'。
Can anyone explain when and why 'final' should be used? In other words, is there any reason why a class should not be extended?
任何人都可以解释何时以及为什么应该使用“最终”?换句话说,有什么理由不应该扩展一个类?
If for example class 'Bar' and class 'Foo' are missing some functionality, it would be nice to create a class which extends 'Bar'.
例如,如果类“Bar”和类“Foo”缺少某些功能,那么创建一个扩展“Bar”的类会很好。
采纳答案by mhanisch
For general usage, I would recommend against making a class final
. There might be some use cases where it makes sense: if you design a complex API / framework and want to make sure that users of your framework can override only the parts of the functionality that you want them to control it might make sense for you to restrict this possibility and make certain base classes final
.
对于一般用途,我建议不要创建 class final
。可能有一些用例是有意义的:如果您设计了一个复杂的 API / 框架并希望确保您的框架的用户只能覆盖您希望他们控制的部分功能,那么您可能对限制这种可能性并制作某些基类final
。
e.g. if you have an Integer
class, it might make sense to make that final
in order to keep users of your framework form overriding, say, the add(...)
method in your class.
例如,如果你有一个Integer
类,final
为了让你的框架的用户能够覆盖add(...)
你的类中的方法,这样做可能是有意义的。
回答by Nikita U.
There is a nice article about "When to declare classes final". A few quotes from it:
有一篇关于“何时将类声明为 final”的好文章。从中摘录几句:
TL;DR: Make your classes always
final
, if they implement an interface, and no other public methods are definedWhy do I have to use
final
?
- Preventing massive inheritance chain of doom
- Encouraging composition
- Force the developer to think about user public API
- Force the developer to shrink an object's public API
- A
final
class can always be made extensibleextends
breaks encapsulation- You don't need that flexibility
- You are free to change the code
When to avoid
final
:Final classes only work effectively under following assumptions:
- There is an abstraction (interface) that the final class implements
- All of the public API of the final class is part of that interface
If one of these two pre-conditions is missing, then you will likely reach a point in time when you will make the class extensible, as your code is not truly relying on abstractions.
TL;DR:
final
如果你的类实现了一个接口,并且没有定义其他公共方法,那么让你的类总是为什么我必须使用
final
?
- 防止厄运的大规模继承链
- 鼓励组合
- 强制开发者考虑用户公共 API
- 强制开发者缩小对象的公共 API
- 一个
final
类总是可以扩展的extends
打破封装- 你不需要那种灵活性
- 您可以自由更改代码
何时避免
final
:最终类仅在以下假设下有效工作:
- 最终类实现了一个抽象(接口)
- 最终类的所有公共 API 都是该接口的一部分
如果缺少这两个先决条件中的一个,那么您可能会到达使类可扩展的时间点,因为您的代码并没有真正依赖抽象。
P.S. Thanks to @ocramius for great reading!
PS 感谢@ocramius 的精彩阅读!
回答by li bing zhao
The reason are:
原因是:
Declaring a class as final prevents it from being subclassed—period; it's the end of the line.
Declaring every method in a class as final allows the creation of subclasses, which have access to the parent class's methods, but cannot override them. The subclasses can define additional methods of their own.
The final keyword controls only the ability to override and should not be confused with the private visibility modifier. A private method cannot be accessed by any other class; a final one can.
将一个类声明为 final 可以防止它被子类化——句号;这是行的尽头。
将类中的每个方法声明为 final 允许创建子类,这些子类可以访问父类的方法,但不能覆盖它们。子类可以定义自己的附加方法。
final 关键字仅控制覆盖的能力,不应与私有可见性修饰符混淆。任何其他类都不能访问私有方法;最后一个可以。
—— quoted from page 68 of the book PHP Object-Oriented Solutionsby David Powers.
-从书中的68页引用PHP的面向对象的解决方案由大卫·鲍尔斯。
For example:
例如:
final childClassname extends ParentsClassname {
// class definition omitted
}
This covers the whole class, including all its methods and properties. Any attempt to create a child class from childClassname would now result in a fatal error. But,if you need to allow the class to be subclassed but prevent a particular method from being overridden, the final keyword goes in front of the method definition.
这涵盖了整个类,包括它的所有方法和属性。任何从 childClassname 创建子类的尝试现在都会导致致命错误。但是,如果您需要允许类被子类化但防止特定方法被覆盖,则 final 关键字位于方法定义之前。
class childClassname extends parentClassname {
protected $numPages;
public function __construct($autor, $pages) {
$this->_autor = $autor;
$this->numPages = $pages;
}
final public function PageCount() {
return $this->numPages;
}
}
In this example, none of them will be able to overridden the PageCount()
method.
在此示例中,它们都无法覆盖该PageCount()
方法。
回答by Matt Asbury
A final
class is one which cannot be extended http://php.net/manual/en/language.oop5.final.php
一个final
类是不能扩展的http://php.net/manual/en/language.oop5.final.php
You would use it where the class contained methods which you specifically do not want overridden. This may be because doing do would break your application in some way.
您可以在类包含您特别不想覆盖的方法的地方使用它。这可能是因为这样做会以某种方式破坏您的应用程序。