5

I have seen many frameworks and modules and their standard they follow is like this

  1. UserInterface which have some predefined methods
  2. AbstractUserClass which implements userInterface
  3. Then GenericUserClass which extends from AbstractuserClass
  4. 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.

  1. So I am confused which methods should go where
  2. Sometimes I see class A extends Abstractuserclass and sometimes class A extends Abstractuserclass implements UseraInterface. What is the difference if Abstractclass already impelements Userinterface
1

4 Answers 4

7

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
  • "There's no difference..." I don't know php enough, but in Delphi you would need to re-declare implementation of the interface when inheriting from a (library) base class (that you don't want to or can't change) that neglected to mark one or more interface methods as virtual. Without re-declaring the interface on the descendant, calling the method on an interface reference would call the base class' method instead of the method of the class that the interface reference refers to. Jan 2, 2014 at 11:05
  • @MarjanVenema Interfaces in PHP are more transparent so to speak; they don't have visibility modifiers, so once declared they can be used anywhere.
    – Jack
    Jan 2, 2014 at 21:56
  • Sorry, don't understand your comment. Delphi doesn't have visibility modifiers on interfaces either. All methods in an interface are implicitly public. And virtual doesn't have anything to do with visibility, but with polymorphism in a class hierarchy. Jan 3, 2014 at 11:33
  • @Marjan I guess I don't know what virtual means then, but it matters not :)
    – Jack
    Jan 3, 2014 at 12:30
  • Nope, just hope that any Delphi developers that read this do :-) Jan 3, 2014 at 12:32
3

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.

0

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
  • If you're implying that you can't enforce types anywhere in PHP (first paragraph), then that's just wrong: PHP typehinting.
    – Friek
    Jan 3, 2014 at 19:19
  • @Friek you can't create a private class. Usually a developer will create a public interface and use private classes to enforce the API contract.
    – Reactgular
    Jan 3, 2014 at 20:11
-1

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.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.