在 Java 中实现类适配器模式

发布于 2024-11-14 21:00:00 字数 1031 浏览 4 评论 0原文

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

类适配器...因为你需要多重继承来实现它,这在Java中是不可能的

为了实验,我尝试了以下操作:

interface MyNeededInterface{
    public void operationOne(MyNeededInterface other);
    public MyNeededInterface operationTwo();
}

public class ThirdPartyLibraryClass{
    public void thirdPartyOp();
}

假设我创建 :

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);
    }
}

在我的代码中,我可以使用:

MyNeededInterface myclass = createThirdPartyWrapper();
myclass.operationOne(someobj);
...

这不是类适配器模式吗?

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?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

郁金香雨 2024-11-21 21:00:01

GoF(四人帮)告诉我们两种主要类型的适配器:

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

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

为了说明这些概念,我将举一个简单的例子:
(来源:《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());
    }
}

控制台输出:

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

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

月下凄凉 2024-11-21 21:00:01

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

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

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

  public class CheckboxAdapter extends Checkbox
  { 

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

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

现在,我们可以处理 AWT 适配的复选框,就像处理 isSelected 方法时的标准 Swing 复选框一样。

  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);
   }

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

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

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.

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.

So we can write an adapter to wrap an SWT check box and adapt the getState() to 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.

  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.

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

锦欢 2024-11-21 21:00:00

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

下面是通过组合的适配器模式的示例:

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();
    }
}

现在,您可以通过 TurkeyAdapterTurkey 传递给需要 Duck 的方法>。

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

通过使用适配器模式,DuckCatcher 现在还能够捕获 Turkey(Adapter)Duck

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

墨小沫ゞ 2024-11-21 21:00:00

是的,只要您只包装单个适配器,您就可以创建带有接口的类适配器。通过多重继承,您可以采用两个或多个适配器并将它们包装到单个接口中。

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.

佼人 2024-11-21 21:00:00

完整的故事是这样的:适配器模式在 Java 中是不可能的,因为 Java 不提供多重继承

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

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)

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文