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.
Related
I've three classes lets say Class A, Class B and Class C.
Class A is parent class and class B and C are its child.
There is function in class B, I want to access that function in class C without inheriting Class C with B. Is it possible?
public class A {
}
class B extends A{
public function hello (){
return "Hello world";
}
}
public class C extends A{
public function world (){
$this->hello();
}
}
To expand upon #u_mulder's comment: it's indeed not possible, because though B and C both derive from the same class A, they are distinct classes, in the same way that a bicycle and a car are both vehicles. When using a bicycle you cannot assume to use functions from a car, simply because they're both vehicles.
The question you'd need to answer yourself is what is the functionality of the method I need in class B? Is it specific to class B? Or is it something all entities which are class A? Or different yet, is it a separately functionality altogether but which only class B needs to consume?
The solution to the first case would be to move the function to class B. In the second case you'd move the function to class A. In the third case you'd implement the function in a separate class and inject that into class B.
I recommend you read up on SOLID principles and other principles of OOP design
I've been trying to build a PDO extension, and I wanted to have special classes in different files but I wanted to have them all link to the same original class.
I have worked with some Frameworks and I see that they use the extends class keyword, and I thought that it added the class you are making to the class that you have given.
Some code I have tried is:
class PSMQuery extends PSM {
// Functions and Jargon
}
I tried making an object for the original PSM class:
$psm = new PSM(/*Information*/);
But when I call the $psm variable like $psm->functionInTheExtendedClass it comes up with an error saying that it was an undefined method when I called it.
Am I using the extends keyword incorrectly?
Am I using the extends keyword incorrectly?
You use it correctly, but it works the other way around.
If PSMQuery extends from PSM, this means you can access and use stuff from PSM in PSMQuery, but not the other way around.
I think to understand it you can use a good example:
class twoRoomApartment extends building { }
So now you can think logical and already see, that a two room apartment probably extends from a building and not the other way around.
Means now in your code, you just create an instance of PSMQuery.
It's inheritance.
Parent : PSM
Child : PSMQuery
When you use extends you are extending parent class functionality and creating child class.
Your child class will inherit all the parent class functionality.
Parent will not get child class functionality.
So when u r trying to create object of parent class it doesn't know child class functionality.
You need to create object of child class and then you can access methods from parent class.
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.
I have imported a PHP source folder into Enterprise Architect. Now, I'd like to see the inheritance chain of any specific class. In other words, I'd like to see one big diagram displaying all relations of a class. Most classes are in folders separate from the parent/child class. How can I do that..?
This was my reason for installing Enterprise Architect: I get confused within a lengthy and branched inheritance chain. It would be very disappointing if such a powerful tool that recognizes all relationships could not give an overview of these relationships.
For example, I can see a class diagram in the root of one folder, illustrating aggregation. However, the aggregated classes listed are only those located in the same folder as the parent class.
Thank you in advance.
This answer applies to EA 9.3. I don't have an old EA 8 lying around but EA is eminently backwards-compatible, so you should upgrade in any case.
There are a couple of ways to follow inheritance chains in EA.
Method 1: add classes to the same diagram.
In a diagram containing the root class of your inheritance hierarchy, right-click the root class and select Add - Related Elements. In the "Insert Related Elements" dialog, select the length of chain ("levels") you want, up to a maximum of 5. Specify "link type" Generalization. You can leave the other options as they are, or play around with them if you like.
This will cause EA to add those classes to the diagram which inherit from the root class in up to 5 steps/levels. You don't have to start from a root class; the option "link direction" in the dialog controls whether relationships should be followed in one or both directions.
You can use this same function to add classes related through other relationships, such as aggregations.
Method 2: Use the Traceability window.
In the main menu, select View - Traceability. This opens the Traceability window, which is a tree view with the currenty selected element at the top, and nodes for all related elements in a hierarchy.
Select the root class and violĂ , all its inheriting classes are shown as child nodes in the Traceability window, and you can expand them in turn to follow the chains further.
Method 1 puts the information in diagrams, where it is kept and needs to be updated. Method 2 is dynamic and more usefu when you need to check a specific relationship chain.
The relationships in a diagram are automatically updated if the underlying model changes, so if for instance you change the code and reimport it, this will be reflected in the diagram. To be on the safe side, always work with manually created diagrams in a separate package from the source package.
Am not sure if there is existing solution but is something you can easily implement using ReflectionClass and Google Graph
Example
class A {
}
class B extends A {
}
class C extends B {
}
class D extends C {
}
class E extends D {
}
class F extends E {
}
function getPath($className) {
$class = new ReflectionClass($className);
$name = $class->getParentClass();
if ($name) {
echo $class->getName(), " extends ";
getPath($name->getName());
} else {
echo $class->getName();
}
}
getPath("C");
getPath("F");
Output
C extends B extends A
F extends E extends D extends C extends B extends A
class A extends B {}
class B extends C{}
class C {}
result
PHP Fatal error: class 'B' not found ...
if the order is like this
class A extends B {}
class C {}
class B extends C{}
everything is ok.
PS: if I remove class C {}
class A extends B {}
class B extends C{}
php tells me class 'B' is not found, why?
php version 5.3.4
The PHP manual clearly mentions:
Classes must be defined before they
are used! If you want the class
Named_Cart to extend the class Cart,
you will have to define the class Cart
first. If you want to create another
class called Yellow_named_cart based
on the class Named_Cart you have to
define Named_Cart first. To make it
short: the order in which the classes
are defined is important.
clearly a parser bug
this works
class A extends B {}
class B {}
this doesn't
class C extends D {}
class D extends E {}
class E {}
consider reporting on bugs.php.net
Class order matters in PHP definitions.
Does the order of class definition matter in PHP?
This is why you don't have visibility of the class defined after the one you are defining (in this case class A cant see class B because it is defined after).
Because php is interpreted rather than compiled the order of declaration must be valid. In this example class B doesn't exist for A to extend.
Obivously class B is not defined in the moment you trying to extend it, because it occurs after extends B. Its not a bug, its the way the world works: You can only use, what exists ;)