3

Class Adapters uptil now have been considered not possible in java.Previous question regarding the same also says so.

But, Java 8 now supports default methods in Interfaces and multiple interfaces can be implemented by a class. So, a class inheriting from multiple interfaces with multiple default methods can make one interface's default methods act as an adapter and make a call to the other interface's (adaptee's) default method.

So, now is the statement Java 8 supports Class Adapters correct?

Community
  • 1
  • 1
Dhruv Rai Puri
  • 1,335
  • 11
  • 20
  • Yes, Java 8 supports multiple inheritance for behaviors (methods) but not properties (fields). – Eng.Fouad Oct 27 '15 at 12:04
  • Ok, but in terms of multiple inheritance for behaviors can we say that Java 8 supports class adapters? I am writing an article on my blog, www.javabrahman.com, about adapter pattern, and when I was about to mention that class adapters are not possible in Java I thought of the above question... – Dhruv Rai Puri Oct 27 '15 at 12:10
  • 1
    I tried to find out, what a Class Adapter is supposed to be and why it shouldn’t be possible with Java, but failed. As far as I understood, a Class Adapter is supposed to inherit an implementation and an interface, which always has been possible with Java, when the implementation is a `class` and the interface, well, an `interface`. So what’s the obstacle? – Holger Oct 27 '15 at 14:12
  • Class Adapter pattern says that the Target and the Adaptee should both be inherited by the Adapter, and that neither of them(Target & Adapter) are abstract. Multiple class inheritance is not possible in Java. Multiple interface implementation is possible but interfaces did not have default methods - until now i.e. Now Java 8 has default methods. But can one default method from one interface call another interface's default method(both interfaces being parents of Adapter class) - and would this qualify as a valid class adapter? This is my question! – Dhruv Rai Puri Oct 27 '15 at 14:16
  • 1
    I didn’t find such a restriction anywhere, that the target is not allowed to be `abstract`. Otherwise, you answered your question yourself. If such a restriction exists, this Pattern is still impossible as `interface`s are still always `abstract` without any exception. Having `default` methods does not change the `abstract` nature of `interface`s – Holger Oct 27 '15 at 14:19
  • If target is allowed to be abstract implying the method which is being invoked is implemented directly in the adapter then target will not work without an implementation. But that is not ideal as adapter will adapt from a working target to a working adaptee i.e. target should ideally not be abstract. – Dhruv Rai Puri Oct 27 '15 at 14:22
  • 1
    If the target already implements the method, there is no point in creating an Adapter at all. You could just use the target. It only makes sense, if the target contains at least one `abstract` method for which the adaptee contains an implementation and ideally both are matched by the Adapter via purely extending both types (*without* having to add code). – Holger Oct 27 '15 at 14:29
  • Lets take a real-world example- say your current logic is for sending a RMI request and you now need to send RESTful requests as remote client is making RMI deprecated.Since the current "implemented" target code for RMI request is not useful for sending the RESTful request,and we do want to break the design by writing a RESTful client in target class, we sub-class the target and the RESTful client class, then override the RMI method by writing a method of the same name in adapter, and instead of creating an RMI request we invoke RESTful client's(Adaptee's) method to send RESTful request. – Dhruv Rai Puri Oct 27 '15 at 14:37
  • If we keep target's method as abstract then it will be an example of Strategy pattern I think – Dhruv Rai Puri Oct 27 '15 at 14:38
  • 1
    Sorry, I can’t follow your example. In RMI, target classes don’t implement the RMI logic, neither do they inherit it. It all works by delegation. So there is no RMI method which you can overwrite in your Adapter. Even if there was, it’s not clear why the overriding Adapter should need to inherit the implementation RESTful client if it has to invoke it explicitly anyway. – Holger Oct 27 '15 at 14:51
  • 1
    Ok, it works, once we realize that you simply swapped the Target and Adaptee role. Since the RMI interface is, well, an `interface`, you can easily create an Adapter class which implements the remote `interface` and extends the RESTful client implementation `class`. A good prove that it actually works in Java… – Holger Oct 27 '15 at 14:54
  • Yep... that is correct from an implementation point of view. Actually RMI client and RESTful were examples I picked just to tell 2 different ways of implementation. If we think from a design angle, what I meant to say was trying to fit in a new implementation in accordance with an existing one - or adapting is something which needs an existing implementation. If we use the existing implementation's interface and put in a new implementation for that then its more of strategy pattern. – Dhruv Rai Puri Oct 27 '15 at 15:02
  • 1
    Well, I get your point. I’m not sure whether the Adapter Pattern really requires overriding existing behavior to be called such, but that’s not important for the answer. As written in my answer, the restrictions didn’t change. Not in formal terms and not in practice (as developers are not going to deliver implementation classes as pseudo-`interface`s). – Holger Oct 27 '15 at 15:13
  • yep... I understood your point as well :) – Dhruv Rai Puri Oct 27 '15 at 15:15

1 Answers1

3

As far as I understood, the Class Adapter Pattern is about creating a class which extends multiple types so that it inherits at least one implementation and at least one interface not formerly directly implemented by the implementation to enable using the existing implementation via the interface.

This has been possible in Java, with the restriction that the Adapter can only inherit one implementation (class) but inherit multiple interfaces (Compare with this answer). This limitation hasn’t changed in any way. You still can only inherit from one class.

It is correct that interfaces can now have default methods, but this doesn’t change the abstract nature of an interface and doesn’t make them eligible for conceptually bearing an implementation.

Even if an interface contains only default methods (no abstract methods), you still can’t instantiate it without creating a new class which implements the interface. Such a strange interface could only exist for primarily supporting the creation of Adapter classes which would then not be an example of the Class Adapter Pattern anymore, as that pattern is about combining formerly unrelated types, not types which were primarily designed for being combined.

In other words, in practice, when you encounter multiple implementation classes that you wish to combine in one Adapter, you will still face multiple classes which you can’t combine via inheritance and the existence of the default method feature won’t change that.

So the bottom line is, before Java 8, this pattern could only be used with restrictions, and these restrictions still apply with Java 8. If you want to view these restriction as “It’s not possible”, then it is still not possible…

Community
  • 1
  • 1
Holger
  • 285,553
  • 42
  • 434
  • 765
  • In the above answer we are taking an implementation on one side and an interface on the other. And we are implementing that interface to make the adapter work... – Dhruv Rai Puri Oct 27 '15 at 15:11
  • Let me take another example - lets say we are using JPA with a vendor adapter to hibernate. JPA's implementation just delegates to hibernate's vendor adapter which executes hibernate code. Now JPA has an implementation existing then there is the vendor adapter and then there is hibernate implementation. So, we have 2 implementations and an adapter in between. – Dhruv Rai Puri Oct 27 '15 at 15:12
  • If I try to fit this in the above answer then the hibernate code will have to be written in vendor adapter itself. But it does not happen that way. Adapter is just that an adapter, it connects 2 implementations - it doesn't implement either side. – Dhruv Rai Puri Oct 27 '15 at 15:13
  • 1
    An Adapter connects 2 implementations, but you have asked for a particular kind of Adapter which creates a connection via inheritance which is only useful if the inheritance has any effect, i.e. overriding or implementing methods. However, the *point* of the answer, is, that the situation hasn’t changed, regardless how you judge it. That should answer your question. – Holger Oct 27 '15 at 15:20