什么时候在 PHP 中使用 Final?

发布于 2024-10-03 10:22:10 字数 307 浏览 7 评论 0原文

我知道 Final 类的定义是什么,但我想知道如何以及何时真正需要 Final 。

<?php
final class Foo extends Bar
{
   public function()
   {
     echo 'John Doe';
   }
}

如果我理解正确的话,“final”使其能够扩展“Foo”。

谁能解释何时以及为什么应该使用“最终”?换句话说,有什么理由不应该延长班级吗?

例如,如果类“Bar”和类“Foo”缺少某些功能,那么创建一个扩展“Bar”的类会很好。

I know what the definition is of a Final class, but I want to know how and when final is really needed.

<?php
final class Foo extends Bar
{
   public function()
   {
     echo 'John Doe';
   }
}

If I understand it correctly, 'final' enables it to extend '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'.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

酸甜透明夹心 2024-10-10 10:22:10

有一篇关于“何时声明类为final”的好文章。摘录几段:

TL;DR:如果您的类实现接口并且未定义其他公共方法,则使它们始终final

为什么我必须使用final

  1. 防止大规模的厄运继承链
  2. 鼓励作文
  3. 迫使开发者考虑用户公共 API
  4. 强制开发者缩小对象的公共 API
  5. final 类始终可以扩展
  6. 扩展打破封装
  7. 您不需要这种灵活性
  8. 您可以随意更改代码

何时避免final

最终课程只有在以下假设下才能有效工作:

  1. 最终类实现一个抽象(接口)
  2. 最终类的所有公共 API 都是该接口的一部分

如果缺少这两个先决条件之一,那么您可能会达到使类可扩展的时间点,因为您的代码并不真正依赖于抽象。

PS 感谢@ocramius 的精彩阅读!

There is a nice article about "When to declare classes final". A few quotes from it:

TL;DR: Make your classes always final, if they implement an interface, and no other public methods are defined

Why do I have to use final?

  1. Preventing massive inheritance chain of doom
  2. Encouraging composition
  3. Force the developer to think about user public API
  4. Force the developer to shrink an object's public API
  5. A final class can always be made extensible
  6. extends breaks encapsulation
  7. You don't need that flexibility
  8. You are free to change the code

When to avoid final:

Final classes only work effectively under following assumptions:

  1. There is an abstraction (interface) that the final class implements
  2. 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.

P.S. Thanks to @ocramius for great reading!

少女情怀诗 2024-10-10 10:22:10

对于一般用途,我建议不要创建类 final。可能在某些用例中它是有意义的:如果您设计一个复杂的 API/框架,并希望确保框架的用户只能覆盖您希望他们控制的功能部分,那么您可能会这样做限制这种可能性并将某些基类设为final

例如,如果您有一个 Integer 类,那么将其设为 final 可能是有意义的,以便让框架的用户能够覆盖 add(. ..) 类中的方法。

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.

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.

静若繁花 2024-10-10 10:22:10

原因是:

  1. 将一个类声明为 Final 可以防止它被子类化——句号;这是该行的末尾。

  2. 将类中的每个方法声明为 Final 允许创建子类,子类可以访问父类的方法,但不能覆盖它们。子类可以定义自己的附加方法。

  3. final 关键字仅控制覆盖的能力,不应与私有可见性修饰符混淆。私有方法不能被任何其他类访问;最后一个可以。

—— 引自 David PowersPHP Object-Oriented Solutions一书的第 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() 方法。

The reason are:

  1. Declaring a class as final prevents it from being subclassed—period; it’s the end of the line.

  2. 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.

  3. 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.

—— quoted from page 68 of the book PHP Object-Oriented Solutions by David Powers.

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.

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.

紫瑟鸿黎 2024-10-10 10:22:10

final 类是无法扩展的 http: //php.net/manual/en/language.oop5.final.php

您可以在类包含您特别不希望覆盖的方法的地方使用它。这可能是因为这样做会以某种方式破坏您的应用程序。

A final class is one which cannot be extended 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.

盗心人 2024-10-10 10:22:10

我的 2 美分:

何时使用 final

  • 从不!!

为什么?

  • 它破坏了当单元测试时使用测试双精度
  • 可能会导致代码重复增加,因为下游代码中的功能存在差距,
  • 使用它的原因都是训练问题,正在通过一种激进的捷径

来解决使用它的坏原因:

  • 防止大量的继承链doom (训练问题)
  • 鼓励组合 (训练问题)
  • 迫使开发者思考用户公共 API (训练问题)
  • 迫使开发者收缩对象的公共 API (训练问题?代码审查?)
  • 最终类始终可以扩展(相关性?)
  • 扩展破坏封装 (什么?不良封装破坏封装;而不是继承。继承本身并不是邪恶的。)
  • 你不需要这种灵活性(短视开发背后的典型思维。准备好遇到功能墙 + 培训问题)
  • 您可以自由更改代码(相关性?)

My 2 cents:

When To Use final:

  • NEVER!!

Why?

  • it breaks the ability to use test doubles when unit testing
  • could lead to increased code duplication because of gaps in functionality in downstream code
  • the reasons to use it are all training issues being addressed with a radical shortcut

Bad Reasons to Use It:

  • Preventing massive inheritance chain of doom (training issue)
  • Encouraging composition (training issue)
  • Force the developer to think about user public API (training issue)
  • Force the developer to shrink an object's public API (training issue? code reviews?)
  • A final class can always be made extensible (relevance?)
  • extends breaks encapsulation (what? poor encapsulation breaks encapsulation; not inheritance. inheritance is not inherently evil.)
  • You don't need that flexibility (typical thinking behind short-sighted development. be prepared to hit a feature wall + training issue)
  • You are free to change the code (relevance?)
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文