有没有特定的方法可以为某个子类提供某些超类的功能?

pas*_*alH 7 java polymorphism inheritance design-patterns

问题

我正在尝试创建一个应用程序,其中对象类可以从可用操作的总池中执行一些操作。最终目标是没有任何代码重复,并尽可能遵守OOP的法律。

更详细地讲,我正在尝试使用Lucene创建一个搜索引擎。Lucene
使用许多索引。我已经实现了一个简单的结构,其中不同的索引对象继承了父类的方法。问题是,无论在该父类中实现什么方法,它都会自动变为可供所有子类使用。我想为用户提供选项,以确定他是否要进行短语搜索,术语搜索或特定索引可用的其他任何内容。要注意的是,例如,某些索引不应具有进行短语搜索的选项。

最初的想法

我曾想过要实现类似于复合模式的功能,
如GoF所述。我将搜索操作(例如,术语搜索,短语搜索)实现为实现某些Component类的原始操作,然后将这些原始对象添加到Composite对象上。该复合物将实施相同的组件类作为原语。

public abstract class Index {
    public Index(String indexPath) {
        // Constructor using the information provided by the subclass
    }

    public void phraseSearch(...) {
         // Do the operation
    }

    public void termSearch(...) {
        // Do the operation
    }

    public void categorySearch(...) {
        // Do the operation
    }
}

public class ReviewIndex extends Index {
    public ReviewIndex() {
        super("./review_index/");
    }
}

public class TipIndex extends Index {
    public TipIndex() {
        super("./tip_index/");
    }
}
Run Code Online (Sandbox Code Playgroud)

预期结果

该类ReviewIndex不应该能够执行categorySearch,但是可以
执行phraseSearch和termSearch。分别是TipIndex
应该能够执行一些父类的方法。

最后的想法

我知道在我的解决方案中没有代码重复,但是每次创建新的索引对象时都会生成无用的方法。谢谢大家!

PS:如果您认为应该使用Composite模式,那么您将以哪种方式将原始对象实际添加到Composite类中,并在需要时以哪种方式调用它们?

Lot*_*har 1

超类中定义的所有方法都可以在派生类中使用,但在 Java 8 中,您可以通过在接口中使用默认方法来获得类似的东西。因此,您可以实现四个接口,而不是包含所有可能方法的一个抽象类

public interface Searchable {
    public String getIndexPath();
}

public interface PhraseSearchable extends Searchable {
    public default void phraseSearch() {
        String indexPath = getIndexPath();
        // do the search
    }
}

public interface TermSearchable extends Searchable {
    public default void termSearch() {
        String indexPath = getIndexPath();
        // do the search
    }
}

public interface CategorySearchable extends Searchable {
    public default void categorySearch() {
        String indexPath = getIndexPath();
        // do the search
    }
}
Run Code Online (Sandbox Code Playgroud)

为了避免重复代码,您可以创建一个抽象类

public abstract class AbstractSearchable implements Searchable {
    private String indexPath;

    public AbstractSearchable(String indexPath) {
        this.indexPath = indexPath;
    }

    // other methods that might be useful
}
Run Code Online (Sandbox Code Playgroud)

然后您的实际类可以实现相应的接口

public class ReviewIndex extends AbstractSearchable implements CategorySearchable {
    public ReviewIndex() {
        super("./review_index/");
    }
}
public class TipIndex extends AbstractSearchable implements PhraseSearchable, TermSearchable {
    public ReviewIndex() {
        super("./review_index/");
    }
}
Run Code Online (Sandbox Code Playgroud)

这是否可能在很大程度上取决于搜索方法的实际实现。接口不能包含任何成员等,因此这些方法必须能够自行运行(就像不使用类的任何静态成员的静态方法)。您可以通过向Searchable接口添加更多方法来克服这个问题,这些方法提供数据并在抽象类中执行实现,但这可能会将内部内容暴露给公众,因为接口中所有声明的方法都是公共的。