i have the following simplified code
class A{}
class B extends A{}
class C extends B{}
It is working perfectly and everything is ok, but i wanted to make sure that it's not bad practice so i googled "multiple inheritance in php" and was surprised that many posts i read said that multiple inheritance in php is not supported and the alternative is traits.
So i doubted my definition of multiple inheritance and googled a good example about it and this Multiple Inheritance: What's a good example? came up, and it is in fact exactly as what i was doing but in a different context.
can someone shed some light on the matter?
You are not using multiple inheritance, you pasted an example of polymorphism.
Multiple inheritace = multiple parents
class Animal {}
class Mammal extends Animal {} //single inheritance
class WingedAnimal extends Animal {} //single inheritance
class Bat extends Mammal extends WingedAnimal {} //multiple inheritance, not supported by PHP.
Related
Let's take the following class structure:
class A {
... has all the functionalities of A
}
class B extends A {
... has all the functionalities of A and B
}
And these two other class structures:
class C extends B {
... has all the functionalities of A and B and C
}
class D extends A {
... all the functionalities of A, and D
}
how could I create a class easily, that would gain all the functionalities of all four of my classes, if I am not allowed to modify class A or class B? Would something like this be possible with PHP?
EDIT:
The reason I would like to do this is the following, I am open for suggestions on other ways my desired outcome can be achieved:
I have a module, which has several classes on which I plan to build on, and I do not want to edit the module directly, but I would like to add functionalities potentially to multiple classes of this module (this is where class A and class B is coming from).
So to edit class A, I would create a class D, which extends it, and add new functionalities, or rewrite already added functionalities that needs rewrite in class D.
But there are multiple classes in this module, which are simmilar in structure to class B, which I would also like to potentially modify, hence my class C. But if I modified the modules class A in my class D, I would need my new class C to extend the class D instead of the class A. (hope you can still follow me:P)
No, in PHP it is not possible to inherit from multiple parents due to "Dimond Problem". In your case, this means you can extend c for the functionality of a, b & c, but you cannot extend d too. Since you cannot modify the other classes, there is not right solution here, but I'd recommend looking into traits (https://www.php.net/manual/en/language.oop5.traits.php), as these allow you to 'inherit' from multiple traits.
I have trouble understanding the import behavior. Let me explain, I have a class B outside of any namespace (for some reason I have double autoload, a proprietary one, and the classic PSR-4, I guess this can have something to do with my issue, I'm ready to gather more information on this tidbit if necessary). In this class I import a class A from a namespace, and it turns out when in a method of my children class I can use the A class to instantiate an object, but when I try to tell class B to extend class A it says the FQN is not found.
<?php
use \App\Services\AbstractController as BaseController;
class BarController extends BaseController
{
public function test() {
$foo = new BaseController();
}
}
There I would have an error on the "class BarController extends BaseController" line saying BaseController can't be found, but if I delete the extends part, the test method will run smoothly with its instantiation (I did try to manipulate the object, it sure works well).
so I guess my question is, is there any difference on the treatment of a class to extend vs. using it to instantiate an object.
Thanks in advance for your thoughts, and I'm ready to answer any additional question.
I did manage to deal with the issue. The controller class was instantiated inside the proprietary autoloader but the method was called later on the process. I switched both autoloader order (ie. first psr-4 then proprietary one) in the init and it works well.
I have 2 Abstract classes: AbstractCommentable (methods for comments) and AbstractImaging (entity methods for manage images).
Some classes already have:
class Trip extends AbstractImaging {/** some stuff **/}
class Marker extends AbstractImaging {/** some stuff **/}
class Gastronomy extends AbstractImaging {/** some stuff **/}
But I want to add AbstractCommentable to this classes...
What's the right way to do that?
You either have to make AbstractImaging already extend AbstractCommentable or other way around ... which i suggest you don't want.
Multiple inheritance can only be linear in PHP because of possible conflicts.
You can't do something like ...
class Whatever extends AbstractImaging, AbstractCommentable
The easy way:
If you're using php 5.4+ you could use a trait to add the CommentableInterface methods to your entity.
The complicated way:
create an annotation and let a doctrine-listener create a proxy class adding the commentable methods.
I haven't used abstract classes much in practice, though I understand what they are : a way to dictate to subclasses which methods must be implemented.
I just put a Kohana project through Doxygen and can see the class hierarchy in its entirety. I see that, at the top of the chain we have a factory:
abstract class Kohana_Model {
public static function factory($name){
// Add the model prefix
$class = 'Model_'.$name;
return new $class;
}
}
Inherited directly below that, we have an empty abstract class:
abstract class Model extends Kohana_Model {}
... And below that, there are three inherited classes: Kohana_Model_Database, Kohana_ORM, and Model_Foobar.
Would someone please explain the programming reasoning for this - what is the purpose of having an empty abstract class this high up in the chain? (and, at all?)
Why not have Kohana_Model_Database, Kohana_ORM, and Model_Foobar inherit directly from Kohana_Model, when there is (apparently?) no other branching or inheritance going on between Model and Kohana_Model?
Answers you're seeking for are Cascading File System and Transparent Extensions.
It allows you to create a model by calling
class News_Model extends Model
by default, and that will automatically then extend Kohana_Model and things will be hunky dory.
It also lets you extend Kohana_Model by creating your own Model file
class Model extends Kohana_Model
which overrides the abstract Model class, and allows you to add custom functionality. Then, when you upgrade your Kohana version to (say) 3.4, your extended Model doesn't get overwritten by the new Kohana files.
What are the consequences of implementing the same interface through two different routes in PHP, are there any?
What I mean, is something like this:
interface baseInterface {}
abstract class baseClass implements baseInterface { }
interface myInterface extends baseInterface {}
class myClass extends baseClass implements myInterface {}
In this case myClass implements baseInterface from two different parents - myInterface and baseClass. Are there any consequences to this? My instinct is that PHP should handle this fine, but I just want to make sure. What exactly does PHP do in this case? Does it just check to see that the necessary functions are implemented for the interface each time it discovers it and call it a day or does it do something more?
That will all work fine. You'll still have to keep them all straight in your head and documentation though :)
In other words, there are no technical concerns.