java – 在创建时告诉类成员变量的类型

假设我有一个Citydistrict类,如下所示:

class Citydistrict {
    List<House> houses;
    ...
}

假设对于某些用例,ArrayList更适合于房屋,有时甚至是LinkedList.您如何告诉Citydistrict创建它应该用于房屋的类

我的三个想法是:

1)这是参数类的用例吗?就像是

class Citydistrict<T> {
    T<House> houses;
    ...
}

然后,您可以创建Citydistrict< ArrayList>.但是我认为T应该是List类型的信息在这里丢失了.

2)或者您可以创建几个构造函数或静态工厂方法,如generateArrayListCitydistrict,但我认为这有点难看.

3)在构造函数Citydistrict(int ListFlag)中使用某种标志变量,并将1映射到ArrayList,依此类推.我觉得还有点难看.

我错过了明显的吗?什么是干净和OOP处理这种情况的方式?

解决方法

您可以传递供应商< List< House>>到构造函数.它将决定实例应该使用的实现:

class Citydistrict {

    List<House> houses;

    public Citydistrict(supplier<List<House>> implementation) {
        houses = implementation.get();
    }

    public static void main(String[] args) {
        Citydistrict arrayListImpl = new Citydistrict(ArrayList::new);
        Citydistrict linkedListImpl = new Citydistrict(LinkedList::new);
    }

}

但是,当您的API用户可以决定在内部使用哪些实现时(尤其是它可能会影响某些性能问题)时,我不确定它是否正常.这打破了封装规则.如果您关心OOP技术(通常应该做什么),这很重要.

我宁愿提供认实现(这里的ArrayList是一个不错的选择)并添加通过工厂方法切换到所需实现的能力:

class Citydistrict {

    List<House> houses;

    private Citydistrict(supplier<List<House>> supplier) {
        houses = supplier.get();
    }

    public Citydistrict() {
        this(ArrayList::new);
    }

    public Citydistrict with(supplier<List<House>> implementation) {
        return new Citydistrict(implementation);
    }

}

相关文章

Java中的String是不可变对象 在面向对象及函数编程语言中,不...
String, StringBuffer 和 StringBuilder 可变性 String不可变...
序列化:把对象转换为字节序列的过程称为对象的序列化. 反序...
先说结论,是对象!可以继续往下看 数组是不是对象 什么是对...
为什么浮点数 float 或 double 运算的时候会有精度丢失的风险...
面试题引入 这里引申出一个经典问题,看下面代码 Integer a ...