首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Java中的多继承

Java中的多继承
EN

Software Engineering用户
提问于 2015-09-19 18:36:36
回答 3查看 2.1K关注 0票数 0

假设我有一个泛型的java类Filter<InputType, OutputType>,它接收一个输入对象并将其转换为一个输出对象。

现在我有了另外两个类(NoInputFilter<OutputType>NoOutputFilter<InputType>),它们应该做同样的事情,但它们没有InputType,分别是OutputType

现在这三个类有一些共同的功能。Filter类应该以与NoOutputFilter相同的方式处理输入对象,并且应该以与NoInputFilter相同的方式处理输出对象。

在功能方面,我得到了类似的东西,其中B是Filter

现在,Java不允许从多个类继承。有这样的设计模式吗?

我的第一种方法是有两个接口。一个接口用于输入,一个接口用于输出。Filter类实现了这两者。但是这样的话,我必须每次实现两次接口。

然后,我考虑给出Filter类(它实现了两个接口) NoOutputFilterNoInputFilter的实例,只调用正确的方法而不是重复的代码。但这打破了语义,有大量的样板代码,而且在我看来并不是一种非常清晰的方法。这里有一个小小的示范:

代码语言:javascript
复制
class Filter<InputType, OutputType> implements INoOutputFilter<InputType>, INoInputFilter<OutputType> {
  private final INoOutputFilter<InputType> noOutputFilter;
  private final INoInputFilter<OutputType> noInputFilter;

  public void InputType setInput(InputType input) {
     noOutputFilter.setInput(input);
  }

  public OutputType getOutput() {
     noInputFilter.getOutput();
  }

  [...]
}

最后一个想法是将站点上的类层次结构降下来:

代码语言:javascript
复制
public class Filter<InputType, OutputType>
public class NoInputFilter<OutputType> extends Filter <Void, OutputType>
public class NoOutputFilter<InputType> extends Filter <InputType, Void>

这样,类的行为方式是正确的,没有重复的代码,但是例如NoOutputFilter有一个public Void getOutput()方法。尽管无法从Void实例化某些内容,但这两个类的API是错误的。会是这样的:

所以这也不是一个好方法。

你有没有任何提示我可以用Java来解决这个问题?这有设计模式吗?

EN

回答 3

Software Engineering用户

回答已采纳

发布于 2015-09-19 18:47:24

首先,Java 8引入了默认方法,它实际上是Java.

中的多继承。

历史证明,复杂的遗传结构是癌症。你应该重于继承。在这种情况下,您是混合输入过滤器和输出过滤器,以创建人工双向过滤器父。我一点也不干净。

我没有您的全貌,但根据您所描述的,我将考虑两个接口:InputFilterOutputFilter。最终双向过滤实现将实现两个接口。

如果有一些共同的功能,我会将这个公共逻辑提取到单独的类中,并将其作为依赖项使用。

票数 0
EN

Software Engineering用户

发布于 2015-09-19 19:48:39

我认为你的做法是错误的。您是从类而不是结果的角度来看待它。你--在我看来--应该这样做:

  • 定义输入接口
  • 定义输出接口
  • 使用可空的受保护属性定义实现两者的基类。
  • 为公开输出内容的NoInput定义一个具体的类
  • 为过滤器定义一个公开两者的具体类。

就这样。

一个

票数 1
EN

Software Engineering用户

发布于 2015-09-19 20:13:58

你考虑过这个吗?

代码语言:javascript
复制
public interface Input<InputType>   { ... }

public interface Output<OutputType> { ... }

public interface Filter<InputType,OutputType>
    extends Input<InputType>, Output<OutputType> { }

为了给你的问题一个更全面的答案:

多继承在

中的应用

(请注意,这在某种程度上是实验性的,我没有让其他经验丰富的java开发人员运行它来了解他们对它的看法。也许我会在这里收到一些反馈。)

在Java中实现多继承的方法是通过接口来实现.如果A类扩展了类X和Y,那么首先需要为X和Y定义接口,这样A就可以实现这两个接口。现在的问题是,一旦所有这些都就位,如何避免代码重复。在Java 8之前,这是一片混乱。使用Java 8,这变得更加容易和干净。(还是不像我希望的那样干净,但至少是可控的。)

每当我在Java8中创建一个以各种不同方式实现的接口时,我都会向它添加DecoratorDefaults子接口。所以,我建造了这样的东西:

代码语言:javascript
复制
public interface Zork
{
    boolean foo();
    boolean bar( int a );

    interface Defaults extends Zork
    {
        @Override
        default boolean foo()
        {
            return bar( 0 );
        }
    }

    interface Decorator extends Defaults
    {
        Zork getDecoratedZork();

        @Override
        default boolean bar( int a )
        {
            Zork decoree = getDecoratedZork();
            return decoree.bar( a );
        }
    }
}

这条路:

  • 希望提供Zork实现的类可以用implements Zork.Defaults声明,而不必实现为其提供默认值的方法。
  • 希望充当佐尔克装饰师的类可以用implements Zork.Decorator声明,为getDecoratedZork()提供一个实现,并实现Zork的任何必要子集,允许将其余的方法委托给修饰的Zork
  • 希望复制继承Zork的类可以声明如下:

(请注意,由于Zork是一个接口,所以MultipleInheritor类可以实现许多其他接口,比如Zork。)

代码语言:javascript
复制
public class MultipleInheritor implements Zork.Decorator
{
    private final Zork myZork = new Zork.Defaults()
    {
        @Override
        public boolean bar( int a )
        {
            return a % 2 == 0;
        }
    }

    @Override
    public Zork getDecoratedZork()
    {
        return myZork;
    }
}
票数 0
EN
页面原文内容由Software Engineering提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://softwareengineering.stackexchange.com/questions/297696

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档