首页 > 解决方案 > Java:三种可能类型的一个字段?

问题描述

我有一个盒子课。盒子里有一个过滤器。

public class Box {
    private Filter filter;

    public Filter getFilter() {
        return filter;
    }

    public void add filter() {
        filter = new Filter();
    }
}

每个盒子只能有一个过滤器,但有 3 种不同类型的过滤器。每种类型的过滤器使用不同的参数来计算过滤效率等。到目前为止,我已经使用了一个过滤器类,它为每种过滤器类型实现了所有功能:

public class Filter {
    // filter fields/functions shared by each filter
    ...

   // filter fields/functions unique to filter type 1
   ...

   // filter fields/functions unique to filter type 2
   ...

   // filter fields/functions unique to filter type 3
   ...
}

这可行,但我不喜欢在构建过滤器后携带不需要/未初始化的字段。例如,如果过滤器对象是类型 1,它仍然存储类型 2 和类型 3 唯一的参数,因为只有 1 个过滤器类。为了防止这种情况,我决定使用继承:

public class Filter {
    // filter fields/functions shared by each filter
    ...
}

public class Filter1 extends Filter {
    // filter fields/functions unique to filter type 1
    ...
}

public class Filter2 extends Filter {
    // filter fields/functions unique to filter type 2
    ...
}

public class Filter3 extends Filter {
    // filter fields/functions unique to filter type 3
    ...
}

这解决了上述问题。但是,现在 box 类将需要区分每个过滤器。我不想执行以下操作,因为现在该框将存储空过滤器,因为每个框只能有一个过滤器。

public class box {
    private Filter1 filter1;
    private Filter2 filter2;
    private Filter3 filter3;

    public Filter1 getFilter() {
        return filter1;
    }

    public Filter2 getFilter() {
        return filter2;
    }

    public Filter3 getFilter() {
        return filter3;
    }

    public void add filter1() {
        filter = new Filter1();
    }

    public void add filter2() {
        filter = new Filter2();
    }

    public void add filter3() {
        filter = new Filter3();
    }
}

我想要以下内容:

public class Box {
    private filter; // either of type Filter1, Filter2, or Filter3

    public getFilter() { //somehow specify correct return type
        return filter;
    }

    public void add filter1() {
        filter = new Filter1();
    }

    public void add filter2() {
        filter = new Filter2();
    }

    public void add filter3() {
        filter = new Filter3();
    }
}

这可能吗?

总结:简而言之,我需要一个可以是多种类型的盒子过滤器。我需要能够根据其类型访问此过滤器的唯一字段/方法。我不想在框中存储多个空过滤器,也不想一个大的过滤器类将每种过滤器类型的功能集中在一起。

标签: java

解决方案


您应该尝试找到一种Box不需要关心Filter其过滤器类型的设计。如果Box需要知道,您应该考虑重新设计。有时您需要此类信息,但 99% 的情况下您不需要。

例如,如果只有Filter1aflowRate并且只有Filter2a density,并且您正在执行以下操作...

class Box
{
    void doStuff()
    {
        if(filter.isFilter1) doFlowStuff(filter.flowRate);
        if(filter.isFilter2) doDensityStuff(filter.density);
    }
}

然后你应该尝试将逻辑移出Box和移入Filter1Filter2

class Box
{
    void doStuff()
    {
        a();
        filter.doFilterStuff();
        b();
    }
}

interface Filter
{
    void doFilterStuff();
}

class Filter1 implements Filter
{
    void doFilterStuff()
    {
        doFlowStuff(flowRate);
    }
}

class Filter2 implements Filter
{
    void doFilterStuff()
    {
        doDensityStuff(density);
    }
}

请注意,这不会满足您将Box.getFilter返回类型设为您想要的子类型的愿望。getFilter可以返回 aFilter1或 a Filter2,但调用的代码getFilter将看到 a Filter,而不是 a Filter1

或者,如果这在您的情况下没有意义,因为它确实Box应该做这些事情,那么这意味着您可能没有只有一种类型的盒子,并且您正试图将多种不同的Box逻辑塞进 1Box当你真的应该有不同的类型时......

interface Box
{
    void doBoxStuff();
}

class Box1 implements Box
{
    Filter1 filter;

    void doBoxStuff()
    {
        filter.doFlowStuff();
    }
}

class Box2 implements Box
{
    Filter2 filter;

    void doBoxStuff()
    {
        filter.doDensityStuff();
    }
}

也就是说,如果您绝对必须将逻辑放在框中,并且过滤器必须具有不同的属性和方法。如果你这样做,有多种盒子类型,你仍然可以拥有Filter1Filter2继承,Filter如果它们的功能重叠足够,它是有意义的,但Box1不会Box2跟踪泛型Filter,而是只跟踪特定类型的过滤器他们能够合作。毕竟,您不希望Box2尝试对Filter1.

这也允许您让您的盒子从getFilter. Box1可以有Filter1 getFilter,也Box2可以有Filter2 getFilter


推荐阅读