I am working on a simple abstract database class. In my usage of this class, I'll want to have some instance be a singleton. I was thinking of having a abstract class that is not a singleton, and then extend it into another abstract class that is a singleton. Is this possible? Recommended?
Edit: I want to have two abstract that are practically identical, except one is a singleton. So the only difference will be that one will have all the functions of the other, but will have the other properties and methods that make it behave like a singleton.
I'd like to have one base class code base for this so as I make changes, I don't have to keep two files in sync.
In the way that I do things, I believe that there's no use for an abstract singleton. This is because,
1) What you want to be a singleton is the final class you instantiate for use within the application whether it'd be a library, model, controller or view and NOT the abstract.
2) Adding the singleton method is easy and can be written in 8 lines. See below.
protected static $_instance;
public static function getInstance()
{
if (!isset(self::$_instance)) {
self::$_instance = new self();
}
self::$_instance;
}
3) PHP 5.3 below version doesn't support late static binding. This will result in instantiating the abstract class instead of the final class inheriting it and will not function as expected, as already mentioned by Gordon and nuqqsa. So, for backward compatibility, better avoid it.
The implementation of the singleton pattern must satisfy two requirements:
It must provide a mechanism to access the singleton class instance without creating a class object
It must persist the singleton object so that it is not instantiated more than once
As long as that's provided, the variations are multiple. There's nothing wrong with making the class abstract extending from another abstract, if that's what you need. BUT, as #Gordon says, be aware that overriding static methods/properties causes peculiar behaviours in PHP < 5.3.
Related
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?
In every example I've seen, extended classes implement the interfaces of their parents. For reference, the following example:
interface MyInterface{
public function foo();
public function bar();
}
abstract class MyAbstract implements MyInterface{
public function foo(){ /* stuff */ }
public function bar(){ /* stuff */ }
}
// what i usually see
class MyClass extends MyAbstract implements MyInterface{}
// what i'm curious about
class MyOtherClass extends MyAbstract{}
Is failure to implement an interface in a child, which is implemented by a parent, considered bad practice or something? Are there any technical drawbacks to omitting the implementation in the child?
I would consider that you are on the right path. There is no need to declare that you are implementing the interface, when extending a class that already implements it. For me it's just another piece of code to maintain if change is needed. So, yes, you are correct!
Is failure to implement an interface
in a child, which is implemented by a
parent, considered bad practice or
something? Are there any technical
drawbacks to omitting the
implementation in the child?
I just can't answer your question better than this guy has:
By their nature, although sometimes
they may look quite similar, abstract
classes and class interfaces serve
very distinct purposes.
The interface of a class is meant as a
tool for the "user" of that class. An
interface is a public presentation for
the class, and it should advertise, to
anyone considering to use it, what
methods and constants are available
and accessible from the outside. So,
as it name suggests, it always sits
between the user and the class
implementing it.
On the other hand, an abstract class
is a tool aimed at helping the
"implementor" of the classes that
extend it. It is an infrastructure
that can impose restrictions and
guidelines about what the concrete
classes should look like. From a class
design perspective, abstract classes
are more architecturally important
than interfaces. In this case, the
implementor sits between the abstract
class and the concrete one, building
the latter on top of the former.
Reference
Thus, it's up to you to decide, based on who is going to use (instantiate) your classes, and who is going to write them. If you are the sole user and writer of your classes, then, maybe, just maybe, you don't need them both. But, if you want to give everyone a stripped down to core bits blueprint for the class writer(s) and class user(s), then you should consider using both abstracting and implementing.
Maybe a little late to the table but I see the above comments do not clarify the main misunderstanding underlying the OP's question.
So the underlying questions are:
Why we use both an Abstract class and an Interface on the same line?
Should both an Abstract method and an Interface declare the same methods at all?
But before some clarifications why to use either of the two above:
Either of them are used by one programmer to define the contract (requirements, obligations, limitations) the other programmers have to obey when they create the concrete classes (and eventually entire software application) based on Abstract classes / Interfaces developed by that programmer.
An Abstract class, in turn, is used to provide the later created concrete class with methods & data structures blueprint via:
data structures declarations (optional),
base implementation of methods (and their signatures, optional)
just methods declarations (similar to an Interface usage, optional).
An Interface is used to provide a concrete class with a methods blueprint via
just methods (and their signatures, optional) declarations.
Here is an example for an Abstract and concrete classes.
abstract class MyAbstractClass {
public function foo() {
// Base implementation of the method here.
}
public function bar() {
// Base implementation of the method here.
}
// Effectively similar to baz() declaration within some interface:
public abstract function baz($value);
}
class MyConcreteClass extends MyAbstractClass {
// foo() and bar() are inherited here from MyAbstractClass.
// baz() must be implemented or declared abstract again.
public function baz($value) {
// implementation.
}
}
Then the questions come:
Why we need an Interface here?
Do we need an Interface to duplicate same method declarations?
The answers:
Due to the fact that PHP allows only single inheritance for each subclass (you cannot write class MyConcreteClass extends MyAbstractClass, MyAnotherClass {}), when we need to expand the concrete class functionality beyond the already used Abstract class we have to declare this additional functionality via one or more Interfaces.
Like this:
class MyConcreteClass
extends MyAbstractClass
implements MyInterface, MyAnotherInterface {
// Methods and data implementations go here.
}
As the result from the answer 1, an Interface better not to duplicate an Abstract class methods' declarations (this is basically useless). An Interface(s) should decalre the methods that may help to enhance the concrete (or another Abstract class, why not) functionality to provide the programmer that will use these with the firm contract for each object built on top of these classes and interfaces.
Finally, answer to the the OP question whether to use an Interface for an Abstract class or for the concrete class is:
use for either or both (or as needed) as long as an Interface enhances a class contract with new methods' declarations.
Is failure to implement an interface in a child, which is implemented by a parent, considered bad practice or something?
The child always implements the interface, it can not go around with this.
I have no clue if that is bad practice or something. I would say it's a language feature.
Are there any technical drawbacks to omitting the implementation in the child?
You can not test the reflection of the abstract class for having the interface for example.
However, abstract class are already an interface, so technically they themselves not really need the interface but you can do so to keep things fluid within the inheritance.
Well, I was confused too, but I think you should use the latter one, You are right, If you implement the interface in the abstract class, then there is no need to write the interface, you can write the method in interface all into abstract as abstract methods, because you will extend the abstract class whatever, and you will have to use the abstract class as a param type when you use the class in other place, that's not a good thing, I think an abstract class should't be used as a param type, while an interface should be.
I'm trying to work out how to best complete my design work on my classes.
my situation.
i have an order abstract class that contains order methods and information that are required for 2 children classes
order_Outbound
and order_inbound
each child class requires 2 static public method called create and get
but from what i have read about php 5.3 you cant have abstract static methods ???
so my thought was to have an interface Order_Interface which takes over that role but how do i implement it. do i still implement it in the parent class
in which case the parent abstract class still requires me to create a get and create method within the abstract class. or do i implement it in the children and extend from the abstract class???
ALSO!!!
both the outbound and inbound children require a create static method but require different parameters to be passed
can i in the interface have public static function create()
and in its implementation within order_outbound declare it public static function create($address, $reference, $orderID)
In most languages, including PHP, you cannot require a class to implement static methods.
This means neither class inheritance, nor interfaces, will allow you to require all implementors define a static method. This is probably because these features are designed to support polymorphism rather than type definition. In the case of static methods you'll never have an object to resolve the type from, so would have to do ClassName::Method explicitly, so the theory is you wouldn't gain anything from polymorphism.
As such, I see three solutions
Declaring the static methods in each class (after all, you are never going to
If you want a method to create instances of your class, but don't want to require an instance to call this method, you could create "Builder" classes to serve this purpose (e.g. OrderBuilder), such that you instantiate an OrderBuilder and call the Create method on this object instead to get Order instances.
(Recommended) Why aren't you simply using the Order constructor?
Update
After the comment from #hvertous, I decided to test this out. Using 3v4l we can see that abstract public static method:
Works for versions 5 > 5.1.6
Doesn't work for 5.2 > 5.6.38
Works for 7.0.0 > 7.3.1
Which confirms that it was removed in PHP 5.2, but if you are using PHP 7+ you can once again use abstract static methods.
Original answer
Yes, abstract static methods were removed in PHP 5.2. Apparently they were an oversight. See Why does PHP 5.2+ disallow abstract static class methods?.
However, you can have static methods in an interface, see this comment on php.net.
The problem you face is that you want your implementations to have different function signatures, which means that you probably shouldn't be using inheritance to solve your problem.
PHP 7.4+ allows to require a static method in an interface:
interface StaticInterface {
public static function interfaceMethod();
}
class MyProvider implements StaticInterface {
//public static function interfaceMethod() {}
}
Fatal error without the method: https://3v4l.org/YbA4u
No errors when implementing the method: https://3v4l.org/QNRJB
I understand that singleton enforces a class to be created once. But why should an instance exists if I dont access it directly? Why is that pattern for, isn't it easier just use full static class with static methods and datas?
Some time ago I was asked what is the benefit of using singleton over of using static class, here is my response:
Static class leads to invisible dependencies - that is a class that use the static class, but that class is not part of the class' interface.
Singleton also allows this, because it provides global access point, but it's instance can be passed as an argument to the class / method
If there is any initialization, as the connect method, it should be called from each class method, which leads to duplicated code. On the other hand, the initialization of the singleton is performed in the constructor, which is called just once from the getInstance()
method
Singleton can be easily refactored in a factory, adding a parameter to the getInstance() method and returning different instances
Static class is harder to extend, because if we want to override a method, that is called within the class with self::methodName(), we should override the caller as well (although in PHP 5.3 there is a late static binding, which can be used to avoid those problems)
If you need to add an argument, needed for all of the methods, you can easily do this in singleton because of the single access point, but you can't in a static class
The major difference between a static class and a singleton is that with the static class, you need to hardcode the class name in your code everywhere you use it:
StaticClass::doSomething();
StaticClass::doSomethingElse();
While with a singleton, you only need to hardcode the class name once:
$singleton = SingletonClass::getInstance();
// other code does not need to know where $singleton came from,
// or even that class SingletonClass exists at all:
$singleton->doSomething();
$singleton->doSomethingElse();
Another important difference is that singleton classes can be part of hierarchies and can implement interfaces.
This does not mean that Singleton (the pattern) is good and should be used liberally. But it is better than using a static class directly.
[Edit]: The stuff I have written below is actually plain wrong. Just got alerted to this answer from years ago by a downvote. They do serve a purpose ;)
A singleton exists once, but it can have internal state - as opposed to a static class. You might e.g. use it as a global registry, which you can't do with a static class.
[Edit:] What comes next, though, is as true as it ever was.
It's debatable whether singletons are a good idea, though. They introduce global state into an application, which can make it very hard to test. But that is another discussion.