当前位置: 首页 > 面试题库 >

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

骆嘉石
2023-03-14
问题内容

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

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);

问题答案:

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

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变量。



 类似资料:
  • 我在Java中读到了关于将超类变量类型化为子类的知识,反之亦然。请告诉我哪些是有效的? 动物是超级类,有猫和狗子类。

  • 如果我有以下代码 首先,这甚至是可能的,因为它编译得很好。但是我不能使用中的方法执行操作: makeCan是否不同时返回Can和PromotionalCan?如果是这样,当返回PromotionalCan时,如何对变量进行操作?谢谢 编辑:PromotionalCan继承自Can,第二种方法是在PromotionalCan中

  • 来自JavaScript背景,我发现以下代码有点过于健壮,包含多条语句;我想知道如何简化代码,并在一条语句中完成所有操作。 Student是超类,Friend和Schedule是聚合到超类ArrayList公共成员中的子类(这些不是嵌套类)。这是我当前的代码: 我想知道我是否可以做这样的事情,在一个语句中声明/实例化超类和子类;这可能吗?

  • 问题内容: 我了解在创建这样的新对象时: 更通用,并且允许更多的可重用性,但是当创建tri时会发生以下情况: 由于Triangle是GeomObject的子类,因此tri还是不是GeomObject?声明的类型如何影响编译?谢谢 add:另一个问题:说我有 Integer n1 = new Integer(3); Object n2 = new Integer(4); System.out.pri

  • “绑定不匹配:Team类型不是league类型 的有界参数 >的有效替代品。”

  • 问题内容: 为什么必须始终在类声明之后编写?例如: 为什么不能这样: 后者会产生编译时错误。 问题答案: 当Java编译器将类转换为字节码时,它必须首先查找父类。这是因为类的基础实现是指向父类的字节码-包含相关的方法和字段。然后,它添加指向子类函数代码的指针-其中一些由’implements’关键字强制执行。 因为父类必须是可编译的,所以如果编译器预先知道该类是什么,则会更容易。此外,您只能扩展一