Java中的继承实现的契约含义

并不是说给一个类取名为RECTANGLE就真能取代一个这个英文单词(矩形)能指代的概念的,一个英文单词有其默认的,隐含的契约,有可能与程序世界里想表达的概念不一致或有细微的差别。
当你写下
public class Rectangle{}
时,可能你脑子里想的是矩形的契约“一个封闭的图形,有四个角,每个角度都是90度”,然后你开始实现这个类
public class Rectangle{
   private int height;
   private int width;
  //setter
  //getter
}
你的实现却完全聚焦到了矩形的长和宽上,却完全忽视了它们的契约”改变长度或者宽度不会互相影响”,注意,此时你并没有实现一个几何意义上的“矩形”,你实现的类与下面的类无异,
public class A{
  private int i;
  private int j;
}
隐患开始埋下……
当你被问到”正方形是一个矩形吗”?你脑子里闪过初中数学(高中数学??)“当然是!!!”,于是你继承了矩形
 
public class Square extends Rectangle{
   //...
   public void setHeight(int height){
      height = height;
 }
   public void setWidth(int width){
       height = width; //!!! 父类的契约被违反了    
}
}
public class Test {
   test(){
      Rectangle rec = new Squre();
      rec.setHeight(4);
      rec.setWidth(5);
      assertEquals(20,rec.getHeigh()*rec.getWidth());// !!!fail, 结果为16!!!
}
}
 
     我们学到了什么?
一个类或接口是被其契约定义出来的,而不是被其“名字”定义出来的。在阅读代码时要意识到虽然代码”可读”但是其语义下的契约并未实现或还是模糊的。不要一开始就建立空中楼阁的架构,设计者对其中的契约并未有具体的认识,这样的设计往往有潜在的缺陷。
不要仅仅从一个名字判断出其能如何被子类继承,例如,“马”能被“斑马”继承吗?


“。。。当然可以”














那么这个“马”能被“海马”继承吗?!!!      (Gotcha!!!)




就继承实现来说,如果子类要invalid父类的行为,就有可能违反LSP。反之,如果子类要大量扩展或新增父类行为,这又说明子类特化的太厉害,已经失去了父类的意味,读这个类已经想象不出父类大概是个什么样子,对于理解设计并未有什么帮助。
不要为了重用行为而继承一个类,可采用聚合/组合来实现。
1,不要包外继承,因为设计者无法控制其契约的变化。
2,不要继承包内不是为继承设计的类
3,尽量不要继承非抽象类
4,尽量继承抽象类
5,继承抽象类时不要添加太多行为
6,对于抽象类的设计,非抽象方法做成FINAL
7,记住,真正可适用实现继承的SCENARIO是很少,很苛刻的。
 
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值