一尘不染

为什么在实例化子类型之前先声明子类型为它们的超类型?

java

阅读其他人的代码,我已经看到很多:

List<E> ints = new ArrayList<E>();
Map<K, V> map = new HashMap<K, V>();

我的问题是:用这种方式实例化它们的目的/优点是什么,而不是:

ArrayList<E> ints = new ArrayList<E>();
HashMap<K, V> map = new HashMap<K, V>();

令我感到奇怪的是,我从未见过类似的东西:

CharSequence s = new String("String");

要么

OutputStream out = new PrintStream(OutputStream);

阅读 221

收藏
2020-12-03

共1个答案

一尘不染

快速回答?使用接口和超类可以提高代码的可移植性和可维护性,主要是通过隐藏实现细节。采取以下假设示例:

class Account {
    private Collection<Transaction> transactions;

    public Account() {
        super();
        transactions = new ArrayList<Transaction>(4);
    }

    public Collection<Transaction> getTransactions() {
        return transactions;
    }
}

我已经声明了一个帐户合同,该合同规定可以将已发布到该帐户的交易作为集合进行检索。我的代码的调用者不必关心我的方法实际上返回的集合类型,也不应该这样做。这样,如果需要,我可以自由地更改内部实现,而不会影响(也称为破坏)未知数量的客户端。因此,如果我发现我需要在事务上施加某种独特性,则可以将上面显示的
实现 从ArrayList更改为HashSet,而对使用我的类的任何人都没有负面影响。

public Account() {
    super();
    transactions = new HashSet<Transaction>(4);
}

关于您的第二个问题,我可以说您在任何有意义的地方都使用了可移植性和封装性原则。那里没有很多CharSequence实现,而String是迄今为止最常用的实现。因此,您不会看到很多开发人员在其代码中声明CharSequence变量。

2020-12-03