继承使实现代码重用的有力手段,但这并非总是完成这项工作的最佳工具,使用不当会导致软件变得很脆弱 。与方法调用不同的是,继承打破了封装性 。子类依赖于其父类中特定功能的实现细节,如果父类的实现随着发行版本的不同而变化,子类可能会遭到破坏,即使他的代码完全没有改变 。
举例说明 , 假设有一个程序使用HashSet,为了调优该程序的性能,需要统计HashSet自从它创建以来添加了多少个元素 。为了提供该功能 , 我们编写一个HashSet的变体 。
【java带走怪味道的代码 java一些有趣的代码】通过在新的类中增加一个私有域 , 它引用现有类的一个实例,这种设计被称为组合,因为现有的类变成了新类的一个组件 。这样得到的类将会非常稳固,它不依赖现有类的实现细节 。即使现有的类添加了新的方法,也不会影响新的类 。许多设计模式使用就是这种套路,比如代理模式、装饰者模式
继承与组合如何取舍
Java提供了两种机制,可以用来定义允许多个实现的类型:接口和抽象类 。自从Java8为接口增加缺省方法(default method),这两种机制都允许为实例方法提供实现 。主要区别在于,为了实现由抽象类定义的类型 , 类必须称为抽象类的一个子类 。因为Java只允许单继承 , 所以用抽象类作为类型定义受到了限制 。
接口相比于抽象类的优势:
接口虽然提供了缺省方法,但接口仍有有以下局限性:
接口缺省方法的设计目的和优势在于:
为了接口的演化
可以减少第三方工具类的创建
可以避免创建基类
由于接口的局限性和设计目的的不同,接口并不能完全替换抽象类 。但是通过对接口提供一个抽象的骨架实现类,可以把接口和抽象类的优点结合起来 。接口负责定义类型 , 或许还提供一些缺省方法,而骨架实现类则负责实现除基本类型接口方法之外,剩下的非基本类型接口方法 。扩展骨架实现占了实现接口之外的大部分工作 。这就是模板方法(Template Method)设计模式 。
Image [5].png
接口Protocol:定义了RPC协议层两个主要的方法,export暴露服务和refer引用服务
抽象类AbstractProtocol:封装了暴露服务之后的Exporter和引用服务之后的Invoker实例,并实现了服务销毁的逻辑
具体实现类XxxProtocol:实现export暴露服务和refer引用服务具体逻辑
由于为了保持Java代码的兼容性,支持和原生态类型转换,并使用擦除机制实现的泛型 。但是使用原生态类型就会失去泛型的优势,会受到编译器警告 。
每一条警告都表示可能在运行时抛出ClassCastException异常 。要尽最大的努力去消除这些警告 。如果无法消除但是可以证明引起警告的代码是安全的,就可以在尽可能小的范围中,使用@SuppressWarnings("unchecked")注解来禁止警告,但是要把禁止的原因记录下来 。
参数化类型不支持协变的,即对于任何两个不同的类型Type1和Type2而言,List既不是List的子类型,也不是它的超类 。为了解决这个问题,提高灵活性 , Java提供了一种特殊的参数化类型,称作有限制的通配符类型,即List? extends E和List? super E 。使用原则是producer-extends,consumer-super(PECS) 。如果即是生产者,又是消费者,就没有必要使用通配符了 。
还有一种特殊的无限制通配符List?,表示某种类型但不确定 。常用作泛型的引用,不可向其添加除Null以外的任何对象 。
嵌套类(nested class)是指定义在另一个类的内部的类 。嵌套类存在的目的只是为了它的外部类提供服务 , 如果其他的环境也会用到的话,应该成为一个顶层类(top-level class) 。嵌套类有四种:静态成员类(static member class)、非静态成员类(nonstatic member class)、匿名类(anonymous class)和 局部类(local class) 。除了第一种之外,其他三种都称为内部类(inner class) 。
推荐阅读
- 视频号怎么扣点,视频号怎么收入
- 视频上下集符号是什么,上下的视频
- 包含postgre无主键同步的词条
- go语言切片需要释放么 go语言切片扩容
- python中sin什么意思,python画sin函数
- 冒险岛DS下载游戏,冒险岛1下载
- c语言数组函数回调 c语言中调用函数,怎么返回数组的值
- oracle中删除表格数据恢复,oracle 恢复删除表
- 关于postgresql9.3性能的信息