Lets say I have a parent class
class parent { }
.....
This parent has three sub class
class child1 { }
class child2 { }
class child3 { }
and these child classes have further smaller parts like
class child1subpar1 { }
class child1subpar2 {
public function foo() {
echo "hi";
}
}
class child2subpar1 { }
class child2subpar2 { }
Now, how to sum this whole up like
class child1 extends child1subpar1, child1subpar2 { }
class child2 extends child2subpar1, childsubpar1 { }
class parent extends child1,child2,child3 { }
I need to execute the methods in its inherited classes and do something like this
$objparent = new parent;
$objparent -> foo();
No, but multiple inheritance is generally considered a bad practice. You should favor composition instead, so you just use instances of classes you wanted to inherit inside your class.
And now when I look into your question again, it's not even an inheritance issue, you should use composition. Maybe if you provided more detail what you expect that class to do, we should answer more accurately.
UPDATE:
You will need to create one method for each of these classes' method which you would want to use - it's called Facade design pattern. Or maybe you are not aware that you can call methods of inner objects like this:
$parent->subObject->subSubObject->wantedMethod();
Facade pattern:
http://en.wikipedia.org/wiki/Facade_pattern
in your case facade wouldn't be anything else than creating one class and define every single method you want to use, and inside that method calling any method of any of your inner instances. But i really don't see any benefit coming from this instead of calling
instances and methods hierarchically
Seems like you're really confused about OOP.
Parent class has no awareness of its children. If you want to execute a child class, you need to create its instance.
Multiple inheritance is also not allowed in PHP (as well as many other popular languages like Java).
It might be worth looking at aggregation - passing smaller sub classes into child or event parent class. also, you can use implement multiple interfaces to force subclasses to have a set of required methods.
What you're doing is really backwards. Inheritance is used to bestow common, shared functionality upon objects without code duplication. The inheritance goes from Parent to Child, everything the Parent can do, the Child can do as well, but it may do more (it extends the functionality of the parent).
class Parent {
function everyoneCanDoThis() { }
}
class Child extends Parent {
// I can implicitly use the everyoneCanDoThis() function
function onlyChildrenCanDoThis() { }
}
Since this is a top-down structure, the Parent should not rely on any specific Child. The Parent does not execute or call functions of a Child. Only you call functions of a Child, but these functions may be inherited from a Parent class.
You should put everything you want every object to be able to do in a Parent class. Specific functionality that's only relevant to a specific object goes into a Child.
Multiple inheritance is a different can of worms that's not possible in PHP, for good reasons. Come back to composition, as suggested elsewhere here, when you get the basics of inheritance. :)
Composition just means that you take several objects and hold references to them in another object. It has nothing to do with inheritance, as each of these objects may or may not inherit from a Parent class and they're still individual objects.
class ComposedObject {
private $part1 = null;
private $part2 = null;
public function __constructor() {
$this->part1 = new Part1();
$this->part2 = new Part2();
}
public function doTask() {
return $this->part1->doSomeTask();
}
public function doOtherTask() {
return $this->part2->doSomeOtherTask();
}
}
The ComposedObject does not have any functionality itself, inherited or otherwise. But it holds two other objects that each carry some functionality. The functionality in the "parts" may be exposed directly, so they're called like $composedObject->part1->doSomeTask(), they may be encapsulated as in the example, so they're called like $composedObject->doTask() and are internally delegated, or you may use some __call() trickery to automatically delegate functions called on the composed object to one of its "parts". This has the same problem as multiple inheritance though; if two "parts" both contain a method of the same name, which one do you call?
+1 to the others. You really have it backwards. Children ALWAYS extends their parents.
But there is even something that can act kind of like multiple inheritance in PHP: The Decorator Pattern.
I wrote an article about it on my blog here.
A class can implement more than one interface, which is a slightly different thing.
When you inherit from a parent, you get everything it has unless you choose to override something, plus you can extend it by adding additional more specific stuff, but the parent should not know anything about the child.
When you implement an interface, the interface defines methods but it doesn't implement them. It is up to you to implement it. Different classes can implement the interface methods however they want as long as they follow what the interface says.
Inheritance tends to be overused and leads to bad programs. Perhaps if you told us what problem you're trying to solve, one of us could suggest how you can structure your classes.
Using Interface in Php maybe solve the question.
Related
I'm trying to make a parent class and child classes, lets say the parent class is called functionality and has functions like add(), validate(), and delete(), and the child classes are driver and passenger , each of the child classes inherit the functions but needs extra parameters and different logic for each inherited function, should I define the function but leave it blank? how is this helpful apart from extendibility?, and should I define a different constructor for each child class because they have different extra variables?
class functionality
class functionality{
protected $from;
protected $to;
protected $date;
protected $name;
public function add(){
}
public function validate(){
}
public function delete(){
}
}
class driver
class driver extends functionality {
private $gasMoney
function add($from, $to, $date, $name, $gasMoney){
//some logic and adding to database
}
}
class passenger
class passenger extends functionality {
private $seatPrefrance
function add($from, $to, $date, $name, $seatPreferance){
//different logic than class driver and
}
}
is this an acceptable approach? and how would I define a constructer? should I define it in the parent class? does the child classes inherit it and can add more to it?
You shouldn't use inheritance for this, it doesn't make sense.
The main idea is that other parts of your application can receive an object, and they don't care if it's a passenger or driver, they just get some instance of functionality and call add on it.
Another reason to use inheritance if you want to take advantage of some shared behavior, so you don't have to reimplement a method.
If arguments are different based on the sub-class, there's no way anything can do something with the generic functionality class, so this is pointless.
You also can't re-use the method, because you are clearly overriding the method for each case.
Think about driver and passenger. Are there parts in your application that need to work with both? What is their actual common functionality? Anything that's not common does not go in the base class.
I know this is probably a contrived example, but it also doesn't make sense to 'add' a passenger name to an existing passenger.
If you call your class 'passenger', I would expect that to represent a single passenger, not multiple.
Learn OOP as a tool, not a religion.
If you meet an inspiring preacher, they might teach you a whole new way of thinking about the world, and suddenly you see everything in a new light. You change your diet, your daily routine, and which TV programs you watch.
If you are given a new drill as a present, you might get some scrape wood to test it out a few times, but after that you'll wait until you need to put some shelves up. You won't work out how you can pour milk through a newly drilled hole in your breakfast counter.
The example you have come up with is trying to do OOP for OOP's sake. It doesn't make any sense, because you haven't actually got a problem you're trying to solve.
In particular, don't pull out the inheritance drill until you need it. Start off by looking for ways to encapsulate state in private properties and define behaviour that is more than just accessing that state. As a silly example, $driver->canLegallyDrive() method might internally check the $insurance and $alcoholLevel properties.
Even when you find logic you want to share, composition (just storing one object in a private property of another one) is often better than inheritance. Inheritance really comes into its own when you need polymorphism - multiple objects which look the same on the outside but behave differently on the inside. And even then, learning to use interfaces rather than base classes will unlock more potential.
I have an application in which a number of objects are all extending an abstract class which defines methods like create() edit() retrieve() and delete(). Since each of the child classes use the same logic for these functions, the abstract class defines that default behaviour, and in the few cases where it needs to be augmented, the child classes can override or use the hooks I've built in.
Now I'm having the situation where some of the child classes need to be made immutable, meaning that they shouldn't have edit() or delete() methods. This need sounds to me like a job for an interface named something like immutable which the immutable classes could implement. Problem is that interfaces don't stop methods from being called, they just enforce a method's existence. So this is obviously not going to work.
Making two parent classes, one for mutable objects and one for immutable ones is ugly and is probably asking for problems down the line which maintenance. I could have the immutable objects override the offending methods with an empty method that did nothing, but that also seems messy and like I'm not doing proper OOP at that point.
So what would you suggest as the best way to allow a large set of classes to all inherit a set of methods, but for some of them to not inherit all of the methods? (The application in question is written php, but general OOP techniques from any language can still be helpful).
create an immutable-base class as a child of the base class.
the immutable-base should implement final overrides of edit() and delete() which do nothing or throw an error.
Final, so that all immutable children are guaranteed not to be able to edit or delete
bonuses of this strategy
easily check if an object is immutable by testing for instanceof immutable-base
easily change objects from immutable and back again by modifing what it extends
Actually creating classes that have empty methods or throw errors is bad - such methods are confusing, they take up space and do nothing.
A better approach would be to make the immutable class the base class and make the mutable class extend it with adding methods for modification. This way each class has only those methods, that really belong there.
I like Java's approach to this. Throw an exception. Create an UnsupportedOperationException and for those implementations that shouldn't use a specific method throw one to let the user know they can't use this functionality for this implementation.
Another thought I wanted to throw out as a possible solution. Classes could implement an interface that looks like the following:
Interface Immutable {
const immutable = true;
}
and then the Base abstract class can write the delete() and edit() methods with
if (!$this->immutable) {
//do_stuff
}
This would also extend well to other classifications of class, like NonDeletable and NonEditable to allow for more fine grained behaviour.
Here is super short workaround, make your method final and start it with:
if(self::class!=static::class) return;#or throw an error
It will not prevent inheritance itself, but methods will not work in children classes (with error or without - is up to you).
As of PHP 5.4, you can use Traits.
For example, you could make a base class that only includes the methods that all child classes have:
class EntityManager {
public function create() {/*...*/}
public function retrieve() {/*...*/}
}
Then you could define a couple of traits:
trait EditTrait {
public function edit() {/*...*/}
}
trait DeleteTrait {
public function delete() {/*...*/}
}
You would then create an immutable child class like this:
class LogManager extends EntityManager {
...
}
And a mutable child class like this:
class ContactManager extends EntityManager {
use EditTrait;
use DeleteTrait;
...
}
Traits have some advantages over some of the other solutions here such as:
No duplication of code.
Single base class.
Methods that don't work or don't make sense, don't appear on classes that don't support them (especially important for docs and apis).
Can anyone give me an example of the following desired OOP structure please.
I want a main class (super class) (interface or abstract class?) where all the other classes that are extending from it can have their functions called from instances of the main super class.
e.g.
class mainSupoerClass() {
}
class doWork exends mainSupoerClass(){
public function addEntity(){
//do stuff for entity
}
}
I want be able to do this:
$data = new mainSupoerClass;
$data->addEntity(); (doesnt belong to this class but its fetching the function from doWork class)
Can anyone give me a start on the correct OOP structure to carry out this work?
In simple terms, you can't. You have to instantiate the extended class and you'll get all functions within the instantiated class and also the parent class/classes.
Is there any reason you need this to be done this way?
That won't work the way you describe it. PHP (nor any other language) can know which derived class you refer too. It would work if you instantiate doWork instead of mainSupoerClass.
I think you are looking for the factory pattern, but I'm not sure.
With that pattern, you build an interface (either an interface or an abstract class), and let a factory instantiate any descendant of that class.
Now your code doesn't need to know which instance it is, because it can call any method declared in the interface/abstract base class.
An interface is more flexible in this regard. If you create an abstract class, you will need to derive all other classes from that class. Usually this won't be a problem, but sometimes you want a whole new implementation. In that case, an interface is better. You can implement the interface in a completely different class, and still make use of PHP's typehinting for validating that any object you pass to a function or method implements the interface.
Even it's called super-class, it does not mean that it has all classes defined elsewhere. The methodology is the following:
[super] --> [concrete]
and not
[concrete] --> [super]
So a concrete class extends the superclass. The concrete class will then have everything of the superclass plus what the concrete class has / overwrites - but not the other way round.
class Super
{
public function a() {}
}
class Concrete extends Super
{
public function b() {}
}
Super has ::a() and in addition Concrete has ::b(). But Super will never have ::b().
Additionally even you have multiple classes, there is always one instance regardless of how many classes it is compound of, commonly called object:
$object = new Concrete;
This makes a Concrete object.
You'll have to read. Try these:
Article: http://sourcemaking.com/design_patterns/abstract_factory
Code: http://sourcemaking.com/design_patterns/abstract_factory/php/2
It appears that the factory design pattern is what you are looking for.
I don't understand why you wanted to be able to do:
(doesnt belong to this class but its fetching the function from doWork class)
What's the reason behind it?
If I have:
class main {
//hello
}
class child1 {
function love($v) {
}
}
class child1 {
function hate($v) {
}
}
function __autoload($file) {
include_once($file . '.php');
}
Is there a way I can set this up so that I can do
$main = new main();
$main->hate();
$main->love();
and still
keep them as seperate classes, and
use the autoloader for the child classes?
I think even if the child classes extend the main class, that I can't access the child methods from the parent class. Is that correct? If so, is there something like a reverse extends which injects the child class properties/methods into the main class?
Update 1
Okay, so it looks like there's nothing straight-up built in to php to acheive this (Thanks everyone for the answers). How about I write up my goal and maybe you or someone you know can suggest a way to acheive this?
I would like to have one main class. I then have a set of subclasses which operate like grouped function libraries. Each of these subclasses is __autoloaded when needed to acheive an end. So for example, I have a subclass of file upload & processing functions, a subclass of database interaction functions, a subclass of xml processing functions, and so on.
I want to use this like: call the main class at the top of every script $main = new main();. Then, later on, an image processing method from a child class (which has not been loaded) is needed, so I call
$main->methodFromChildClass(); which will cause that child class to be autoloaded and the method used.
I am hoping in this way to optimize which files are loaded, and keep things well organized. I'm fairly new to oop. Is there a way to achieve this type of organization now?
There is not such a language construct (not in PHP anyway - other languages offer mechanisms like mixins, which kind of work like that), but there is a technique to do something like that called inversion of control.
class Main {
public $child;
public function __construct($child) {
$this->child = $child;
}
}
$main = new Main(
new Child1()
);
$main->child->love();
This is very simplified example, that does not show full potential of this technique. For more information search for 'inversion of control' and 'design patterns'
I think you're interested in is called traits, which are not available in the current release of PHP, but will be in the next version, and is available in trunk if you check out the source from SVN and compile yourself.
For more information, see http://wiki.php.net/rfc/traits
Not to my knowledge, kinda violates the whole concept of OO programming. The main class should have the methods and properties which need to be used by all child classes of the main class, and then the child classes have methods and properties that only they will need to use.
I suppose if you really wanted to, you could store a child class object inside a main class object and do something like $main->child->hate(); but that would be sort of recursive, because if the child extends the parent class, and if the child was created and stored on the parent's construct, then you would wind up with an infinite loop of the parent creating the child which creates a new parent inside it which creates a new child which creates a new parent ad infinitum. Though you could get around that by simply having a method that would have to be manually called in order to create and store the child.
With the code you gave, it's not going to work.
If child1 extends main, you can call hate() method only by creating instance from the child1 class or by introducing the hate() method in the main() class.
Child classes inherit methods from Mother classes but the reverse is not true.
What exactly are you trying to do ?
You can use magic to simulate that behaviour, but "clean" is something different
class main {
public function __call ($name, $args) {
switch ($name) {
case 'hate':
$x = new child1;
return $x->hate();
break;
case 'love':
$x = new child2;
return $x->hate();
break;
}
}
}
The idea is to create a DOM-like tree. But there are some restrictions, that only certain types can actually contain the other.
I want to use an interface|abstract class|superclass to implement some well known js-functions as appendChild, replaceChild etc.
I'm using the classes page, block and item, where pages can contain blocks and blocks can contain either blocks or items.
Example: Page is a web page, block could be an list element and item could be an list item element.
But these objects contain more than just html-data and the concepts goes beyond just plain HTML representation. It's an overall idea of managing items, wether they have an actual representation or are just abstract objects. The concept itself works for many different hierarchies.
What I want to achieve is to reuse as much code of the parent class as possible (adding a child is basically the same for all classes) but to differ the type hints to match the allowed types to add as a child.
There are basically four ways I found out myself:
I use an interface, which allows me to type hint to the superclass but not to change these.
I use a superclass with public methods, so i can redefine the type hints (which is totally against usual practices when heriting preconditions).
I use a superclass with protected methods, which seems still being quite quirky.
I get rid of any superclass and just define almost the same class several times.
I use a method to check for the type, despite the feature of type hints.
So, if anyone is still willing to answer I'm happy for any proposition, idea or hint, which option to choose. I hope I could describe the issue well enough.
And if there is something i missed I'm thankful to hear it ;)
Code
Superclass way (works, but breaks precondition inheriting practice)
class Base {
public|protected function appendChild(Base $child) {
// do stuff
}
}
class Block extends Base {
public function appendChild(Block $child) {
parent::appendChild($child);
}
}
Interface way (Does not work. It must not)
interface Interface1 {
public function appendChild(Base $child);
}
class Base implements Interface1 {
public|protected function appendChild(Base $child) {
// do stuff
}
}
class Block extends Base{
public function appendChild(Block $child) {
parent::appendChild($child);
}
}
Edited parts are bold
Interface makes most sense to me. You can have one class that plays multiple roles, as it can implement multiple interfaces.
// you don't need any methods in the interfaces
class Foo implements Inline, Block {}
will work with both:
appendChild(Inline $foo); and appendChild(Block $foo);
and interfaces can extend each other, so there can be common interface for all your objects.
You can still use inheritance to reuse implementation, and you'll have flexibility to use inhertiance tree strictly for reuse of implementation, not limited by your page logic (you'll never be forced to make StaticSimpleton extend HeavyDatabaseyWidget).
If not interfaces, I'd go for option 5: just make appendChild call $child->canBeChildOf($this) and/or $this->accepts($child). Again, logic and implementation will be independent, and you'll have a lot of freedom with your logic.
PHP does type checks at run tmie, so use of type system doesn't buy you much anyway.