How to impose contract to subclass from parent class implementation - php

If I have an interface and I want the functions in my interface to be implemented in my sub class but the parent class must implement the interface. And Sub class extends Parent Class.
Here is what I want.
interface MyInterface {
public function find();
}
class B implements MyInterface {
}
class A extends B {
}
But an error is thrown saying find() function must be added in class B.
Anyone who could enlighten me on what am I doing wrong? thanks!

Interface is a structure, which contains a set of fields and methods that have to be implemented in every class that implements this interface. If your B class implements MyInterface it means it has to implement all of its methods/fields.
interface MyInterface
{
public function find();
}
class B implements MyInterface {
public function find()
{
echo "Hello world";
}
}
Does A class have to implement this method too? I'll leave it as your homework.

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!

How to use reflection as callback in php

I have one class
Class Mainclass{}
And another class which is
Class Childclass extends Mainclass{}
Now i want to write callback in Mainclass which check if child class found with method, merge value and return?
How can i achieve using reflection?
One easy way would be to create an interface containing that method
interface XYZ
{
public function myMethod();
}
And make your child class implement it
class Childclass extends Mainclass implements XYZ
{
public function myMethod()
{
//actual implementation
}
}
Afterwards, your main class can easily check if it is implementing that interface:
class Mainclass
{
public function whatever()
{
if ($this instanceof XYZ)
{
$this->myMethod();
}
}
}
Now, I'm fairly sure it would work but I really think this is bad design: a parent class should never depend on the implementation of its child classes. However since I don't know the context in which you're working, I'll leave this here and hope it helps you anyway.

Interface and its inheritances

interface myI
{
public function myF();
}
class myTest implements myI
{
public function myF()
{
echo 'blah';
}
}
class myTest2 extends myTest
{
}
Above is a simple Interface requiring classes to implement the myF function. Now, if a class implements that interface, then all other inheritance of that class won't be require to implement it, right?
I tested:
$lists = new myTest2();
if($lists instanceof myI){
echo 'yes' . "<br />";
}
And it outputted yes.
Then I changed
Then I changed
class myTest2 extends myTest
to
class myTest2 extends myTest implements myI
and it still outputted 'yes', even though myTest2 did not implement the myF function.
Why is that?
It's extending the base class which already implements the interface and defines the method.
It is because your parent class myTest covers implementation of interface. You can overwrite implementation in myTest2.
Because myTest2 inherits myF from myTest. Implementing the interface, myTest2 already has the function inherited from myTest, so it is in check with the interface's requirements.

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