I have a functionality that need to be shared by a few classes that manage a common aspect of my software. In Java, i would have all theses classes in the same package and the common functionality would be in a protected method in a helper class.
In PHP, protected method mean that you can only use it in sub-classes so my current solution is to make the method protected and have all the classes needing this method to extend the helper class. The problem with my current solution is the fact than you can't inherit multiple classes so lets say i need to helper classes, im ...
So, is there a way to have a method visibility comparable to java protected in PHP? If not, any cleaner way to solve my problem?
It sounds that you are looking to use traits.
http://php.net/manual/en/language.oop5.traits.php
This would let you define your shared protected method and provide to the classes that require it. I would recommend implementing this with an interface so that you can specify that the method provided by the trait has to be there.
PHP only lets you extend one abstract class however you can implement multiple interfaces.
You could try namespaces (5.3) and reference the utility class instead of extending it. This doesn't quite solve the problem but it does help isolate your class. I try to avoid using private methods.
In PHP 5.4 they added traits which kind of allow a class to extend multiple classes. Schleis has already answered with that.
Related
I happened to need to extend my class from two others:
My PDOUser class that provides basic PDO helper functions like getRow, query, mysql_error and so on.
My Debuggable class, that provides debugging methods and error methods to print out nice debug and error messages.
I was taught that inheriting multiple classes is a confusing way to make programs and that's why PHP doesn't support it.
Why I wouldn't dare to doubt the advices of more experienced programmers, I can't see a way to solve my problem nicer.
I can't make any of the classes static. The PDOUser class provides protected property pdo that can be also accessed from child classes.
The debugger class accesses the current classes names and method names to provide useful debug info.
I could make one of the helper classes inherit the other, but I think that would be confusing as well.
You can use composition over inheritance. This decouples yours objects.
Your new class doesn't need to inherit two classes, it can hold them as instances and use their functionality.
Inheritance vs. Composition:
Wikipedia
Javaworld
I've faced a situation when I want to extend two parent classes, but php does not allow this.
Why I can't extend more than one class, but can implement more than one interface. What's wrong with extending many classes?
It seemed to me like a pretty obvious thing, until I got parse errors.
Is it a bad practice? If so, what are the alternatives?
Is it possible in other languages?
Why multiple inheritance is forbidden in some/most programming languages is argued with the diamond problem http://en.wikipedia.org/wiki/Diamond_problem.
Put simple if you have a car that can swim and drive because it inherits from vehicle and boat what happens on execution of the move function!?
Try using interfaces and follow the Strategy pattern or State pattern.
You're probably looking for: Multiple Inheritance in PHP.
It seems to be possible in Python.
Take a look at Can I extend a class using more than 1 class in PHP?
Is it a bad practice? If so, what are alternatives?
Unless the language is specifically designed for it, yes. Consider, you have two classes, A and B. Both classes provide a public method foo() which have identical signatures (not hard in PHP). Now, you make a class C which extends both A and B.
Now, you call C.foo(). Without explicit instructions, how does the interpreter know which version of foo() to call?
It's not supported by PHP. It can however be simulated using runkit, APD or by just overriding __call and __get to simulate inheritance from multiple classes. Symfony (and I seldomly recommand that) also provides "sfMixin" or "sfMixer" for multiple inheritance.
Separate classes implementing the same method is not a good argument against multiple inheritance, as currently multiple interfaces can be implemented. You just can't implement two interfaces with the same method. Quote from http://www.php.net/manual/en/language.oop5.interfaces.php: "A class cannot implement two interfaces that share function names, since it would cause ambiguity."
I know this question is 2 years old but I've only just had the same problem. My work-around is this: if you have one regular class and two abstracts and want to extend both, e.g abstract class AbstractOne and abstract class AbstractTwo, you can say:
abstract class AbstractOne extends AbstractTwo {
}
Then add to the main class like this:
class MyMainClass extends AbstractOne {
}
This way, it inherits both AbstractOne and AbstractTwo.
I have multiple inheritance like this one: Can I extend a class using more than 1 class in PHP? (let's not discuss this approach itself please) and want my IDE to know about inherited class methods and properties. Is there a way to do it with PhpDoc?
It seems there is currently no way to do it easily. I've created a ticket at PhpStorm issue tracker. Maybe they will add support for this feature.
http://youtrack.jetbrains.net/issue/WI-1730
The #method anotation should be used for classes implementing __call. On a related note, for __get, __set and __isset, the #property annotations should be used. The only thing I don't know for sure is whether Eclipse PDT supports these annotations. I know NetBeans does.
there is no support for multiple inheritances at class level. This means you can't extend more than one class at a time. However multiple inheritance is supported in interfaces. An interface can extend an arbitrary number of other interfaces
at a time.
I just noticed this behavior today - weird, I'm pretty sure in java a you can only access protected methods upstream on the inheritance chain since going the other way violates encapsulation.
Was there a reason for this behavior in the language?
I've found it useful when one method defined in the parent only needs a small part of its functionality to change based on the extension class type. You can call an abstract method from within the parent, and it's functionality changes as needed with the definition of that method in the child classes.
I would also add that sibling classes can also access each other's protected properties and methods, as long as they are declared in the parent class (this can be abstract or not).
This is allowable in Java as well. This is probably allowed in Java however, since protected is also considered to be package level scope and not just relegated to access within the inheritance chain.
protected != private
Why should I usefunction __construct() instead of function className() in PHP 5?
The __ magic methods/functions seem to be a consistent theme in PHP (for once!). One advantage of using __construct() over ClassName() as a constructor is if you change the name of the class, you don't need to update the constructor.
Because php5 wanted to be more like python.
I kid, I kid...
Having a standard method for standard actions, like construction, is a reasonable solution. It's the same reason that in C# classes, when you extend a class, you use base for calling base class constructors instead of a named object: it simplifies code and makes maintenance easier.
Because it has been unified with the __destruct() method and other special methods beginning with two underscores for example __get, __sleep, __serialize
http://us2.php.net/manual/en/language.oop5.magic.php
My guess would be that by the time object-oriented capability was being added to PHP, the designers were looking at Python.
By doing so always, you can invoke the constructor from the super (base-)class without having to know its name. This is very useful for class tree maintenance, because you don't want to have to update all your classes just because you re-arrange your class trees
and...just guessing.. if all classes name their constructors identically __construct(), in theory a constructor could be inherited from a superclass without any required definition. This makes sense in class trees where there are intermediate abstract classes, and in constructs like in objective C where default constructor behaviour is derived entirely from class metadata and therefore (in priciple!) would need no coding at all.
Old question, but I'll bite since no one has actually answered the actual question yet.
function className() is a PHP4-style constructor.
function __construct() is a PHP5-style constructor.
You should use the latter because the former is deprecated and may be removed from the language.
Also, the former may or may not ignore various PHP5 OO concepts, such as the public/private visibility operators. Not that you'd want to make the constructor private if you weren't using the Singleton or Factory patterns.