温馨提示:本文翻译自stackoverflow.com,查看原文请点击:java - Is there a specific way to give a certain subclass some functions of the superclass?
inheritance java design-patterns polymorphism

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

发布于 2020-03-27 11:16:58

问题

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

In more detail, I'm trying to make a search engine using Lucene. Lucene
uses many indices. I've already implemented a simple structure where different index-objects inherit the methods of a parent class. The problem is that, whatever method is implemented in that parent class, it automatically becomes available for all subclasses to use. I want to give the option to the user to determine if he wants to do a phrase search, a term search or whatever else there is available for that specific index. The catch is, some indices shouldn't have the option to conduct phrase search, for example.

First Thoughts

I've thought of implementing something close to the Composite pattern,
as described by the GoF. I would implement the search operations (e.g. term search, phrase search) as primitive operations implementing some Component class and add these primitive objects later on to a Composite object. The Composite object will be implementing the same Component class as the primitives.

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

Expected Outcome

The class ReviewIndex shouldn't be able to perform a categorySearch but be
able to execute phraseSearch and termSearch. Respectively, the TipIndex class
should be able to execute some of the parent class methods.

Final Thoughts

I know that in my solution there is no code duplication but there are useless methods being generated each time a new index object is created. Thank you all in advance!

P.S. If you think the Composite pattern is the way to go, in which way would you actually add the primitive objects to the composite class and in which way would you invoke them when need to?

查看更多

查看更多

提问者
Invalid_Path
被浏览
60
Lothar 2019-07-03 22:38

All methods defined in a superclass are available at deriving classes but with Java 8 you might be able to get something like this by using default-methods in interfaces. So instead of one abstract class containing all possible methods you might implement four interfaces

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

To avoid duplicate code you can create an abstract class

public abstract class AbstractSearchable implements Searchable {
    private String indexPath;

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

    // other methods that might be useful
}

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

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

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