PHP, OOP, Different formulation - php

I am studying the differences between Abstract and Interface and I read some sentence
saying
A child class can only extend a single abstract (or any other) class,
whereas an interface can extend or a class can implement multiple
other interfaces.
I understand when he says, “A child class can only extend a single abstract (or any other) class,” he means:
class first
{
public function Search()
{
return 'Hellow';
}
}
abstract class first2 extends first
{
}
class second extends first2
{
}
$ob = new second();
echo $ob->Search();
However, I didn’t understand the rest of his sentence, where he says, “whereas an interface can extend or a class can implement multiple other interfaces.”
Could someone please explain his last sentence and add a code example?
Thank you all and have a nice day.

You can implement more than one interface
interface C {
public function method1();
}
interface D {
public function method2();
}
class A implements C,D {
//implement from interface C
public function method1() {
}
//implement from interface D
public function method2() {
}
}
Here you will need implement methods from interface C and D. You can also extend interfaces within interfaces, like normal classes.
interface D extends C{}
It's useful when well you need some common methods. so you write "schema" into interface what methods you are expecting from base class to be implemented.
While abstract is single extended class, you canot create instance for it, only extend. It's useful when you want have some base class with common functionality or abstract methods what should be implemented later.
More you can always read at php.net - interfaces

Related

Declaring abstract the method implemented from an interface

I wonder if it is possible to not implement a method coming from an interface and let child class do it.
For example :
abstract class Foo implements Bar
{
public abstract methodFromBar();
}
And then :
class SubFoo extends Foo
{
public methodFromBar()
{
// Implementation...
}
}
The idea behind this is to simplify development and just specifying that the subclass extends from the main class instead of writing again that the subclass implements the interface.
You don't need to mention the interface method in the parent class at all. If it doesn't implement the interfaces listed, then PHP will require that the subclass fulfills the contract instead. This will work fine:
interface Bar
{
public function methodFromBar();
}
abstract class Foo implements Bar
{
}
class SubFoo extends Foo
{
public function methodFromBar()
{
echo 'Hello world';
}
}
$subFoo = (new SubFoo)->methodFromBar();
// Hello world
See https://eval.in/1016337
If the subclass does not implement the method, you'll receive a message along the lines of
Fatal error: Class SubFoo contains 1 abstract method and must therefore be declared abstract or implement the remaining methods (Bar::methodFromBar)
Whether or not you think it's a good idea for an abstract class to implement an interface is probably a discussion for another site.

When do we should use abstract function or normal function in base class in PHP?

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!
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.
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!

Difference between abstract class extends and normal class extends

Is there any clear difference why to use abstract for extends if we can do same in with the normal class excepts it doesnt provide the contract for eg.
abstract class Survivalneeds {
abstract public function eat(); // everyone eats but different foods which would probably work as contract
public function breathe() {
// everyone inhale o2 exhale co2 only for animals
}
}
Now
class human extends Survivalneeds {
protected function eat() {
//sometimes eat goat
// contract
}
breathe()// already extending having same functionality inhale o2 and exhale co2
}
class goat extends Survivalneeds{
protected function eat() {
//wee eat greens
// contract
}
breathe()// already extending having same functionality inhale o2 and exhale co2
}
Now the same functionality can be granted by normal class by extending except the contract method and for contract we could use interface also.
What you are saying its correct inheritance works in both cases but the idea of an Abstract class is that its some common logic shared by x classes that extend this functionality but that is not instantiable by it self because it doesn't make sense (maybe you want only to have types of cars in your system but not a generic car that doesn't have a brand)
Also if you will use regular class and interface you will be forced to create stub in a class in order to follow the contract. So you will be able to create the instance of the class. And just imagine you will use this common function in your upper class.
interface Crashable{
function crash();
}
class Car implements Crashable{
function crash(){}
function getCrashParams(){
return $this->crash();
}
}
class Volvo extends Car{
function crash(){
parent::crash(); // will be OK that it's not right
//.. specific params
return $params;
}
}
class Saab{
function crash(){
//.. specific params
return $params;
}
}
$car = new Car(); // will be ok, that it's not right
//getCrashParams() function in a Car will use the local version of the crash() and not the function of it's child that will kill the data flow
You should use an interface whenever you have a need for a contract. You should use abstract class in case there's a common functionality for some simmilar classes and you don't want to repeat the code (DRY :). Of course, it is always better to use composition, but this is not the time for this discussion :)
The problem with your code (with Survivalneeds class) is the fact the class from one side is responsible for the contract (breathe and eat methods) and from another is responsible for providing common functionality. You could change your code in following way:
interface Survivor {
public function eat();
public function breathe();
}
abstract class Survivalneeds implements Survivor {
public function breathe() {
// method's body
}
}
With such implementation responsibilities are splitted. Also it is clear that all classes that will extend Survivalneeds will need to as well fulfill Survivor contract.

PHPStorm 9 inspection of class inheritance works unexpectable

I'm facing the following issue in PHPStorm 9:
Say I have an interface FieldInterface that has some methods:
namespace Acme;
interface FieldInterface {
public function methodA();
public function methodB();
}
then I have an abstract class that implements base functionality of the interface. That abstract class has the user to implement certain methods, let's say it's methodB in our example:
namespace Acme;
abstract class AbstractField implements FieldInterface {
public function methodA() {
// implement methodA
}
public abstract function methodB(); // have the user implement it
}
And finally I have some ready-to-use class StringField:
namespace Acme;
class StringField extends AbstractField {
public function methodB() {
// implement methodB
}
}
At this point everything's going well. But if I add new method in the FieldInterface, PHPStorm does not say that anything is wrong with AbstractField while it's obvious that I should add public abstract function newMethod(); in there. However, it spots the error in StringField class instead.
It could be understood from the point that abstract classes are made for the purpose of extention, but usually you extend the abstract class rather than implement underlying interface. The whole meaning of making abstract class is to save user's time for implementing the interface. So why PHPStorm forces me to implement interface in concrete class rather than forcing me to implement it in abstract class that is explicitly implements the interface.
So I wonder if it is a bug in PHPStorm, or maybe it's done on purpose. Either way, is there any workaround?
That's how it should be, showing an error in the abstract class would be wrong.
In fact, public abstract function methodB(); is redundant because the abstract class already "inherits" this abstract method from the interface as it does not implement it.
The only workaround is to make AbstractField not abstract.

Propagating a function to parents

I have a PHP object that consists of a set of classes. For sake of simplicity lets call it an object of class C that extends class B which in its turn extends class A. At some point in my code I want to clean up the object by calling its doCleanup() function which it inherits from interface I:
interface I { public function doCleanup(); }
class A implements I { ... }
class B extends A { ... }
class C extends B implements I { ... }
In the doCleanup function in class C I want to also execute any cleanup function in my parent classes (in this case, the doCleanup() in class A). However, for some objects I am not sure whether any of the parent classes actually implement interface I, so I am not sure whether I can simpley call parent::doCleanup().
My question therefore is if there is a way to check whether any of my ancestors implement the interface for example by using some sort of instanceof call?
You can do this nicely with get_parent_class and is_subclass_of (which works for interfaces as well as parent classes):
<?php
interface I {
public function doCleanup();
}
class A implements I {
public function doCleanup() {
echo "done cleanup\n";
}
}
class B extends A {}
class C extends B implements I {
public function doCleanup() {
if (is_subclass_of(get_parent_class($this), 'I')) {
parent::doCleanup();
}
}
}
$c = new C;
$c->doCleanup(); // outputs "done cleanup"
Since class C extends B, and B extends A, and A is required to implement doCleanup, then logically you can call parent::doCleanup() in C and it will work. If B does not implement it, it will be passed up to A, which must implement it. More accurately, B will run it, using A's implementation.
If you didn't know whether A implemented I or not, then it wouldn't necessarily be your responsibility to call it. If it were library code, for example, docs might tell you what you should do.

Categories