PHP OOP - Overriding class methods

Last revision:

Overview

When you define a child class that extends a parent class, the child class inherits all properties and methods from its parent class.

You can add as many properties and methods as you want in your child class, but you can also override them to change their implementation (in the case of methods) or initial value (in the case of constants).

Overriding class methods

To override a parent method, redefine the method in the child class and use the same function signature: the same name, the same parameters, and the same return type.

Example

Code
<?php

class Animal {

  public function move() {
    print("This animal is moving...");
  }

}

class Bird extends Animal {

  public function move() {
    print("This animal is flying. Flap flap flap...");
  }

}

$eagle = new Bird();
$eagle->move();

Activity

In the previous Animal / Bird example, what do you expect will be the output of $eagle->move()?

Answer / solution

"This animal is flying. Flap flap flap..."

If the Bird class had not overridden the move() method, $eagle->move() would have executed the parent's move() method instead of its own move() method.

Calling the parent method from the child class

You can call the parent constructor from your child constructor using parent::__construct().

In fact, when you are overriding any parent method, you can still call the parent method from the child class using parent::name_of_the_method():

Code
<?php

class Animal {

 public function move() {
   print("This animal is moving... ");
 }

}

class Bird extends Animal {

 public function move() {
   parent::move();
   print("Flap flap flap..." . PHP_EOL);
 }

}

class Fish extends Animal {

 public function move() {
   parent::move();
   print("Splash splash splash..." . PHP_EOL);
 }

}

$eagle = new Bird();
$eagle->move();

$finn = new Fish();
$finn->move();

Output:

This animal is moving. Flap flap flap...
This animal is moving. Splash splash splash...

This pattern is interesting to use if you want to extend a parent method without duplicating all of its code. 

Overriding class constants

You can override constants as well as methods by redefining them in your child class:

Code
<?php

class Figure {

 const NUM_SIDES = 3;

}

class Octahedron extends figure {

 const NUM_SIDES = 8;
 
}

$octo = new Octahedron();
print ($octo::NUM_SIDES);

// Output: 8.

Final: preventing overridden methods or constants

In certain situations you might want to completely prevent classes from being extended, or prevent child classes from overriding certain parent methods or constants.

You can use the final keyword to do so:

Example: final class

The following example defines an Animal class that is marked as final, and a Fish class that attempts to extend from Animal.

This code will result in an error.

Code
<?php

final class Animal {

 public string $name;

 public function __construct($name) {
   $this->name = $name;
 }

 public function move() {
   print("{$this->name} is moving." . PHP_EOL);
 }

}

class Fish extends Animal {

 public function move() {
   print("{$this->name} is swimming." . PHP_EOL);
 }

}

$myfish = new Fish('Nemo');
$myfish->move();

Output:

Fatal error:  Class Fish cannot extend final class Animal.

Example: final method

In the following example, the Animal class itself is no longer final, but we've made the move() method final.

This code will also result in an ERROR, but a different one.

Code
<?php

class Animal {

 public string $name;

 public function __construct($name) {
   $this->name = $name;
 }

 final public function move() {
   print("{$this->name} is moving." . PHP_EOL);
 }

}

class Fish extends Animal {

 public function move() {
   print("{$this->name} is swimming." . PHP_EOL);
 }

}

$myfish = new Fish('Nemo');
$myfish->move();

Output:

Fatal error:  Cannot override final method Animal::move()

Example: final const

Lastly, you can also make consts final. You would do this if you are absolutely certain that the const should never have any other value than the one you provide in your class definition.

The following code will result in an ERROR:

Code
<?php

class Circle {
 final const PI = 3.1415927;

 public function __construct (int $radius) {
   $this->radius = $radius;
 }
 public function calculateCircumference(): float {
   return 2 * self::PI * $this->radius;
 }
}

class MyCircle extends Circle {
 const PI = 3.14;
}

$mycircle = new MyCircle(5);
print $mycircle::PI;

Output:

Fatal error: MyCircle::PI cannot override final constant Circle::PI

Summary

  • Child classes can override their parent's methods and constants.
  • From within a class, use self::NAME_OF_CONST to access a constant.
  • From outside a class, use $myobject:NAME_OF_CONST:
  • If a child class overrides a parent's methods or constants, the parent's methods or constants can still be called directly via the parent:: syntax.
  • Use the final keyword to:
    • completely prevent a class from being extended
    • prevent a method from being overridden
    • prevent a const from being overridden