Implementing Class Adapter Pattern in Java
Solution 1
The class adapter pattern is not possible in Java because you can't extend multiple classes. So you'll have to go with the adapter pattern which uses composition rather than inheritance.
An example of the adapter pattern through composition can be found below:
interface Duck
{
public void quack();
}
class BlackDuck implements Duck
{
public void quack() { }
}
class Turkey
{
public void gobble() { }
}
class TurkeyAdapter implements Duck
{
private Turkey t;
public TurkeyAdapter(Turkey t)
{
this.t = t;
}
public void quack()
{
// A turkey is not a duck but, act like one
t.gobble();
}
}
Now you can pass a Turkey
to a method which is expecting a Duck
through the TurkeyAdapter
.
class DuckCatcher
{
public void catch(Duck duck) { }
}
By using the adapter pattern the DuckCatcher
is now also able to catch Turkey(Adapter)
s and Duck
s.
Solution 2
Yes, you can create a class adapter with an interface as long as you're only wrapping a single adaptee. With multiple inheritance you could take two or more adaptees and wrap them into a single interface.
Solution 3
The full story in heads up is: class adapter pattern is impossible in Java just because Java does not provide multiple inheritance.
In their diagram, they show that the Adapter
class subclasses both Target
and Adaptee
. Your example is (close to) the Object adapter pattern. The difference is that you implement the Target in your adapter class, rather then just subclassing the target (MyNeededInterface
in your example)
Solution 4
GoF (Gang of Four) tells us about two major kinds of adapters:
A. Class adapters. They generally use multiple inheritance to adapt one interface to another. (But we must remember, in java, multiple inheritance through classes is not supported (for a good reason :) ). We need interfaces to implement the concept of multiple inheritance.)
B. Object adapters. They depend on the object compositions.
To illustrate the concepts, I'll present a simple example: (source: book Java Design Patterns)
interface IIntegerValue
{
public int getInteger();
}
class IntegerValue implements IIntegerValue
{
@Override
public int getInteger()
{
return 5;
}
}
// Adapter using interface
class ClassAdapter extends IntegerValue
{
//Incrementing by 2
public int getInteger()
{
return 2 + super.getInteger();
}
}
// Adapter using composition
class ObjectAdapter implements IIntegerValue
{
private IIntegerValue myInt;
public ObjectAdapter(IIntegerValue myInt)
{
this.myInt=myInt;
}
//Incrementing by 2
public int getInteger()
{
return 2+this.myInt.getInteger();
}
}
class ClassAndObjectAdapter
{
public static void main(String args[])
{
System.out.println("Class and Object Adapter Demo");
ClassAdapter ca1=new ClassAdapter();
System.out.println("Class Adapter is returning :"+ca1.getInteger());
ClassAdapter ca2=new ClassAdapter();
ObjectAdapter oa=new ObjectAdapter(new IntegerValue());
System.out.println("Object Adapter is returning :"+oa.getInteger());
}
}
Console output:
Class and Object Adapter Demo
Class Adapter is returning :7
Object Adapter is returning :7
markjason72
I am a java programmer working with python at times.I like using Django for making webapps.I have used postgresql for most of my projects..
Updated on June 04, 2022Comments
-
markjason72 over 1 year
While reading up on the Class Adapter pattern in Head First Design Patterns, I came across this sentence:
class adapter... because you need multiple inheritance to implement it, which is not possible in Java
Just to experiment, I tried the following:
interface MyNeededInterface{ public void operationOne(MyNeededInterface other); public MyNeededInterface operationTwo(); } public class ThirdPartyLibraryClass{ public void thirdPartyOp(); }
Suppose I create :
class ThirdPartyWrapper extends ThirdPartyLibraryClass implements MyNeededInterface{ @Override public void operationOne(ThirdPartyWrapper other){ this.thirdPartyOp(); dosomeExtra(); } @Override public ThirdPartyWrapper operationTwo(){ int somevalue = doSomeThingElse(); return new ThirdPartyWrapper(somevalue); } }
In my code, I can use:
MyNeededInterface myclass = createThirdPartyWrapper(); myclass.operationOne(someobj); ...
Is this not the Class Adapter pattern?
-
Vineet Reynolds over 12 yearsThis is the object adapter pattern. The OP wants to attempt implementing the class adapter pattern.
-
Kevin over 12 years@Vineet: Could you expand? I'm not sure what the difference is between both? I thought there was just one general 'adapter pattern'.
-
Vineet Reynolds over 12 yearsthe Head First Patterns book, discusses the variant where inheritance (and not composition) is used to implement the class adapter. This is possible in C++ - see this example for instance.
-
Kevin over 12 years@Vineet: Ah I see, thanks for the link. The adapter pattern through inheritance would be impossible in Java though.
-
Pace over 12 yearsYet it achieves the same goal (adapting the adaptee) and clearly isn't the object adapter pattern. If you can't call it the class adapter pattern then what do you call it?
-
rai.skumar over 10 yearsdon't agree that Class Adapter is not possible; check out this link en.wikipedia.org/wiki/Adapter_pattern
-
2rs2ts over 10 yearsI'm with @rai.skumar on this one... it's very obvious that you use interfaces instead of subclassing. To quote Wiki directly: "This type of adapter uses multiple polymorphic interfaces to achieve its goal. The adapter is created by implementing or inheriting both the interface that is expected and the interface that is pre-existing. It is typical for the expected interface to be created as a pure interface class, especially in languages such as Java that do not support multiple inheritance."
-
2rs2ts over 10 yearsIt is a different story if you don't get to choose those interfaces ahead of time, though, I suppose.
-
Admin over 9 years+1 for making a turkey act like a duck; clear, concise & comical.