在 Java 中实现类适配器模式

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/6305784/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-30 15:17:42  来源:igfitidea点击:

Implementing Class Adapter Pattern in Java

javaclassdesign-patternsadapter

提问by markjason72

While reading up on the Class Adapter pattern in Head First Design Patterns, I came across this sentence:

在阅读Head First Design Patterns 中的类适配器模式时,我遇到了这句话:

class adapter... because you need multiple inheritance to implement it, which is not possible in Java

类适配器...因为你需要多重继承来实现它,这在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?

这不是类适配器模式吗?

回答by Kevin

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.

类适配器模式在 Java 中是不可能的,因为您不能扩展多个类。因此,您必须使用使用组合而不是继承的适配器模式。

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 Turkeyto a method which is expecting a Duckthrough the TurkeyAdapter.

现在,您可以将 a 传递Turkey给期望 aDuck通过 的方法TurkeyAdapter

class DuckCatcher
{
    public void catch(Duck duck) { }
}

By using the adapter pattern the DuckCatcheris now also able to catch Turkey(Adapter)s and Ducks.

通过使用适配器模式,DuckCatcher现在还可以捕获Turkey(Adapter)s 和Ducks。

回答by Andreas Dolk

The full story in heads up is: classadapter pattern is impossiblein Java just because Java does not provide multiple inheritance.

注意事项的全部内容是:适配器模式在 Java 中是不可能的,因为 Java 不提供多重继承

In their diagram, they show that the Adapterclass subclassesboth Targetand Adaptee. Your example is (close to) the Object adapter pattern. The difference is that you implement the Targetin your adapter class, rather then just subclassing the target (MyNeededInterfacein your example)

在他们的图表中,他们表明Adapter该类子类化TargetAdaptee。您的示例是(接近)对象适配器模式。不同之处在于您在适配器类中实现了Target,而不是只是将目标子类化(MyNeededInterface在您的示例中)

回答by Pace

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.

是的,您可以创建带有接口的类适配器,只要您只包装一个适配器即可。通过多重继承,您可以使用两个或更多的被适配者并将它们包装到一个单一的界面中。

回答by Timothy

GoF (Gang of Four) tells us about two major kinds of adapters:

GoF(Gang of Four)告诉我们两种主要的适配器:

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.)

A. 类适配器。他们通常使用多重继承来使一个接口适应另一个接口。(但我们必须记住,在 Java 中,不支持通过类进行多重继承(这是一个很好的理由 :))。我们需要接口来实现多重继承的概念。)

B. Object adapters. They depend on the object compositions.

B. 对象适配器。它们取决于对象组合。

To illustrate the concepts, I'll present a simple example: (source: book Java Design Patterns)

为了说明这些概念,我将提供一个简单的示例:(来源:Java 设计模式一书)

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

类和对象适配器演示
类适配器返回 :7
对象适配器返回 :7

回答by Saad

Class Adapters are kind of possible in Java by using single inheritance. As an example from Design pattern for dummies, suppose we have to adapt AWT checkboxes to be used alongside with Swing checkboxes, we can write a class adapter for this.

通过使用单继承,类适配器在 Java 中是可能的。作为傻瓜设计模式的一个例子,假设我们必须调整 AWT 复选框以与 Swing 复选框一起使用,我们可以为此编写一个类适配器。

The UI code in Swing to determine if a check box is checked is done with the isSelected method. But, AWT check boxes dont support isSelected(), they use getState() instead.

Swing 中用于确定是否选中复选框的 UI 代码是使用 isSelected 方法完成的。但是,AWT 复选框不支持 isSelected(),而是使用 getState()。

So we can write an adapter to wrap an SWT check box and adapt the getState() to isSelected()

所以我们可以编写一个适配器来包装一个 SWT 复选框,并将 getState() 适配为 isSelected()

  public class CheckboxAdapter extends Checkbox
  { 

      public CheckboxAdapter(String n) 
      {
         super(n);
      }

      public boolean isSelected()
      {
         return getState();
      }
  }

Now we can handle AWT adapted check boxes as we would standard Swing check boxes when it comes to the isSelected method.

现在,当涉及到 isSelected 方法时,我们可以像处理标准 Swing 复选框一样处理 AWT 自适应复选框。

  public void itemStateChanged(ItemEvent e)
  {
      String outString = new String("Selected: ");

      for(int loopIndex = 0; loopIndex 
         <= checks.length - 1; loopIndex++){
           if(checks[loopIndex].isSelected()) {
              outString += " checkbox " + loopIndex;
           }
       }
      text.setText(outString);
   }

EDIT: True class adapter are not possible in Java, if they were we could inherit from multiple classes, which we want to mimic in an adapter class.

编辑:真正的类适配器在 Java 中是不可能的,如果它们是我们可以从多个类继承的,我们想在适配器类中模仿。

Also see http://www.journaldev.com/1487/adapter-design-pattern-in-java-example-tutorialfor two examples in Java using Class Adapter and Object adapter, to achieve same result.

另请参阅http://www.journaldev.com/1487/adapter-design-pattern-in-java-example-tutorial中使用类适配器和对象适配器的两个 Java 示例,以实现相同的结果。