<?php
class parentClass {
public function someMethod() { }
}
class childClass extends parentClass {
public final function someMethod() { } //override parent function
}
$class = new childClass;
$class->someMethod(); //call the override function in chield class
?>
Palavra-Chave 'final'
PHP 5 introduz a palavra-chave 'final', que previne que classes filhas sobrecarreguem um método. Basta prefixar a definição com 'final'.
Exemplo #1 Exemplo de métodos 'final'
<?php
class ClasseBase {
public function teste() {
echo "ClasseBase::teste() chamado\n";
}
final public function maisTeste() {
echo "ClasseBase::maisTeste() chamado\n";
}
}
class ClasseFilha extends ClasseBase {
public function maisTeste() {
echo "ClasseFilha::maisTeste() called\n";
}
}
// Resulta em erro Fatal: Não pode sobrescrever método final ClasseBase::maisTeste()
?>
Exemplo #2 Exemplo de classe Final
<?php
final class ClasseBase {
public function teste() {
echo "Método ClasseBase::teste() chamado\n";
}
// Aqui não importa se você especificar a função como Final ou não
final public function maisTeste() {
echo "Método ClasseBase::maisTeste() chamado\n";
}
}
class ClasseFilha extends ClasseBase {
}
// Resulta em erro Fatal: A classe ClasseFilha não pode herdar de uma classe Final (ClasseBase)
?>
Nota: Propriedades não podem ser definidas como fina, apenas classes e metodos podem ser declarados como final.
slorenzo at clug dot org dot ve ¶
5 years ago
Anonymous ¶
2 years ago
The behaviour of FINAL is not as serious as you may think. A little explample:
<?php
class A {
final private function method(){}
}
class B extends A {
private function method(){}
}
?>
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 class
But 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.
santoshjoshi2003 at yahoo dot co dot in ¶
4 years ago
The use of final keyword is just like that occurs in Java
In 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
jriddy at gmail dot com ¶
3 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
penartur at yandex dot ru ¶
6 years ago
Note that you cannot ovverride final methods even if they are defined as private in parent class.
Thus, the following example:
<?php
class parentClass {
final private function someMethod() { }
}
class childClass extends parentClass {
private function someMethod() { }
}
?>
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.
Baldurien ¶
2 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
This 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 :
<?php
class Bar {...}
class Foo {
public static $FOOBAR;
static function __init() {
static $init = false;
if ($init) throw new Exception('Constants were already initialized');
self::$FOOBAR = new Bar();
$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 :
<?php
function __autoload($className) {
... require the file where the class is ...
if (interface_exists($className, false)) return;
if (class_exists($className, false)) {
$rc = new ReflectionClass($className);
if (!$rc->hasMethod('__init')) return;
$m = $rc->getMethod('__init');
if (!($m->isStatic() && $m->isPrivate())) {
throw new Exception($className . ' __init() method must be private and static !');
}
$m->invoke(null);
return;
}
throw new Exception('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:
<?php
class B {
public static $X;
private static function __init() {
echo 'B', "\n";
self::$X = array(1, 2);
}
}
class A {
public static $Y;
private static function __init() {
echo 'A', "\n";
self::$Y = array(3, 4);
}
}
?>
test.php:
<?php
function __autoload($n) {
if ($n == 'A' || $n == 'B') require 'test2.php';
... do our __init() trick ...
}
var_dump(B::$X); // shows B, then array(2) (1, 2)
var_dump(A::$Y); // shows NULL.
?>
Kiam ¶
3 years ago
The final keyword doesn't change the visibility of a property / method, which is public by default.
sunil dot boodram at gmail dot com ¶
4 years ago
Using the scope resolution operator, we can easily access constants, static variables, public functions and final functions from Final Classes
Note: even by omitting the "public" keyword from the "nightNews()" method, we can see that the function defaults to public even if prefixed with the keyword final.
<?php
final class news{
const micCheck = "test1"; // will work
static public $promptCheck = "test2"; //will work
//will work
public function morningNews(){
print 'good morning world!';
}
//will work
final public function eveningNews(){
print 'good evening world!';
}
//will work
final function nightNews(){
print 'good night world!';
}
}
print news::micCheck; // output: test1
print '<br/>';
print news::$promptCheck; // output: test2
print '<br/>';
print news::morningNews(); // output: good morning world!
print '<br/>';
print news::eveningNews(); // output: good evening world!
print '<br/>';
print news::nightNews(); // output: good night world!
?>
