1

So I have a question about the difference between "when we should declare normal function" and "when we should declare abstract function" in base class. Look at my example.

In the abstract class:

abstract class Birds {
    abstract public function fly();
}

class Swallow extends Birds {
    public function fly() {
        // This function override fly function in Birds class
        echo "Implement fly function in Swallow class";
    }
}

In the normal class:

class Birds {
    public function fly() {
        echo "Implement fly function in Birds class";
    }
}

class Swallow extends Birds {
    public function fly() {
        // This function override fly function in Birds class
        echo "Implement fly function in Swallow class";
    }
}

What you can see. The fly function in Swallow class is inherited by Birds class (in all cases). They are a same thing. So I'm embarrassed and I dont know when we should declare abstract function in base class?

Thanks for your help!

Duy Trần
  • 204
  • 3
  • 15
  • 2
    Possible duplicate of [PHP - if all methods in abstract class are abstract then what is the difference between interface and abstract class](http://stackoverflow.com/questions/37437633/php-if-all-methods-in-abstract-class-are-abstract-then-what-is-the-difference) – Ali May 31 '16 at 06:12

2 Answers2

3

Taken from PHP OOP Class Abstraction:

When inheriting from an abstract class, all methods marked abstract in the parent's class declaration must be defined by the child; additionally, these methods must be defined with the same (or a less restricted) visibility. For example, if the abstract method is defined as protected, the function implementation must be defined as either protected or public, but not private.

This is essentially saying that your Swallow class has to inherit (have) the fly() method in it if it extends the Bird class based off of its abstract definition.

The general rule of thumb when harnessing abstract methods is when you want normality among classes.

Take the following for example:

Class Car {

    abstract public function make();
    abstract public function model();
}

This is our "base" class. Anything that extends from this has to specify the make() & model() methods.

Class Tesla extends Car {

    public function make() {}

    public function mmodel() {}
}

As you see above, our Tesla class has the required methods within. If you do not include these methods, you'll have PHP errors thrown.


Note

If you're exploring this option of "container" like development, then I'd suggest that you have a good look at PHP OOP Object Interfaces too, well worth it!

Darren
  • 13,050
  • 4
  • 41
  • 79
3

Abstract functions are actually only an interface. E.g. there's no difference in your example between abstract class and if it would be an interface (that's because there's only abstract method).

//abstract class
abstract class Birds {
    abstract public function fly();
}
//interface
interface Birds {
    public function fly();
}

That's because abstract methods have the same purpose that interface's method. When you somewhere else create a function (or method or a class or another interface etc.), and you will require any Birds instance, you will be sure you have that abstract method avaiable, although it was not implemented in Birds.

public function sendBirdToSpace(Birds $bird) { //no matter what Bird subclass
    $bird->fly(); //you're sure this method is avaiable
} 

Also usually you will have more than one child class. When it comes to that, it's getting more clear about abstract method.

It's actually pretty simple. Should Birds have a default behaviour implementation of flying? That's all. If every bird should can fly, but there's no default method - make it abstract.

Jakub Matczak
  • 15,341
  • 5
  • 46
  • 64
  • Hi @dragoste, It's really a good explanation. Thanks so much. But I have a question in your explanation. What happen If I declare a Penguin class? They can not fly but the flying function is had to defined in Penguin class. So I'm really embarrassed when I analyze this class. – Duy Trần May 31 '16 at 06:32
  • 1
    I thought the same thing. That's why I said ***if** every bird should can fly*. Alternatively if it's just an exception from the rule, use can throw Exception('Not implemented'), but in this case you have to be prepared to handle this exception anywhere use invoke `fly()`. Another way to handle it could be to use interfaces. Here it would be `FlyingBird` interface that has method `fly()`, and this method would not be in `Birds` class anymore. – Jakub Matczak May 31 '16 at 06:34