【问题标题】:Same methods, different enums, how to design a parent class?相同的方法,不同的枚举,如何设计一个父类?
【发布时间】:2019-08-27 18:49:18
【问题描述】:

我的两个 Type 类 SearchType 和 ResultcodeType 需要一个优雅的父类。如何设计这两个类和一个父类都继承自一个干净和节省代码的方式?

public enum SearchType {
    BARCODE(0),
    TEXT(1);

    SearchType(int i)
    {
        this.type = i;
    }

    private int type;

    public static SearchType getType(int value) {
        for (SearchType searchType : SearchType.values()) {
            if (searchType.type == value)
                return searchType;
        }
        throw new IllegalArgumentException("SearchType not found.");
    }

    public int getNumericType() {
        return type;
    }
}

public enum ResultcodeType {
    RESULTS(0),
    NO_RESULTS(1),
    PROBLEMS(2),
    NO_VALUE(-1);

    ResultcodeType(int i)
    {
        this.type = i;
    }

    private int type;

    public static ResultcodeType getType(int value) {
        for (ResultcodeType resultcodeType : ResultcodeType.values()) {
            if (resultcodeType.type == value)
               return resultcodeType;
        }
        throw new IllegalArgumentException("ResultcodeType not found.");
    }

    public int getNumericType() {
        return type;
    }
}

我在哪里使用 SearchType / ResultCodeType?

布局数据绑定

<ImageView
    app:srcCompat="@{item.searchType == SearchType.BARCODE ? @drawable/ic_barcode : @drawable/ic_one_loupe}" 
/>

房间数据库转换器类(再次存在冗余)。但是现在 room 不能在它的 TypeConverter 中处理泛型类型。所以这将保持原样。

@TypeConverter
public static SearchType SearchTypeFromInt(Integer value) {
    return SearchType.getType(value);
}

@TypeConverter
public static ResultcodeType ResultcodeTypeFromInt(Integer value) {
    return ResultcodeType.getType(value);
}

POJO(带房间注释)

@NonNull
@ColumnInfo(name = "resultcode", defaultValue="-1")
private ResultcodeType mResultcode;

【问题讨论】:

  • 为什么他们需要一个父类?在 Java 中,枚举不能从另一个类继承,只能从接口继承。
  • @rgettman 他们共享相同的方法 - 当然有很多冗余。
  • 只是好奇。你为什么要使用一些int value,然后尝试为该值找到enum type?为什么不在课堂上使用枚举本身?这就是他们的目的。
  • @WJS 我将 int 值保存到房间数据库中。
  • @S.Gissel 它们是否共享相同的代码,因为它们在语义上是绑定的,或者它们是否“偶然”共享代码(即两者的实现是否都需要以相同的方式进行更改,或者是否有可能只有一个实现必须改变或两者都必须改变,但不同)?如果它们是偶然共享的,不要通过引入抽象来耦合它们。

标签: java inheritance enums abstract


【解决方案1】:

由于枚举不能有基类,我认为这是你将得到的最接近的:

public interface Typed {
    int getNumericType();

    static <E extends Enum<E> & Typed> E getType(E[] values, int type) {
        for (E value : values)
            if (value.getNumericType() == type)
                return value;
        throw new IllegalArgumentException(values[0].getClass().getSimpleName() +
                                           " not found: " + type);
    }
}
public enum SearchType implements Typed {
    BARCODE(0),
    TEXT(1);

    private final int type;

    private SearchType(int type) {
        this.type = type;
    }

    @Override
    public int getNumericType() {
        return this.type;
    }

    public static SearchType getType(int type) {
        return Typed.getType(values(), type);
    }
}
public enum ResultcodeType implements Typed {
    RESULTS(0),
    NO_RESULTS(1),
    PROBLEMS(2),
    NO_VALUE(-1);

    private final int type;

    private ResultcodeType(int type) {
        this.type = type;
    }

    @Override
    public int getNumericType() {
        return this.type;
    }

    public static ResultcodeType getType(int type) {
        return Typed.getType(values(), type);
    }
}

【讨论】:

    【解决方案2】:

    您的枚举可以实现接口并添加默认方法。

    例如:

    interface Typed {
       Typed getType(int value) 
    
    public enum ResultcodeType implements Typed {
        public Typed getType(int value) {
            for (ResultcodeType resultcodeType : 
            ResultcodeType.values()) {
                if (resultcodeType.type == value)
                   return resultcodeType;
            }
            throw new IllegalArgumentException("ResultcodeType not found.");
        }
    
    
    .... 
    } 
    

    【讨论】:

    • 我正在考虑在父类中接受 ResultCodeType 和 Searchtype 以及其他可能的遗传学,而不是在每个派生类中实现相同的代码行,例如 getType。
    • @S.Gissel “遗传学”是指“通用”?
    • @Turing85 不,我的意思是泛型。
    【解决方案3】:

    我还建议使用地图而不是搜索的以下方法。事实上,您所需要的只是映射。你甚至不需要提供一个值。请注意,您不能从构造函数中引用静态值,因此您必须在外部构建地图。

       enum SearchType {
          BARCODE(0), TEXT(1), UNKNOWN(-1);
          static Map<Integer, SearchType> map =
                Map.of(0, SearchType.BARCODE, 1, SearchType.TEXT);
    
          SearchType(int i) {
             this.type = i;
          }
    
          private int type;
    
          public static SearchType getType(int value) {
             return SearchType.map.getOrDefault(value, SearchType.UNKNOWN);
          }
    
          public int getNumericType() {
             return type;
          }
       }
    
       public static void main(String[] args) {
    
          System.out.println(SearchType.getType(0));
          System.out.println(SearchType.getType(1));
          System.out.println(SearchType.getType(99));
    
       }
    

    【讨论】:

      猜你喜欢
      • 2018-02-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-08-21
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多