• EffectiveJava——接口优于抽象类


      Java程序设计语言提供两种机制,可以用来定义允许多个实现的类型:接口和抽象方法,这两者直接醉为明显的区别在于,抽象类允许某些方法的实现,但接口不允许,一个更为重要的区别在于,为了实现由抽象类定义的类型,类必须成为抽象类的一个子类。任何一个类,只要定义了所有必要的方法,并且遵守通用约定,它就被允许实现一个借口,而不管这个类是处于类层次的哪个位置。因为Java只允许单继承,所有抽象类作为类型定义受到类极大的限制。

      现有的类很容易被更新,以实现新的接口。

      如果你希望让两个类扩展同一个抽象类,就必须把抽象类放到类型层次结构的高处,以便这两个类的一个祖先成为它的子类。遗憾的是这样做会间接到伤害到类层次,迫使这个公共祖先到所有后代类都扩展这个新的抽象类,无论它对于这些后代类是否合适。

      接口是定义混合类型的理想选择。

      接口允许我们构造非层次结构的类型框架。

      假如我们有两个接口,一个表示歌唱家,另一个表示作曲家,在现实生活中,有很多人即是歌唱家又是作曲家,如果是接口,我只需要同时实现这两个接口就可以,如果是抽象类,因为Java是单继承的,我就没有办法描述这一类的人。

      虽然接口不允许包含方法的实现,但是,使用接口来定义类型并不妨碍你为程序猿提供实现上的帮助。通过对你导出的每个重要接口都提供一个抽象骨架的实现类,把接口和抽象类的优点都结合起来。接口的作用仍然是定义类型,但是骨架的实现类接管类所有与接口实现相关的工作。

      骨架为接口提供实现上的帮助,但又不强加“抽象类被用作类型定义时”所特有的严格限制。对于接口大多数的实现来讲,扩展骨架实现类是个很显然的选择,但不是必须的。如果预制的类无法扩展骨架实现类,这个类始终可以收工实现这个接口。此外,骨架实现类仍然有助于接口的实现。实现类这个接口的类可以把对于这个接口方法的调用,转发到一个内部私有类的实例上,这个内部私有类扩展骨架实现类。这种方法被称作模拟多重继承。这项技术具有多重继承的绝大多数有点,同时又避免了相应的缺陷。

      编写骨架实现类相对比较简单,只是有点单调乏味。首先,必须认真研究接口,并确定哪些方法时最为基本的,其他方法则可以根据它们来实现。这些方法将成为骨架实现类中的抽象方法。然后,必须为接口中的所有其他的方法提供具体实现。例如,下面是Map.Entry接口的骨架实现类:

    /**
     * 接口优于抽象类
     * @author weishiyao
     *
     * @param <K>
     * @param <V>
     */
    // Skeletal Implementation
    public abstract class AbstractMapEntry<K, V> implements Map.Entry<K, V>{
    
    	// Primitive operations
    	public abstract K getKey();
    	public abstract V getValue();
    	
    	// Entries in modifiable maps must override this method
    	public V setValue(V value) {
    		throw new UnsupportedOperationException();
    	}
    	
    	// Implements the general contract of Map.Entry.equals
    	@Override
    	public boolean equals(Object obj) {
    		if (obj == this) {
    			return true;
    		}
    		if (!(obj instanceof Map.Entry)) {
    			return false;
    		}
    		Map.Entry<?, ?> arg = (Map.Entry) obj;
    		return equals(getKey(), arg.getKey()) && equals(getValue(), arg.getValue());
    	}
    	
    	private static boolean equals(Object obj1, Object obj2) {
    		return obj1 == null ? obj2 == null : obj1.equals(obj2);
    	}
    	
    	// Implements the general contract of Map.Entry.hashCode
    	@Override
    	public int hashCode() {
    		return hashCode(getKey()) ^ hashCode(getValue());
    	}
    	
    	private static int hashCode(Object obj) {
    		return obj == null ? 0 : obj.hashCode();
    	}
    }
    

       骨架实现类时为了继承的目的而设计的,这种使用方式在平时开发中经常可以见到,很多框架中都有使用方式,之前为也是见过好多次框架中这么使用,大致能明白这么写是干什么,这次经过这么详细讲解,算是彻底明白为什么要这么使用了,能想到这种写法的人真的也是大神了。

      

     

      

  • 相关阅读:
    #include <utility>
    Html的空格显示
    ExtJs自学教程(1):一切从API開始
    天黑的时候,我又想起那首歌
    citrix协议ICA技术原理
    约瑟夫环问题
    数据结构和算法设计专题之---八大内部排序
    HDU
    深入分析C++引用
    八大排序算法总结
  • 原文地址:https://www.cnblogs.com/babycomeon/p/5585801.html
Copyright © 2020-2023  润新知