部分继承Java中的接口?

时间:2018-05-08 18:09:05

标签: java oop

我想实现一个简单的Cache接口:

public interface Cache {
    Object get(Object key);
    Object put(Object key, Object value);
    void clear();
}

我意识到它是java.util.Map接口的一部分。因此,像HashMap这样的对象应该能够传递给需要Cache对象的函数。

但另一方面,我不想让我自己的Cache类实现整个Map接口,因为我不需要除了这三个之外的其他方法。

Java不是一种鸭式语言,所以在这种情况下最好的做法是什么?

3 个答案:

答案 0 :(得分:2)

我认为你可以在Cache

的实现中包装Map
class CacheImpl<K, V> implements Cache<K, V> {
    Map<K, V> cacheMap;

    CacheImpl() {
        this(new LinkedHashMap<>());
    }

    CacheImpl(Map<K,V> cacheMap) {
        this.cacheMap = cacheMap;
    }

    @Override
    public V get(K key) {
        return cacheMap.get(key);
    }

    @Override
    public V put(K key, V value) {
        return cacheMap.put(key, value);
    }

    @Override
    public void clear() {
        cacheMap.clear();
    }
}

我已经使用Generic添加了示例,但您可以随意使用Object作为键和值。

因此,在我的示例中,为了使其线程安全我们可以ConcurrentHashMap已经thread safe并且已经很好地实现了。我建议使用Factory类来创建缓存对象,如下所示。

class CacheImplFactory {
    public static <K, V> Cache<K, V> newSimpleCache() {
        return new CacheImpl<K, V>();
    }

    public static <K, V> Cache<K, V> newSynchronizedCache() {
        return new CacheImpl<K, V>(new ConcurrentHashMap<>());
    }

    public static <K, V> Cache<K, V> newWeakCache() {
        return new CacheImpl<K, V>(new WeakHashMap<>());
    }
}

答案 1 :(得分:2)

java中没有这样的功能。

我认为你能做的最好的事情是在你担心的时候创建一个HashMap的包装器。

界面是合约。实现的类应该通过实现虚拟/抽象方法来填充合同。

您的CacheImpl仅使用Cache界面填写合同。同时HashMap仅使用Map界面填写合同。

具有相同签名的CacheMap接口共享方法,但它们需要不同的合同/实现。

您实际上无法确定某个界面是否包含与您的Object put(Object key, Object value);界面兼容的方法Cache,因为您不了解该界面提供的合同。

所以在Java中,除非他们提供语义来创建现有界面的 &#34; parent&#34; 界面,否则你不能这样做。

答案 2 :(得分:1)

如果我理解你的问题,你就会问如何使用像HashMap这样的现有java类来支持接口。

您必须创建自己的实现来实现您的接口,并扩展HashMap。

Interface方法会将操作委托给HashMap。通过这种方式,您的自定义类将满足具有接口签名的任何Method的接口需求。

一个工作示例我聚集在一起展示如何做你在泛型中提出的问题:

缓存接口:

package interfaces;

public interface Cache<K,V> {
    V get(K key);
    V put(K key, V value);
    void clear();
}

实施:

package classes;

import java.util.HashMap;
import interfaces.Cache;

public class MyCache<K,V> extends HashMap<K,V> implements Cache<K,V> {

    private static final long serialVersionUID = 1L;

    @Override
    public V get(Object key) {
        return super.get(key);
    }

    @Override
    public V put(K key, V value) {
        return super.put(key, value);
    }

    @Override
    public void clear() {
        super.clear();
    }
}

然后您可以这样使用它:

import classes.MyCache;
import interfaces.Cache;

public class DoStuff {

    private Cache<String,Integer> cache;

    public void initCache() {
        //This works
        //Since MyCache implements Cache
        MyCache<String,Integer> mCache=new MyCache<String,Integer>();
        setCache(mCache);

        //This will not
        //Since HashMap does not implement Cache
        HashMap<String,Integer> mMap=new HashMap<String,Integer>();
        setCache(mMap);
    }

    public void setCache(Cache<String,Integer> c) {
        cache=c;
    }

    public Cache<String,Integer> getCache() {
        return cache;
    }
}