zoukankan      html  css  js  c++  java
  • EffectiveJava(18)接口优先于抽象类

    ***接口和抽象类同样可以用来定义多个实现的类型,然而,接口通常是最佳途径.***
    

    这条规则有个例外 – 当演变的容易性比灵活性和功能性更为重要的时候,应该用抽象来定义类型
    ,但前提是必须理解并且可以接受这些局限性.
    接口
    1.现在的类可以很容易被更新,以实现新的接口
    2.接口式定义mixin的理想选择
    3.接口允许我们构造非层次结构的类型框架

        public interface ISinger {
            AudioClip sing(Song song);
        }
    
        public interface ISongWriter {
            Song compose(boolean hit);//构成 冲击
        }

    定义一个接口同时实现ISinger和ISongWriter

        public interface ISingerSongWriter extends ISinger,ISongWriter{
            AudioClip strum();//音频剪辑弹奏
            void actSensitive();//行为敏感
        }

    抽象类
    1.如果使用抽象类定义类型,那么必须使用继承的手段来增加功能
    2.演变的容易性比灵活性和功能性更为重要的时候,应该用抽象来定义类型
    3.抽象类的演变比接口的演变容易得多

    通过对导出的每个重要接口都提供一个抽象的骨架实现类,把接口和抽象类的优点结合起来
    接口的作用仍然是定义类型,但是骨架实现类接管了所有域接口实现相关的工作
    骨架实现–

    static List<Integer> intArrayAsList(final int[] a){
            if(a == null)
                throw new NullPointerException();
            return new AbstractList<Integer>() {
                public Integer get(int i){
                    //自动装箱
                    return a[i];
                }
                public Integer set(int i,int val){
                    int oldval = a[i];
                    //自动拆箱
                    a[i] = val;
                    自动装箱
                    return oldval;
                }
                public int size(){
                    return a.length;
                }
            };
        }

    骨架为抽象类提供了实现上的帮助,但又不强加抽象类被用作类型定义时所特有的严格限制

    模拟多重继承:实现了接口的类可以把对于接口的方法调用,转发到一个内部私有类的实例上,这个内部私有类扩展了股价实现类

    编写骨架方法必须确定哪些方法是最基本的,其他的方法可以根据他们来实现.这些基本的方法将成为股价实现类中的抽象方法,
    

    然后必须为接口中所有其他的方法提供具体的实现.
    –例如Map.Entry接口的骨架实现类

    public abstract AbstractMapEntry<K,V> implements Map.Entry<K,V> {
        public abstract K getKey();
        public abstract V getValue();
    
        @Override
        public V setValue(V value) {
            // TODO Auto-generated method stub
            return (V) new UnsupportedOperationException();
        }
    
        @Override
        public boolean equals(Object o){
            if(o==this)
                return true;
            if(!(o instanceof Map.Entry))
                return false;
            Map.Entry<K, V> arg = (Entry<K, V>) o;
            return equals(getKey(),arg.getKey())&&
                    equals(getValue(),arg.getValue());
        }
        private boolean equals(Object o1,Object o2){
            return o1 == null? o2 == null: o1.equals(o2);
        }
    
        @Override
        public int hashCode(){
            return hashCode(getKey())^hashCode(getValue());
        }
    
        private int hashCode(Object o){
            return o == null?0:o.hashCode();
        }
    }
  • 相关阅读:
    硬盘任性丢数据,但分布式存储一定可靠吗?
    Service的基本组成
    固定cell.imageView.image的大小
    剪贴板服务
    取得正在运行的Activity
    取得正在运行的服务
    C#.NET学习笔记1---C#.NET简介
    取得手机的网络信息
    四、cocos2dx动画Animation介绍
    C#.NET学习笔记2---C#.第一个C#程序
  • 原文地址:https://www.cnblogs.com/qwop/p/6637295.html
Copyright © 2011-2022 走看看