简体   繁体   English

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

[英]Using SuperClass as reference instead of SubClass?

To implement a Queue, why do we use? 要实现队列,我们​​为什么要使用?

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

I mean a Superclass reference, why don't we use a LinkedList reference? 我的意思是超类引用,为什么我们不使用LinkedList引用?

We have a design principle called Code to interfaces never with concrete implementations 我们有一个名为Code的设计原则,从不与具体实现接口

Here Queue is an Interface which can hold implementation class 这里Queue是一个可以保存实现类的接口

Advantages over above principle 优于上述原则的优点

1.Switching between multiple implementations become easy in future 1.将来很容易在多个实现之间切换

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

2.If we won't use above principle we loose key Object oriented concept polymorphism. 如果我们不使用上述原则,我们就会失去关键的面向对象的概念多态性。

Avoid unnecessary restrictions 避免不必要的限制

You should always try to declare your variables with the least unnecessary restriction; 你应该总是尝试用最少的不必要的限制来声明你的变量; often that means to an interface like Queue or Collection. 通常这意味着像Queue或Collection这样的界面。 This allows you to more easily change your implementation. 这使您可以更轻松地更改您的实现。 I will use two classes from the collections framework as my example but the principle is general. 我将使用集合框架中的两个类作为我的示例,但原则是通用的。

Imagine the following objective: 想象一下以下目标:

I need 2 collections that can have objects added to it. 我需要2个可以添加对象的集合。 And I also need to be able to find which objects are in both collections. 而且我还需要能够找到两个集合中的哪些对象。 So in other words I need the following methods 换句话说,我需要以下方法

Collection#add
Collection#retainAll

These are both within Collection so any collection will do. 这些都在Collection内,所以任何集合都可以。 Collection is an interface so I need to choose a concrete implementation. Collection是一个接口,所以我需要选择一个具体的实现。 I choose ArrayList, on a whim. 我一时兴起选择ArrayList。 My code is the following: 我的代码如下:

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

This code works fine and does exactly what I asked it to do. 这段代码工作正常,完全符合我的要求。 However; 然而; in profiling I find that it is a bottleneck. 在剖析中我发现它是一个瓶颈。 So I test out different implentations of the Collection class and profile the results. 因此,我测试了Collection类的不同实现并分析了结果。

在此输入图像描述

As you can see, for the retainAll operation the HashSet turned out to be much better. 正如您所看到的,对于retainAll操作,HashSet变得更好。 So I can change my implementation by changing just new ArrayList<>(); 所以我可以通过改变new ArrayList<>();来改变我的实现new ArrayList<>(); to new HashSet<>(); new HashSet<>(); in one place. 在一个地方。 No need to change every other method I've used to HashSet as well because they don't care, as long as they get some sort of Collection they are happy 不需要改变我用过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
}

Well that was easy. 那很容易。 Now imagine a much larger application with dozens of methods; 现在用几十种方法想象一个更大的应用程序; all of which could be hardcoded to use ArrayList even though they didn't need to, all of which you would now need to manually alter. 所有这些都可以硬编码以使用ArrayList即使它们不需要,所有这些都需要手动更改。

To implement a Queue,why do we use?

No one can really assert that this is the patter that everyone must follow. 没有人能够断言这是每个人都必须遵循的模式。 You can very well use 你可以很好地使用

LinkedListq=new LinkedList();

Reason above patter is used frequently because it offers the power of polymorphism. 经常使用上述模式的原因,因为它提供了多态性的力量。 To explain it in short you now need a LinkedList but later you may need PriorityQueue . 简而言之,您现在需要一个LinkedList但稍后您可能需要PriorityQueue To use same reference for multiple concrete classes we use above pattern. 要对多个具体类使用相同的引用,我们使用上面的模式。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM