简体   繁体   English

将 Java 中的变量初始化为不同类的实例,但初始化关键字相同

[英]Initializing variables in Java as instances of different classes but same initializing keyword

I am new to Java and I finally faced with a problem that I have been postponing for a long time.我是 Java 的新手,我终于遇到了一个我已经推迟了很长时间的问题。

I was learning LinkedLists in Java and have the following confusion, please check:我在Java中学习LinkedLists,有以下困惑,请查看:

import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;

public class LinkedListDemo {
    public static void main(String[] args) {
        List<Integer> myList = new LinkedList<Integer>();

        myList.add(1);
        myList.add(22);
        myList.add(42);

        Iterator it = myList.iterator();

        while(it.hasNext()){
            if((int)(it.next()) == 42)
                System.out.println("We found 42");
        }

        myList.remove();
        System.out.println(myList);
    }
}

Here myList.remove();这里 myList.remove(); gives the following error: "cannot resolve the method 'remove'."给出以下错误:“无法解析方法'remove'。”

however, if I instantiate myList variable like this但是,如果我像这样实例化 myList 变量

LinkedList<Integer> myList = new LinkedList<Integer>();

I don't have the same error and my code compiles successfully.我没有同样的错误,我的代码编译成功。

I just want to know the working behind this.我只想知道这背后的工作。 I mean sometimes I declare ArrayList variables with我的意思是有时我声明 ArrayList 变量

List myList = new ArrayList<>();

should I instead declare like this?我应该这样声明吗?

ArrayList myList = new ArrayList<>();

thank you谢谢你

Separate abstraction from implementation将抽象与实现分开

Separate abstraction from implementation allows to code thinking in "I know I'll need here and there a List , but I still don't know/want to choose which kind of List at this moment" or: "I'd like to keep my options open to any List implementation here and there in my code".从实现中分离抽象允许在“我知道我需要在这里和那里一个List ,但我现在仍然不知道/想要选择哪种List ”或“我想保留我的选项对我的代码中的任何List实现开放”。 This is good thing to ease coding.这是简化编码的好方法。

LinkedList and ArrayList are less abstract than List , which means that these are different implementations of List . LinkedListArrayList没有List抽象,这意味着它们是List的不同实现。 Usually you will prefer to use more abstract classes, like List on this case, to separate abstraction from implementation, which is usually a good thing, eg to play with different implementations without changing the rest of your code.通常你会更喜欢使用更多的抽象类,比如在这种情况下的List ,将抽象与实现分开,这通常是一件好事,例如在不改变代码的 rest 的情况下使用不同的实现。 So:所以:

List<Integer> myCoolList = new LinkedList<Integer>()

is usually better (as it promotes separation between abstraction and implementation, which is a good habit for your code) than:通常比:

LinkedList<Integer> myCoolList = new LinkedList<Integer>()

Now, if you choose to separate abstraction from implementation, of course you will lose the power to use methods specific for each implementation.现在,如果您选择将抽象与实现分开,当然您将失去使用特定于每个实现的方法的能力。 But usually the most general class (in this case, List ) will give enough alternatives to replace the lost methods ( the LinkedList.remove() method in this case)但通常最通用的 class (在本例中为List )将提供足够的替代方法来替换丢失的方法(在本例中为LinkedList.remove()方法)

Typically your remove method should have parameters.通常,您的删除方法应该有参数。

The List interface doesn't have any remove() method without params. List 接口没有任何没有参数的remove()方法。

So when your compiler statically checks your code, cannot find a matching method.因此,当您的编译器静态检查您的代码时,找不到匹配的方法。

On the other hand, LinkedList has it.另一方面,LinkedList 有它。 So that's why your code works.所以这就是你的代码有效的原因。

Check the java docs for List and the LinkedList .查看 java 文档中的ListLinkedList

List 列表

LinkedList 链表

You can check the original code of the link, you can see that it has a remove() method that does not contain any parameters:你可以查看链接的原始代码,可以看到它有一个不包含任何参数的 remove() 方法:

 /**
 * Retrieves and removes the head (first element) of this list.
 *
 * @return the head of this list
 * @throws NoSuchElementException if this list is empty
 * @since 1.5
 */
public E remove() {
    return removeFirst();
}

However, this remove() method does not exist in the List class, the parent class of LinkedList, so when you declare in this way:但是这个remove()方法在LinkedList的父class的List class中是不存在的,所以这样声明的时候:

 List<Integer> myList = new LinkedList<Integer>();

You will not be able to use the remove() method.您将无法使用 remove() 方法。

But if you use LinkedList initialization, then you will be able to use it, because remove() is unique to the subclass LinkedList.但是如果你使用 LinkedList 初始化,那么你将能够使用它,因为 remove() 对于子类 LinkedList 是唯一的。

 LinkedList<Integer> myList = new LinkedList<Integer>();

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

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