PHP LogoInheritance

Inheritance is one of the fundamental principles of Object-Oriented Programming (OOP) that allows a new class (child class or subclass) to inherit properties and methods from an existing class (parent class, superclass, or base class). This mechanism promotes code reusability, reduces redundancy, and establishes a hierarchical "is-a" relationship between classes.

Key Concepts:
* Parent Class (Superclass/Base Class): The class whose properties and methods are inherited.
* Child Class (Subclass/Derived Class): The class that inherits from the parent class. It can extend the functionality of the parent class by adding new properties and methods or by overriding existing ones.

How Inheritance Works in PHP:
In PHP, inheritance is achieved using the `extends` keyword. A child class can extend only one parent class (PHP supports single inheritance).

When a child class extends a parent class:
1. Property Inheritance: All `public` and `protected` properties of the parent class are inherited by the child class. `private` properties are not directly accessible from the child class but can be accessed via `public` or `protected` methods inherited from the parent.
2. Method Inheritance: All `public` and `protected` methods of the parent class are inherited by the child class. `private` methods are not inherited.
3. Method Overriding: A child class can provide its own implementation for a method that is already defined in its parent class. This is known as method overriding. When an object of the child class calls that method, the child's version is executed.
4. Constructor Inheritance: If a child class does not define its own constructor, it inherits the parent's constructor. If a child class defines its own constructor, it must explicitly call the parent's constructor using `parent::__construct()` if it wishes to execute the parent's initialization logic.
5. Access Modifiers:
* `public`: Members are accessible from anywhere. Inherited and fully accessible by child classes.
* `protected`: Members are accessible within the class itself and by all its child classes.
* `private`: Members are accessible only within the class where they are defined. They are not accessible by child classes (though they exist within the object's memory).
6. The `final` Keyword: The `final` keyword can be used with classes or methods.
* `final class MyClass`: Prevents other classes from inheriting from `MyClass`.
* `final public function myMethod()`: Prevents child classes from overriding `myMethod()`.

Benefits of Inheritance:
* Code Reusability: Common logic can be placed in a parent class and reused across multiple child classes.
* Maintainability: Changes to shared logic only need to be made in one place (the parent class).
* Extensibility: New functionalities can be added to existing systems by creating new child classes without modifying the parent.
* Polymorphism: Allows objects of different classes to be treated as objects of a common parent class, enabling more flexible and generic code.

Example Code

<?php

// Parent Class (Superclass)
class Animal {
    // Public property accessible everywhere
    public $name;
    // Protected property accessible within the class and by child classes
    protected $species;

    // Constructor for the Animal class
    public function __construct(string $name, string $species) {
        $this->name = $name;
        $this->species = $species;
        echo "A new animal named {$this->name} ({$this->species}) has been created.\n";
    }

    // Public method
    public function eat() {
        echo "{$this->name} is eating.\n";
    }

    // Public method, intended to be overridden by child classes
    public function makeSound() {
        echo "{$this->name} makes a generic sound.\n";
    }

    // Protected method, only accessible by the class itself and child classes
    protected function getSpeciesInfo() {
        return "This is a {$this->species}.";
    }

    // Public method to expose protected method's result
    public function describe() {
        echo "{$this->name}. " . $this->getSpeciesInfo() . "\n";
    }
}

// Child Class (Subclass) - Dog inherits from Animal
class Dog extends Animal {
    // New property specific to Dog
    public $breed;

    // Dog's constructor, overrides Animal's constructor
    public function __construct(string $name, string $species, string $breed) {
        // Call the parent constructor to initialize inherited properties ($name, $species)
        parent::__construct($name, $species);
        $this->breed = $breed;
        echo "And it's a {$this->breed} dog.\n";
    }

    // Method Overriding: Dog provides its own implementation for makeSound()
    public function makeSound() {
        echo "{$this->name} barks: Woof! Woof!\n";
    }

    // New method specific to Dog
    public function fetch() {
        echo "{$this->name} is fetching!\n";
    }

    // Accessing a protected method from the parent class
    public function showDogDetails() {
        echo "{$this->name} is a {$this->breed}. " . $this->getSpeciesInfo() . "\n";
    }
}

// Another Child Class - Cat inherits from Animal
class Cat extends Animal {
    public function __construct(string $name) {
        // Cats are generally 'Feline', so we pass it to the parent
        parent::__construct($name, "Feline");
        echo "It's a lovely cat.\n";
    }

    // Method Overriding
    public function makeSound() {
        echo "{$this->name} meows: Meow!\n";
    }

    // New method specific to Cat
    public function scratch() {
        echo "{$this->name} is scratching the furniture!\n";
    }
}

echo "--- Creating a Dog object ---\n";
// Create an object of the Dog class
$myDog = new Dog("Buddy", "Canine", "Golden Retriever");
$myDog->eat();         // Inherited method
$myDog->makeSound();   // Overridden method
$myDog->fetch();       // Dog-specific method
$myDog->describe();    // Inherited method that uses a protected method
$myDog->showDogDetails(); // Dog-specific method that uses a protected method from parent

echo "\n--- Creating a Cat object ---\n";
// Create an object of the Cat class
$myCat = new Cat("Whiskers");
$myCat->eat();         // Inherited method
$myCat->makeSound();   // Overridden method
$myCat->scratch();     // Cat-specific method
$myCat->describe();    // Inherited method

echo "\n--- Accessing properties ---\n";
echo "Dog's name: " . $myDog->name . "\n"; // Public property
// echo "Dog's species: " . $myDog->species . "\n"; // This would cause a fatal error as 'species' is protected.
echo "Dog's breed: " . $myDog->breed . "\n"; // Public property specific to Dog

?>