简体   繁体   English

接口/抽象类之间的Java关系

[英]Java Relationship between interfaces/abstract classes

I am trying to build an algorithm that works in different ways depending on a traversal strategy and an update strategy . 我正在尝试构建一种算法,该算法根据遍历策略更新策略以不同的方式工作。 However, not every update Strategy works with every traversal strategy. 但是,并非每个更新策略都适用于每个遍历策略。 Hence, I figured that an update strategy must only be instantiated with a corresponding traversal strategy. 因此,我认为仅可以使用相应的遍历策略实例化更新策略。 I wanted to force a constructor for that (see below). 我想为此强制构造器(见下文)。 So that the subclasses would have to check if they support the strategy. 这样子类就必须检查它们是否支持该策略。

I am currently having an Interface 我目前有一个界面

public interface TraversalStrategy {
...
}

And an (invalid) abstract class 还有一个(无效的)抽象类

public abstract class UpdateStrategy {
protected TraversalStrategy travStrategy;

public abstract UpdateStrategy(TraversalStrategy travStrategy);
}

What is the correct way to imply such a dependency? 暗示这种依赖性的正确方法是什么? I could of course add an empty body to this constructor but that seemed wrong to me. 我当然可以在此构造函数中添加一个空的主体,但这对我来说似乎是错误的。

Update: Inspired by the Answer of @Kayaman, I created a new class TestcaseGenerator that is used to construct a valid combination. 更新:受@Kayaman答案的启发,我创建了一个新类TestcaseGenerator,用于构造有效的组合。

public TestcaseGenerator(TraversalStrategy travStrategy, UpdateStrategy updStrategy){
    if (updStrategy.supports(travStrategy)){
        this.travStrategy = travStrategy;
        this.updStrategy = updStrategy;
    }
}

当前类图

What I don't like about this yet is, that it would now be unnecessary to give the instance of TraversalStrategy to the UpdateStrategy in order to check if it is supported. 我对此不满意的是,现在不必将TraversalStrategy实例提供给UpdateStrategy来检查它是否受支持。 I would rather only need the class name. 我宁愿只需要类名。 Can you tell me how to achieve that? 你能告诉我如何实现吗? Experiments with .getClass().getName() seemed horrible. 使用.getClass().getName()似乎很可怕。 Currently I am doing: 目前我正在做:

public boolean supports(TraversalStrategy travStrategy){
   if(travStrategy instanceof UpstreamTraversalStrategy){ 
       return true; 
   }
   return false;
}

One common way is to have the superclass constructor call an abstract method such as isSupported(TraversalStrategy t); 一种常见的方法是让超类构造函数调用一个抽象方法,例如 isSupported(TraversalStrategy t); and fail if it's not true. 如果不正确,则会失败。

\n

The subclasses would then implement the method accordingly by using instanceof or any other way to determine if the strategy is a supported one. 然后,这些子类将通过使用 instanceof或任何其他方式确定该策略是否受支持来相应地实现该方法。

One approach would be to create a third class with a Builder pattern approach. 一种方法是使用Builder模式方法创建第三类。 Instead of providing TraversalStrategy as a parameter to UpdateStrategy , they would both be included in the third object (and they could be checked at build() to prevent incompatible strategies). 而不是将TraversalStrategy作为UpdateStrategy的参数提供,它们都将包含在第三个对象中(并且可以在build()进行检查以防止策略不兼容)。

You could then have general functionality in the third class, with the strategy classes becoming lighter. 然后,您可以在第三堂课中拥有常规功能,而策略课变得更轻便。

Even an abstract class must have a valid constructor. 甚至抽象类也必须具有有效的构造函数。 Even through it is not possible to create an instance of an abstract class, a non abstract subclass always calls the constructor of the super class first. 即使无法创建抽象类的实例,非抽象子类也始终会首先调用父类的构造函数。 Therefore your constructor on the abstract class needs a body to initialize the TraversalStrategy . 因此,抽象类上的构造函数需要一个主体来初始化TraversalStrategy

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM