• 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();
        }
    }
  • 相关阅读:
    原创:PHP编译安装配置参数说明
    原创 :xftp SFTP子系统申请已拒绝 请确保SSH链接的SFTP子系统设置有效
    原创:LNMP架构部署个人博客网站 禁止转载复制
    原创 :单刷深渊 在Linux中系统安装mysql实战直播
    原创:一键化部署百台服务器级别后端服务器
    原创 :nfs软件服务利用ansible实现一键化部署
    原创: rsync软件服务利用ansible实现一键化部署
    原创:100 台规模集群存储系统搭建及数据实时备份
    原创Couldn't read packet: Connection reset by peer 错误排查思路(推荐)
    原创:Docker在云家政的应用 谢绝复制粘贴内容
  • 原文地址:https://www.cnblogs.com/qwop/p/6637295.html
Copyright © 2020-2023  润新知