简体   繁体   中英

Type mismatch for extending classes

I'm trying to implement a HashMap. I've already implemented an ArraySet and a KeyValuePair with the following signatures:

public class ArrayList<E> implements List<E>
public class ArraySet<E> extends ArrayList<E> implements Set<E>
class KeyValuePair<K, V> implements Map.Entry<K, V>
public class HashMap<K, V> implements Map<K, V>

For the entrySet method I have the following:

public Set<Entry<K, V>> entrySet() {
    Set<Entry<K,V>> entries = new ArraySet<KeyValuePair<K,V>>();
}

But this gives Type mismatch: cannot convert from ArraySet<KeyValuePair<K,V>> to Set<Map.Entry<K,V>> despite the fact ArraySet implements Set and KeyValuePair implements Map.Entry. I can't change the return type as it's part of the Map interface.

You cannot assign a new Set<KeyValuePair<K,V>>() to a variable declared as Set<Entry<K,V>> for a good reason. If you could, you would then be able to call entries.add(<some item that is a Set.Entry but not a KeyValuePair>) and that would obviously lead to trouble.

To fix your immediate problem, you need to assign a compatible type, so do this:

Set<Entry<K,V>> entries = new ArraySet<Entry<K,V>>();

and then you can add KeyValuePair items to your entries set.

However, your code still has some problems:

  1. You should avoid calling your classes the same name as well-known classes from package java.util . This can lead to confusion when someone reads your code. Choose names other than ArrayList and HashMap. You already have an ArraySet, so why not ArrayMap.

  2. Avoid duplication. You can see the implementation of HashSet in the Java API source: it's actually just a HashMap with dummy values. You can do the same in your code, implementing ArraySet in terms of ArrayMap.

  3. Your ArraySet implements both the List and Set interfaces. You cannot correctly implement both interfaces, as they have conflicting contracts. You shouldn't extend ArrayList. Your ArraySet is a Set, it's not really a List. It's implemented using a List, so you should use a private List member in your implementation.

public class ArraySet<E> extends ArrayList<E> implements Set<E>

ArraySet does both implementing ArrayList and Set.

Set<Entry<K,V>> entries = new ArraySet<KeyValuePair<K,V>>();

Where can Set store ArrayList members?

So, You cannot write the above code. Instead you can do

Set<Entry<K,V>> entries = new Set<KeyValuePair<K,V>>();

Because you can also do, since KeyValue pair only implements Entry and don't do anything else.

Entry<K,V> entries = new KeyValuePair<K,V>();

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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