范文健康探索娱乐情感热点
投稿投诉
热点动态
科技财经
情感日志
励志美文
娱乐时尚
游戏搞笑
探索旅游
历史星座
健康养生
美丽育儿
范文作文
教案论文

JAVA冷知识JAVA居然支持多继承吗?让我们用内部类去实现吧

  写在前面JAVA冷知识 ,今天和小伙伴分享的是通过内部类的方式实现 JAVA的多继承 一个 Demo 和JDK源码 中的具体场景部分内容参考  《编写高质量代码(改善Java程序的151个建议)》《Effective Java》中文版第3版 博文理解有误的地方小伙伴留言私信一起讨论
  与亲近之人不要说气话,不要说反话,不要不说话。——烽火戏诸侯 《剑来》
  众多周知,对于面向对象语言来讲,JAVA是不支持多继承的,只支持单继承,但是提供了接口来补偿。
  在实际的项目中,接口更多的用于行为的委托,把类本身一些是共性但又是特定的行为委托给一个接口的具体实现,当然接口也可以用于属性的委托,对象结构型的设计模式大都采用接口的方式来实现对对象内部组成的注册和操作
  如果实现java的多继承,其实很简单,关键是对于内部类的特征的掌握,内部类可以继承一个与外部类无关的类,保证了内部类天然独立性,根据这个特性从而实现一个类可以继承多个类的效果
  下面我们看一个Demo,声明父母两个接口,实现父母两个类,看如何通过内部类来继承父母类,而不是通过,接口委托的方式, 一个Demo
  父亲接口 package com.liruilong;  /**  * @Project_name: workspack  * @Package: com.liruilong  * @Description: 父亲接口  * @Author: 1224965096@qq.com  * @WeChat_Official_Accounts: 山河已无恙  * @blog: https://liruilong.blog.csdn.net/  * @Date: 2022/2/12  2:48  */ public interface Father {     /**      * @return: int      * @Description 强壮的行为      * @author LiRuilong      * @date  2022/2/12  2:49      **/      int strong(); }
  父亲实现类 package com.liruilong;  /**  * @Project_name: workspack  * @Package: com.liruilong  * @Description: 父亲类  * @Author: 1224965096@qq.com  * @WeChat_Official_Accounts: 山河已无恙  * @blog: https://liruilong.blog.csdn.net/  * @Date: 2022/2/12  2:51  */ public class FatherImpl implements Father {      static  public   String height = "身体超高";     /**     * @return: int     * @Description  强壮值     * @author LiRuilong     * @date  2022/2/12  2:51     **/     @Override     public int strong() {         return 8;     } }
  母亲接口 package com.liruilong;  /**  * @Project_name: workspack  * @Package: com.liruilong  * @Description: 母亲接口  * @Author: 1224965096@qq.com  * @WeChat_Official_Accounts: 山河已无恙  * @blog: https://liruilong.blog.csdn.net/  * @Date: 2022/2/12  2:50  */ public interface Mother {    /**     * @return: int     * @Description 温柔的行为     * @author LiRuilong     * @date  2022/2/12  2:50     **/    int Kind(); }
  母亲实现类 package com.liruilong;  /**  * @Project_name: workspack  * @Package: com.liruilong  * @Description: 母亲类  * @Author: 1224965096@qq.com  * @WeChat_Official_Accounts: 山河已无恙  * @blog: https://liruilong.blog.csdn.net/  * @Date: 2022/2/12  2:51  */ public class MotherImpl implements Mother{     static   public  String pretty = "脸蛋特别漂亮";    /**     * @return: int     * @Description 温柔值     * @author LiRuilong     * @date  2022/2/12  2:51     **/     @Override     public int Kind() {         return 8;     } }
  OK,准备工作做好了, 看我们如何实现。 package com.liruilong;  import java.util.logging.Logger;  /**  * @Project_name: workspack  * @Package: com.liruilong  * @Description: 孩子类  * @Author: 1224965096@qq.com  * @WeChat_Official_Accounts: 山河已无恙  * @blog: https://liruilong.blog.csdn.net/  * @Date: 2022/2/12  13:16  */ public class Son extends FatherImpl implements Mother {     static Logger logger = Logger.getAnonymousLogger();      MotherSpecial motherSpecial = new MotherSpecial();       @Override     public int strong() {         return super.strong() + 1;     }      @Override     public int Kind() {         return motherSpecial.Kind();     }       @Override     public String toString() {         return "Son{" +                 "height=" + height +"," +                 "pretty=" + MotherSpecial.pretty +                 "}";     }       public class MotherSpecial extends MotherImpl {         @Override         public int Kind() {             return super.Kind() - 1;         }     }      public static void main(String[] args) {         Son son = new Son();         logger.info(son.toString());         logger.info(son.strong()+"");         logger.info(son.Kind()+"");     }  }
  我们用内部类继承一个外部类无关的类,实现了 Son 类的多继承Bad level value for property: .level Bad level value for property: java.util.logging.ConsoleHandler.level Can""t set level for java.util.logging.ConsoleHandler 二月 12, 2022 2:02:06 下午 com.liruilong.Son main 信息: Son{height=身体超高,pretty=脸蛋特别漂亮} 二月 12, 2022 2:02:06 下午 com.liruilong.Son main 信息: 9 二月 12, 2022 2:02:06 下午 com.liruilong.Son main 信息: 7  Process finished with exit code 0
  这里只是讨论这样的写法,我个人认为,这种方法有些 鸡肋 。这种方式实现的多继承 ,完全可以通组合 的方式来实现,我们简单分析一下优缺点优缺点分析优点:
  通过内部类的方式,把继承关系控制在类的内部,理论上 比通过组合的方式更加安全 ,代码可读性要好一点。
  更符合设计原则中的 迪米特法则 ,又称最少知道原则(Demeter Principle),一个实体应当尽量少地与其他实体之间发生相互作用,使得系统功能模块相对独立。缺点:
  首先通过继承的方式实现, 打破了类的封装性 ,子类依赖于其超类中特定功能的实现细节。 超类的实现有可能会随着发行版本的不同而有所变化,如果真的发生了变化,即使子类的代码完全没有改变,但是子类可能会遭到破坏因而,子类必须要跟着其超类的更新而演变,除非超类是专门为了扩展而设计的,并且具有很好的文挡说明 。
  其次,通过这样的方式实现的,不符合常态思想,尤其内部类同名的情况,容易被忽略某些特性(见JDK源码)。 JDK源码中的运用
  关于通过内部类来实现 java多继承 的JDK 场景,我们简单分析一下asListList integers = Arrays.asList(1, 2, 3);
  这个代码小伙伴们一定不陌生,这里通过 Arrays 工具类来生成一个List ,但是这里的List 并不是真正的ArrayList ,而是在Arrays工具类 内部定义的一个继承了AbstractList的静态内部类ArrayList ,这里java通过内部类的方式巧妙的实现了。  .......     @SafeVarargs     @SuppressWarnings("varargs")     public static  List asList(T... a) {         return new ArrayList<>(a);     }      /**      * @serial include      */     private static class ArrayList extends AbstractList         implements RandomAccess, java.io.Serializable     {         private static final long serialVersionUID = -2764017481108945198L;         private final E[] a;          ArrayList(E[] array) {             a = Objects.requireNonNull(array);         }     .................
  但是这里同样需要注意的是 通过内部类实现多继承要考虑其类的特殊性 :
  这样生成的 List 调用add 方法会抛不支持的操作的异常 ,基于Arrays 的ArrayList 是一个静态私有内部类,除了Arrays能访问以外,其他类都不能访问,正常的ArrayList中add方法是ArrayList父类提供,Arrays的内部类ArrayList没有覆写add方法。
  下面源码为 ArrayList静态内部类 实现的个方法。    /**      * @serial include      */     private static class ArrayList extends AbstractList         implements RandomAccess, java.io.Serializable     {         private static final long serialVersionUID = -2764017481108945198L;         private final E[] a;          ArrayList(E[] array) {             a = Objects.requireNonNull(array);         }          @Override         public int size() {             return a.length;         }          @Override         public Object[] toArray() {             return a.clone();         }          @Override         @SuppressWarnings("unchecked")         public  T[] toArray(T[] a) {             int size = size();             if (a.length < size)                 return Arrays.copyOf(this.a, size,                                      (Class<? extends T[]>) a.getClass());             System.arraycopy(this.a, 0, a, 0, size);             if (a.length > size)                 a[size] = null;             return a;         }          @Override         public E get(int index) {             return a[index];         }          @Override         public E set(int index, E element) {             E oldValue = a[index];             a[index] = element;             return oldValue;         }          @Override         public int indexOf(Object o) {             E[] a = this.a;             if (o == null) {                 for (int i = 0; i < a.length; i++)                     if (a[i] == null)                         return i;             } else {                 for (int i = 0; i < a.length; i++)                     if (o.equals(a[i]))                         return i;             }             return -1;         }          @Override         public boolean contains(Object o) {             return indexOf(o) != -1;         }          @Override         public Spliterator spliterator() {             return Spliterators.spliterator(a, Spliterator.ORDERED);         }          @Override         public void forEach(Consumer<? super E> action) {             Objects.requireNonNull(action);             for (E e : a) {                 action.accept(e);             }         }          @Override         public void replaceAll(UnaryOperator operator) {             Objects.requireNonNull(operator);             E[] a = this.a;             for (int i = 0; i < a.length; i++) {                 a[i] = operator.apply(a[i]);             }         }          @Override         public void sort(Comparator<? super E> c) {             Arrays.sort(a, c);         }     }
  即没有实现 add 和remove 方法,所以asList 返回的为一个长度不可变的列表 ,数组为多长转换为列表为多长,即不在保持列表动态变长的特性 。subList
  嗯,不多讲,直接上代码         ArrayList arrayList = new ArrayList();         LinkedList linkedList = new LinkedList();         Vector vector = new Vector();         linkedList.subList(2,3);         arrayList.subList(2,3);         vector.subList(2,3);
  List 提供一个subList 方法,与String 的subString 有点类似,这里的List 通过subList 生成子list 方式也是通过内部类继承方式的多继承 实现的。
  当然这里,具体需要分析, ArrayList 和其他List 的实现的方式略有不同
  ArrayList 是自己定义的内部类SubList 继承AbstractList 实现的public class ArrayList extends AbstractList         implements List, RandomAccess, Cloneable, java.io.Serializable {   .......     public List subList(int fromIndex, int toIndex) {         subListRangeCheck(fromIndex, toIndex, size);         return new SubList(this, 0, fromIndex, toIndex);     } .....     private class SubList extends AbstractList implements RandomAccess {         private final AbstractList parent;         private final int parentOffset;         private final int offset;         int size;     .........
  LinkedList 的subList 方法是由AbstractList 实现的,它会根据是不是随机存储 提供不同的实现方法 ,subList 返回的类也是AbstractList的子类SubList 。public abstract class AbstractList extends AbstractCollection implements List {   ........    public List subList(int fromIndex, int toIndex) {         return (this instanceof RandomAccess ?                 new RandomAccessSubList<>(this, fromIndex, toIndex) :                 new SubList<>(this, fromIndex, toIndex));     }    class SubList extends AbstractList {      ...     }    class RandomAccessSubList extends SubList implements RandomAccess{     .......     }     ........  }
  这里需要注意的是,不管是ArrayList还是LinkedList等其他List,通过SubList内部类生成的List,其所有的方法(get,add,set,remove等)都是在 原始列表上操作 的,它自身并没有生成一个数组或是链表 ,也就是子列表只是原列表的一个视图(View) ,所有的修改都反映在原列表 上。

富爸爸穷爸爸作者买入比特币和白银,为大崩盘做准备知名畅销书富爸爸穷爸爸作者罗伯特清崎(RobertKiyosaki)在其社交媒体推特上发文称,随着美元贬值,比特币和白银是最好的投资。罗伯特清崎8月24日发文指出,目前比特币正从低学前班第22课外汇市场的层级结构首先,你需要知道的是,外汇市场一个去中心化的市场。它并不像股票市场那样集中交易,买方和卖方通过证券交易所专营经纪人进行交易。外汇市场不需要进入诸如纽约股票交易所等只有单一报价的集中非农交易做的烂?专业交易员提供4个技巧和2个事实今日(9月3日),金融市场将迎来全球瞩目的美国8月非农就业报告,这将可能成为市场的下一个推动风向标。那么,今天我们来详细聊聊全球外汇交易者非常关注的美国非农就业报告(NFP),它为中兴通讯董事长李自学推动数字经济协同发展,形成产业大格局当前,数字经济在我国的国民经济发展中占据重要地位,发挥着全新动能。因此有专家指出数字经济是新一轮科技革命和产业变革最强劲的力量和最核心的引擎,也是我国经济高质量发展的关键。据信通院学前班第21课一周中最佳外汇交易时间正如我们前面所说,在两个交易时段重叠期间,市场流动性非常充裕,各主要货币对或交易品种报价点差较低,这个时候比较适合投资者参与其中。东京伦敦交易时段重叠在夏季,从300400AMET都是十万级大空间SUV,对比北京x7和欧尚x7,差距明显,怎么选?预算在10万左右能够选择的自主品牌SUV中可以说有着非常多的选择,而如果要在这个价格区间里加上一个大字,那么你会想到哪几款车呢?而能够让我最先想到的有两款,其中是长安欧尚旗下的欧尚北京加强商品房预售资金监管预售资金重点监管额度提升43财联社(北京,记者李洁)讯,多家房企出现资金问题后,北京进一步加强了对商品房预售资金的监管力度。11月4日,北京市住建委人行营管部北京银保监局三部门联合印发北京市商品房预售资金管理监管银行不再零门槛新设资金封闭管理制北京进一步规范商品房预售资金的安全使用财联社(上海,实习记者徐川)讯,继成都发文进一步明确商品房预售款监管有关事项后,11月4日,北京市住建委人行营管部北京银保监局三部门联合印发北京市商品房预售资金管理办法(2021年三星主导OLED苹果力挺MiniLED?道不同,然而终将走向MicroLED科技的发展,显示技术也千变万化,一些术语不断产生。本文简要介绍OLEDMiniLED,QLED,以及最终的显示技术王者MicroLED。一OLEDOLED中文全称叫做有机发光二极管能源危机暂时缓解欧洲煤炭期货腰斩跌破100美元关键价位财联社(上海,编辑史正丞)讯,当地时间周一,在中国增产带来的持续利好作用下,明年到期的欧洲煤炭期货价格持续走弱,显著缓解当地能源价格飙升的困难局面。继中国国家发改委十月宣布煤炭日产COP26首日各国呈现显著诉求差异印度给出2070碳中和目标财联社(上海,编辑史正丞)讯,继周末G20峰会在气候问题上仅达成本世纪中叶实现碳中和的声明后,周一的格拉斯哥气候变化大会在更大范围内展现了全球各国在减排问题上的不同意见。东道主约翰
微信读书是否能颠覆kindle?作为一个目前有三台kindle和每天都在使用微信读书的用户,我的结论是微信读书必定会颠覆kindle!原因有以下几点第一,墨水屏并不是kindle的壁垒。微信读书如果愿意,也可以出数字化工厂总体设计与建设方案超详细剖析数字化工厂伴随数字仿真技术和虚拟现实技术发展而来,是智能制造发展的重要实践模式,它通过对真实工业生产的虚拟规划仿真优化,实现对工厂产品研发制造生产和销售服务的优化和提升,是现代工业工厂周边百名儿童鼻出血比亚迪陷污染指控后承诺彻底整改独家凤凰网新视界出品作者季倩编辑于浩5月7日,据中国慈善家杂志报道,长沙比亚迪雨花区工厂(下称长沙比亚迪)陷入环境污染漩涡。凤凰网新视界了解到,近两个月,比亚迪长沙工厂附近有浓烈的油漆CTFSSTI(服务器模板注入)绕过过滤绕过绕过姿势getitem绕过。class。mro。getitem(2)。subclasses()。getitem(40)(etcpasswd)。read()。class。mr小小SDK,如何玩转人脸识别2022年两会期间,有人大代表提出身联网,将人体与互联网相连的技术。2020年开始,历经几轮疫情之后,社区和企业厂区越来越关注无接触快速精准识别,AI人脸识别业务迎来短暂的黄金时代积极推动民用和军用的小型无人飞艇的尝试随着现在无人机在各行各业显示出来的优势使用,以及无人机在战场上的优异表现,未来在无人机领域竞争肯定会越来越激烈。因为各国都会投入更多去支持本国的无人机产业。我们中国除了应该继续积极组装机台式电脑组装机和原装机有什么区别?台式电脑组装机和原装机的区别有稳定性方面灵活性方面以及外观方面。一稳定性方面1原装机有自己独立的技术部门,会针对原装机的各部件进行严格的测试和检验,所以兼容性非常好,不容易出现故障你怎么看待去美国化的电脑文件根据网上泄露的某文件,说相关部门需要推进,替换掉美国产的电脑硬件。全部换成国产硬件,国产cpu,国产内存,国产磁盘。从爱国者的意义上来说我举双手双脚支持这种举措。但是我想了解的是这iPhone14全系惨遭曝光果粉看完沉默了中关村在线消息苹果将于6月召开WWDC开发者大会,iOS16手机操作系统将在本次发布会中登场,不出意外的话,iPhone14系列将会首发搭载。近日,大家关心的iPhone14配置被经典再升级,还能延续经典吗?兴戈洛神EM2R絮叨如果说青春有记忆的话,我能联想到的东西可太多了。但如果就听音乐这件事来说,除了一首首旋律烂熟于心的曲子以外,最能承载记忆的也就是各种设备了,这里头播放器和耳塞是必不可少。早在去iPhone14系列曝光,抢先看大家放心,还有4个多月的时间,我们才会和iPhone14系列见面。根据网上爆料的信息,外媒汇总了iPhone14系列的相关配置规格,并绘制了渲染图。如下图这次iPhone14系列取