使用SuperClass作为参考而不是SubClass?

时间:2014-05-07 13:20:16

标签: java class generics inheritance

要实现队列,我们​​为什么要使用?

Queue<Integer> q = new LinkedList<Integer>();

我的意思是超类引用,为什么我们不使用LinkedList引用?

3 个答案:

答案 0 :(得分:1)

我们有一个名为代码的设计原则,从不与具体实现接口

这里Queue是一个可以保存实现类

的接口

优于上述原则

1.将来很容易在多个实现之间切换

 So it is always recommonded to code to interface instead of concrete implementations

2.如果我们不能使用上述原则,我们就会失去关键的面向对象的概念多态性。

答案 1 :(得分:1)

避免不必要的限制

你应该总是尝试用最少的不必要的限制来声明你的变量;通常这意味着像Queue或Collection这样的界面。这使您可以更轻松地更改您的实现。我将使用集合框架中的两个类作为我的示例,但原则是通用的。

想象一下以下目标:

  

我需要2个可以添加对象的集合。我也   需要能够找到两个集合中的对象。所以   换句话说我需要以下方法

Collection#add
Collection#retainAll

这些都在Collection中,所以任何集合都可以。 Collection是一个接口,所以我需要选择一个具体的实现。我一时兴起选择ArrayList。我的代码如下:

public static void main(String[] args){
    Collection<Integer> a=new ArrayList<>();
    Collection<Integer> b=new ArrayList<>();

    initialise(a);
    initialise(b);
    testRetain(a,b);
}

public static void initialise(Collection<Integer> collection){
    Random rnd=new Random();


    for(int i=0;i<1000;i++){
        collection.add(rnd.nextInt());
    }
}

public static void testRetain(Collection<Integer> collection1, Collection<Integer> collection2){
    collection1.removeAll(collection2);
}

此代码工作正常,完全符合我的要求。然而;在剖析中我发现它是一个瓶颈。因此,我测试了Collection类的不同实现并对结果进行了分析。

enter image description here

正如您所看到的,对于retainAll操作,HashSet变得更好。因此,我可以通过在一个位置仅将new ArrayList<>();更改为new HashSet<>();来更改我的实施。不需要改变我曾经习惯HashSet的所有其他方法,因为他们不关心,只要他们得到某种Collection他们很高兴

public static void main(String[] args){
    Collection<Integer> a=new HashSet<>();
    Collection<Integer> b=new HashSet<>();

    initialise(a); //<--no need to alter this method
    initialise(b);
    testRetain(a,b); //<--no need to alter this method
}

那很容易。现在用几十种方法想象一个更大的应用程序;所有这些都可以硬编码以使用ArrayList,即使他们并不需要,所有这些都需要手动更改。

答案 2 :(得分:0)

To implement a Queue,why do we use?

没有人能够断言这是每个人都必须遵循的模式。你可以 好好用

LinkedListq=new LinkedList();

经常使用上述模式的原因,因为它提供了多态性的力量。简而言之,您现在需要LinkedList,但稍后您可能需要PriorityQueue。要对多个具体类使用相同的引用,我们使用上面的模式。