I have seen many frameworks and modules and their standard they follow is like this
UserInterface
which have some predefined methodsAbstractUserClass
which implementsuserInterface
- Then
GenericUserClass
which extends fromAbstractuserClass
- Then other classes extending from that generic
Now I have seen that abstract class has additional functions to the interface, and the generic class also has additional functions.
- So I am confused which methods should go where
- Sometimes I see
class A extends Abstractuserclass
and sometimesclass A extends Abstractuserclass implements UseraInterface
. What is the difference ifAbstractclass
already impelementsUserinterface
1
A rule of thumb is that:
- Interfaces define the public API (contract) or a certain functionality if you will,
- Abstract classes (may) provide a private API (for extended classes to use), such as shared functionality.
So i am confused which methods should go where
If a method should be part of the public API, add it to the interface and update dependencies where necessary (i.e. Abstract and / or Generic class).
Otherwise, implement the method as high up as is needed based on how generic or specific it is.
Sometimes i see class A extends Abstractuserclass and sometimes class A extends Abstractuserclass implements useraInterface. what is the difference if Abstractclass already implements Userinterface
There’s no difference in that case; you don’t have to specify an interface twice if the ancestor already implements it, because the interpreter will throw an error if you try to break the contract.
This would only make sense if the child class implements another interface altogether. And this is a strength of interfaces; since you’re defining a piece of functionality rather than a specific implementation, you can make any class implement any interface if you wanted to. This is a great help when writing mock classes for testing.
6
The interface is a contract – an API that exposes the necessary functionality for the object it represents. Therefore, an interface should support all the methods that are related to the concept it stands for.
So I am confused which methods should go where
Usually, an abstract class, or abstract generic class is used instead of directly implementing the interface. These classes in most cases serve as a faster way of implementing the interface and spare you boilerplate code. Generics usually address type-safety of a potential implementation of the interface. It is normal for them to introduce new methods.
A classical example is an abstract class that implements an interface and performs most of the validations and checks, just leaving a few abstract methods that must contain the user logic. This would reduce most of the boilerplate code for the concrete implementation, and point directly to the functionality that is left unimplemented.
The generic classes usually implement most of the interface with along with the type casts and checks and leave similar, now generic methods for the final implementation, which are being called from the non-generic interface methods.
Besides the above, the base classes may introduce context-specific methods for the implementation, or additional methods that do not seem to belong to the interface concept. For instance, when implementing a network stream using an imaginary Stream
interface, the implementation may expose methods or properties for the network location, url or other connection details. These are specific to the NetworkStream
and the networking context, and will be out of place on the generic Stream
interface, as you may also have a MemoryStream
implementation, which has nothing to do with network paths.
Another reason for an abstract class to introduce new methods that must not be present in the interfaces is to avoid code dependencies. The interface should not trigger dependency of libraries that are not directly related to the functionality it covers. In most cases, if you stick to the programming to interfaces paradigm, you will reference the library that has the interface and use any implementation of interface trough it, instead of working directly with the implementation type. This will allow you to avoid direct references to any implementation specific libraries when you work with the interface.
Sometimes I see class A extends Abstractuserclass and sometimes class A extends Abstractuserclass imlements useraInterface. What is the differnece if Abstractclass already impelements Userinterface
There is no difference if you specify the interface, if the base class already implements it. I would assume some people do it either because they are too verbose, or because this makes the code more readable. By reading the following line of code, I will not need to gasp into the Abstractuserclass
to see that it implements the UseraInterface
:
class A extends Abstractuserclass implements UseraInterface
So, this saves some effort and makes the code a kind of a self-explanatory one.
Some answers here are very generic stating that an interface
is a contract. It’s difficult to say they are a contract when there is no scope for interfaces and classes in PHP. So it’s impossible to enforce the contract. There is nothing stopping a developer from instantiating a class and ignoring the interface. So the contract description isn’t that clear to developers who haven’t used Java or C++ before.
So what’s it all about?
Your example is not a very good one. UserInterface
to AbstractUserClass
to GenericUserClass
doesn’t really show the benefits of what is going on. So let me expand on that a bit.
Why do we have interfaces, because an object can implement multiple interfaces. Think of an interface not as methods but as a defined behavior for a class. The interface is saying “I can behave like a user“. It doesn’t matter how the code achieves this. Just that it supports this interface.
The key to good interface design is not to create multi-purpose interfaces. Let each interface define a single behavior. This makes it much easier to create single purpose classes that work upon those kinds of objects. Instead of having one UserInterface
you might expand that to include AdminInterface
, AuthenticatedUserInterface
and UserPermissionsInterface
. So later in your code you can ask an object if it supports the AdminInterface
and if so, then that user is an administrator.
Why do we have abstract classes?
Interfaces, interfaces, everywhere interfaces… One of the drawbacks to using interfaces is that an interface implements absolutely no code. For every interface a programmer must implement at least one class. A good framework that uses interfaces will provide you with a wide range of already implemented abstract classes that give you a starting point to using those interfaces. A bad framework is one that requires many interfaces and gives you nothing to start from.
Avoid the super abstract class that implements many interfaces and provides most of the functionality for those interfaces. It’s also heavily inherited by many other classes.
What you want are small abstract class that implement an interface from different perspectives. You might want to create a couple of classes that implement UserInterface
like this AbstractInvalidUser
, AbstractAnonymousUser
or AbstractAuthenticatedUser
. Later you might need to use Facebook for logging in a user. You can then create a FaceBookUser
that extends AbstractAuthenticatedUser
. It’s clear now what each abstract class does but they all implement the UserInterface
.
So now the big question “Where do all the methods go?”
The key to creating maintainable source code is to always reduce dependencies down to their smallest part. That means you do not want source code using FaceBookUser
when all it’s doing is displaying the current user’s name. If everything in your source code is using FaceBookUser
then it’s difficult to move that class to another folder or rename that class. It’s easier for you to just use UserInterface
to display a user’s name and now all that source code doesn’t care if it’s Facebook, Google+ or your own sign in. The dependency is kept small because the interface is simple and single purpose.
Because interfaces separate code from the implementation of the interface. Your other code doesn’t care if the current object is a wrapper class, delegate class, super heavy class or just a simple class. As far as the code cares it’s just a UserInterface
reference.
Interfaces are tools that help you create management code. Place methods in interfaces so you don’t create dependencies between classes. You create break up your dependency by creating more then one interface.
That is what people mean when they call it a contract thingy.
2
Use interfaces to reuse contracts. Use abstract classes to reuse implementation. My guess is that AbstractUserClass
provides some common code that all foreseeable implementations of UserInterface
will need.