Movatterモバイル変換


[0]ホーム

URL:


update page now
PHP 8.5.3 Released!
    Object Cloning »
    « Magic Methods

    Final Keyword

    The final keyword prevents child classes from overriding a method, property, or constant by prefixing the definition withfinal. If the class itself is being defined final then it cannot be extended.

    Example #1 Final methods example

    <?php
    classBaseClass{
    public function
    test() {
    echo
    "BaseClass::test() called\n";
    }

    final public function
    moreTesting() {
    echo
    "BaseClass::moreTesting() called\n";
    }
    }

    class
    ChildClassextendsBaseClass{
    public function
    moreTesting() {
    echo
    "ChildClass::moreTesting() called\n";
    }
    }
    // Results in Fatal error: Cannot override final method BaseClass::moreTesting()
    ?>

    Example #2 Final class example

    <?php
    final classBaseClass{
    public function
    test() {
    echo
    "BaseClass::test() called\n";
    }

    // As the class is already final, the final keyword is redundant
    final public functionmoreTesting() {
    echo
    "BaseClass::moreTesting() called\n";
    }
    }

    class
    ChildClassextendsBaseClass{
    }
    // Results in Fatal error: Class ChildClass may not inherit from final class (BaseClass)
    ?>

    Example #3 Final property example as of PHP 8.4.0

    <?php
    classBaseClass{
    final protected
    string $test;
    }

    class
    ChildClassextendsBaseClass{
    public
    string $test;
    }
    // Results in Fatal error: Cannot override final property BaseClass::$test
    ?>

    Example #4 Final constants example as of PHP 8.1.0

    <?php
    classFoo
    {
    final public const
    X="foo";
    }

    class
    BarextendsFoo
    {
    public const
    X="bar";
    }

    // Fatal error: Bar::X cannot override final constant Foo::X
    ?>

    Note: As of PHP 8.0.0, private methods may not be declared final except for theconstructor.

    Note: A property that is declaredprivate(set) is implicitlyfinal.

    Found A Problem?

    Learn How To Improve This PageSubmit a Pull RequestReport a Bug
    add a note

    User Contributed Notes11 notes

    306
    jriddy at gmail dot com
    16 years ago
    Note for Java developers: the 'final' keyword is not used for class constants in PHP. We use the keyword 'const'.http://php.net/manual/en/language.oop5.constants.php
    111
    penartur at yandex dot ru
    18 years ago
    Note that you cannot ovverride final methods even if they are defined as private in parent class.Thus, the following example:<?phpclassparentClass{    final private functionsomeMethod() { }}classchildClassextendsparentClass{    private functionsomeMethod() { }}?>dies with error "Fatal error: Cannot override final method parentClass::someMethod() in ***.php on line 7"Such behaviour looks slight unexpected because in child class we cannot know, which private methods exists in a parent class and vice versa.So, remember that if you defined a private final method, you cannot place method with the same name in child class.
    someone dot else at elsewhere dot net
    12 years ago
    @thomas at somewhere dot comThe 'final' keyword is extremely useful.  Inheritance is also useful, but can be abused and becomes problematic in large applications.  If you ever come across a finalized class or method that you wish to extend, write a decorator instead.<?phpfinal classFoo{    publicmethod doFoo()    {// do something useful and return a result}}final classFooDecorator{    private$foo;        public function__construct(Foo $foo)    {$this->foo=$foo;    }        public functiondoFoo()    {$result=$this->foo->doFoo();// ... customize result ...return$result;    }}?>
    Rumour
    2 years ago
    Class constants CAN be “finalised” since PHP8.1. To partly contradict to the most popular user contribution, that was written a long time ago, they were still absolutely right.
    mattsch at gmail dot com
    11 years ago
    You can use final methods to replace class constants.  The reason for this is you cannot unit test a class constant used in another class in isolation because you cannot mock a constant.   Final methods allow you to have the same functionality as a constant while keeping your code loosely coupled.Tight coupling example (bad to use constants):<?phpinterfaceFooInterface{}classFooimplementsFooInterface{    constBAR=1;    public function__construct()    {    }}interfaceBazInterface{    public functiongetFooBar();}// This class cannot be unit tested in isolation because the actual class Foo must also be loaded to get the value of Foo::BARclassBazimplementsBazInterface{    private$foo;    public function__construct(FooInterface $foo)    {$this->foo=$foo;    }    public functiongetFooBar()    {        returnFoo::BAR;    }}$foo= newFoo();$baz= newBaz($foo);$bar=$baz->getFooBar();?>Loose coupling example (eliminated constant usage):<?phpinterfaceFooInterface{    public functionbar();}classFooimplementsFooInterface{    public function__construct()    {    }    final public functionbar()    {        return1;    }}interfaceBazInterface{    public functiongetFooBar();}// This class can be unit tested in isolation because class Foo does not need to be loaded by mocking FooInterface and calling the final bar method.classBazimplementsBazInterface{    private$foo;    public function__construct(FooInterface $foo)    {$this->foo=$foo;    }    public functiongetFooBar()    {        return$this->foo->bar();    }}$foo= newFoo();$baz= newBaz($foo);$bar=$baz->getFooBar();?>
    slorenzo at clug dot org dot ve
    18 years ago
    <?phpclassparentClass{    public functionsomeMethod() { }}classchildClassextendsparentClass{    public final functionsomeMethod() { }//override parent function}$class= newchildClass;$class->someMethod();//call the override function in chield class?>
    cottton at i-stats dot net
    11 years ago
    imo good to know:<?phpclassBaseClass{    protected static$var='i belong to BaseClass';    public static functiontest()    {        echo'<hr>'.'i am `'.__METHOD__.'()` and this is my var: `'.self::$var.'`<br>';    }    public static functionchangeVar($val)    {self::$var=$val;        echo'<hr>'.'i am `'.__METHOD__.'()` and i just changed my $var to: `'.self::$var.'`<br>';    }    final public static functiondontCopyMe($val)    {self::$var=$val;        echo'<hr>'.'i am `'.__METHOD__.'()` and i just changed my $var to: `'.self::$var.'`<br>';    }}classChildClassextendsBaseClass{    protected static$var='i belong to ChildClass';    public static functiontest()    {        echo'<hr>'.'i am `'.__METHOD__.'()` and this is my var: `'.self::$var.'`<br>'.'and this is my parent var: `'.parent::$var.'`';    }    public static functionchangeVar($val)    {self::$var=$val;        echo'<hr>'.'i am `'.__METHOD__.'()` and i just changed my $var to: `'.self::$var.'`<br>'.'but the parent $var is still: `'.parent::$var.'`';    }    public static functiondontCopyMe($val)// Fatal error: Cannot override final method BaseClass::dontCopyMe() in ...{self::$var=$val;        echo'<hr>'.'i am `'.__METHOD__.'()` and i just changed my $var to: `'.self::$var.'`<br>';    }}BaseClass::test();// i am `BaseClass::test()` and this is my var: `i belong to BaseClass`ChildClass::test();// i am `ChildClass::test()` and this is my var: `i belong to ChildClass`                    // and this is my parent var: `i belong to BaseClass`ChildClass::changeVar('something new');// i am `ChildClass::changeVar()` and i just changed my $var to: `something new`                                        // but the parent $var is still: `i belong to BaseClass`BaseClass::changeVar('something different');// i am `BaseClass::changeVar()` and i just changed my $var to: `something different`BaseClass::dontCopyMe('a text');// i am `BaseClass::dontCopyMe()` and i just changed my $var to: `a text`ChildClass::dontCopyMe('a text');// Fatal error: Cannot override final method BaseClass::dontCopyMe() in ...?>
    santoshjoshi2003 at yahoo dot co dot in
    17 years ago
    The use of final keyword is just like that occurs in JavaIn java final has three uses    1) prevent class Inheritance    2) prevent method overriding or redifination of         method in subclass     3) and to declare constants  But the third point seems to be missing from the PHP I guess, as i am a java developer Currently gaining competence in PHP
    Anonymous
    15 years ago
    The behaviour of FINAL is not as serious as you may think. A little explample:<?phpclassA{     final private functionmethod(){}     }classBextendsA{    private functionmethod(){}}?>Normally you would expect some of the following will happen:- An error that final and private keyword cannot be used together- No error as the private visibility says, that a method/var/etc. is only visible within the same classBut what happens is PHP is a little curios: "Cannot override final method A::method()"So its possible to deny method names in subclasses! Don't know if this is  a good behavior, but maybe its useful for your purpose.
    Anonymous
    1 year ago
    When desiring a special class structure finalizing magic methods maybe helpful.<?phpabstract classA{   final public function__construnct(){ echo"A"; } }classBextendsA{  public function__construct(){ echo"B"; }}$b= newB();// outputs: PHP Fatal error:  Cannot override final method a\A::__construct()?>
    Baldurien
    15 years ago
    "Note for Java developers: the 'final' keyword is not used for class constants in PHP. We use the keyword 'const'."http://php.net/manual/en/language.oop5.constants.phpThis is more or less true, regardless of the fact that constant (being defined at class level or not) in PHP are only scalar (int, string, etc) while in Java they may be pure object (ex: java.awat.Color.BLACK). The only possible solution of having such kind of constant is :<?phpclassBar{...}classFoo{  public static$FOOBAR;  static function__init() {    static$init=false;    if ($init) throw newException('Constants were already initialized');self::$FOOBAR= newBar();$init=true;  }}Foo::__init();?>That said, perhaps it is useless unless PHP automatically calls the __init() method.However, one alternative that could be done in certain case is this :<?phpfunction__autoload($className) {   ... requirethe file where theclassis...  if (interface_exists($className,false)) return;  if (class_exists($className,false)) {$rc= newReflectionClass($className);     if (!$rc->hasMethod('__init')) return;$m=$rc->getMethod('__init');    if (!($m->isStatic() &&$m->isPrivate())) {      throw newException($className.' __init() method must be private and static !');    }$m->invoke(null);    return;  }  throw newException('Class or interface not found '.$className);}?>This can only work when one class is defined per file, since we are assured that __autoload() will be called to load the file containing the class.eg: test2.php:<?phpclassB{ public static$X; private static function__init() {   echo'B',"\n";self::$X= array(1,2); }}classA{  public static$Y;  private static function__init() {    echo'A',"\n";self::$Y= array(3,4);  }}?>test.php:<?phpfunction__autoload($n) {  if ($n=='A'||$n=='B') require'test2.php';  ... doour __init()trick...}var_dump(B::$X);// shows B, then array(2) (1, 2)var_dump(A::$Y);// shows NULL.?>
    add a note
    To Top
    and to navigate •Enter to select •Esc to close •/ to open
    PressEnter without selection to search using Google

    [8]ページ先頭

    ©2009-2026 Movatter.jp