第四章 类和接口

类和接口是java程序设计的核心,java也为其提供了很多的元素。这章提供了一些准则,来实现更加有用,灵活,健壮的类和接口。

第十三节:使类成员的可访问性最小化

在类的模块设计中,将和其他类通信的API设置为public的其他设为private,protect或者package-private。信息隐藏或封装能够解除各个模块之间的耦合,使各个模块之间能够独立的开发,测试优化,同时也能非常方便对类进行维护和理解。

java中的一些机制来帮助实现信息隐藏。访问控制机制决定了类,接口,成员的可访问性。一个实体的可访问性由该实体所在的包的位置(package-private),以及声明该实体所用的访问修饰符(private,protect,public)共同决定。正确的使用这些修饰符来实现信息隐藏非常的关键。

对于顶级的类和接口,只有两种可能的访问级别,package-private和公有的。

第一规则:尽可能的使每个类或者成员不被外界访问。

第二:如果方法覆盖了超类的某个方法,则子类的访问级别高于基类的访问级别。可以使得基类的引用可以调用子类的方法。

第三规则:实例的域决不能是公有的。其中final除外。如果域是公有的则放弃了对该域的控制。同时公有的域也不是线程安全的。

如果一个域是不可变的同时是静态的static final 。如果是引用的不可变对象,如果引用所指向的对象可变则会导致灾难性的后果。

注意:长度非零的数组域总是可变的。所以,类具有公有的静态的final数组域,或者返回这种域的访问方法,几乎就是错误的。因为这种域的访问方法,客户端将能够修改数组中的内容。这是安全漏洞中常见的一个隐患。

有两种方法来修正:一是将公有数组变成私有的,并添加一个公有的不可变列表。

二是,可以将数组变成私有的,并添加一个公有的方法,该方法返回一个该数组的克隆。

在java中Collections中有一个返回不可变的序列的方法。

 

综上所述:尽可能的降低可访问性。在设计一个最小的公有api时,应该防止把任何散乱的类,接口和成员变成API的一部分。除了公有静态final域的特殊情形之外,公有类都不应该包含公有域。并且保证公有静态final域所引用的对象都是不可变的。

 

第十五节 使类的可变性最小化(待消化)

使类的实例不可变。遵守如下五条规则:

一、不要提供任何会修改类的状态的方法。

二、保证类不会被扩展

三、使所有的域都是final的

四、使所有的域都是private的

五、确保对于任何可变组件的互斥访问。

 

 

第十六条 复合优于继承

继承是实现代码重用的重要手段,但并非最佳的手段,继承会使得软件变得非常的脆落。包内部使用继承是比较的安全,因为这些类都是在同一个程序员的控制下。对于专门为了继承而设计,并且具有很好的文档说明的类来说,使用继承也是很安全的。而对于普通的具体的类进行挎包继承则是非常危险的行为。会将类变的脆弱。

与方法的调用不同的是,继承打破了类的封装性。子类依赖于父类的特定的实现细节。如果父类发生了变化,子类则会遭到破坏。

 

导致子类变得脆弱的原因是,当后序的版本中父类的方法做修改时,子类将要跟着修改,否则出错。也有可能是当子类中的方法在以后的版本中父类中添加了相同名字和参数但返回类型不同的方法将导致子类编译通不过。

改进以上情况的方法是:不用扩展现有的类,而是在新的类中添加一个私有的域,它引用现有类的一个实例。这种方法叫做组合(composition),因为现有的类是新的类的一个组件。新类中的每个实例方法都可以调用被包含的现有类的实例方法,并返回结果。这被称为转发(forwarding),新类中的方法称为转发方法。这样方法将会非常稳固,不依赖于现有类的实现细节。即使现有类添加新的方法,也不会影响到新的类。

 

只有在子类是父类的真正的子类型时,才适合使用继承,换而言之,对于两个类A和B,只有存在‘is-a’关系时,才适合使用继承。否则将使用组合,将a变为b的一个实例,啊是b的实现细节的一部分。

 

java平台的类中有一些违反 了这条原则的地方Properties不应该扩展HashTable。

 

同时如果在适合使用符合的地方使用了继承,则会不必要的暴露细节,这样的到的API会将你限制在原始的实现上,永远限定了类的性能。更为严重的是,客户端就会直接的去访问这些细节(父类的方法)。也可能会导致予以语义上的混淆。

 

同时,组合会隐藏父类中的一些不好的地方,而继承会将这些确定传给子类,并一直传下去。

 

简而言之:继承的功能强大,但也只适用于在同一个包中,或者是在不同的包中专门为继承为设计的同时拥有很好的文档的类中。否则应当避免使用。组合的功能更加的强大,同时代码会更加健壮。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值