我知道Final类的定义是什么,但我想知道如何以及何时真正需要final。
<?php
final class Foo extends Bar
{
public function()
{
echo 'John Doe';
}
}
如果我理解正确,'final'使它能够扩展'Foo'。
任何人都可以解释何时以及为什么应该使用'final'?换句话说,是否有任何理由不应该扩展课程?
例如,如果类'Bar'和类'Foo'缺少某些功能,那么创建一个扩展'Bar'的类会很好。
答案 0 :(得分:44)
有一篇关于"When to declare classes final"的好文章。引用的一些引用:
TL; DR:如果他们实现了一个接口,并且没有定义其他公共方法,则使您的课程始终为
final
为什么我必须使用
final
?
- 防止大规模的厄运继承链
- 鼓励作文
- 强制开发人员考虑用户公共API
- 强制开发人员缩小对象的公共API
final
类始终可以扩展extends
打破封装- 您不需要这种灵活性
- 您可以自由更改代码
醇>何时避免
final
:最终课程只能在以下假设下有效运作:
- 最后一个类实现了一个抽象(接口)
- 最终类的所有公共API都是该接口的一部分
醇>如果缺少这两个前提条件中的一个,那么您可能会到达可以使类可扩展的时间点,因为您的代码并不真正依赖于抽象。
P.S。感谢@ocramius的精彩阅读!
答案 1 :(得分:18)
对于一般用法,我建议不要将课程设为“最终”。可能存在一些有意义的用例:如果您设计一个复杂的API /框架并希望确保框架的用户只能覆盖您希望他们控制的功能部分,那么您可能有意义限制这种可能性并使某些基类最终。
e.g。如果你有一个“整数”类,那么为了让你的框架形式的用户覆盖你的班级中的“add(...)”方法,最后做出决定是有意义的。
答案 2 :(得分:10)
原因是:
将一个类声明为final可防止它成为子类化的句点;这是该行的结束。
将类中的每个方法声明为final都允许创建子类,这些子类可以访问父类的方法,但不能覆盖它们。子类可以定义自己的其他方法。
- 醇>
final关键字仅控制覆盖的功能,不应与私有可见性修饰符混淆。任何其他类都无法访问私有方法;最后一个可以。
- 引自 David Powers 的 PHP面向对象解决方案一书的第68页。
例如:
final childClassname extends ParentsClassname {
// class definition omitted
}
这涵盖了整个班级,包括其所有方法和属性。从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;
}
}
在此示例中,它们都不能覆盖PageCount()
方法。
答案 3 :(得分:5)
最后一堂课是无法展开的课程http://www.php.net/manual/en/language.oop5.final.php
您可以在类包含您特别不希望被覆盖的方法的地方使用它。这可能是因为这样做会以某种方式破坏您的应用程序。
答案 4 :(得分:-2)
final
: