Effective java -- 3 类和接口

时间:2022-05-06 07:57:42

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

一个设计良好的模块会将实现细节隐藏起来,只将暴露API。模块之间调用并不知道对象的细节。这个概念成为信息隐藏或封装。
要注意一点,设计的一个方法或者其他什么,只要不是私有的,外面能访问,那么以后在重构重写的过程中,这个方法就不能删掉,即使只是某个方法中的一个过程。
非零数组总是可变的,即使加了final,里面的内容也是可变的:

public static final Thirteenth[] values = {new Thirteenth(), new Thirteenth(), new Thirteenth()};

用这种方法想声明一个不可变的数组是错误的,这只能说明values改不了,但是里面的每个成员还是可变的。用以下方法:

方法一:
private static final Thirteenth[] values = {new Thirteenth(), new Thirteenth(), new Thirteenth()};
public static final List<Thirteenth> VALUES = Collections.unmodifiableList(Arrays.asList(values2));
方法二:  
private static final Thirteenth[] values = {new Thirteenth(), new Thirteenth(), new Thirteenth()};
public static final Thirteenth[] values(){
return values.clone();
}

四种访问权限,private(私有的),默认的(包级私有的),protected,public。要做到访问权限最小化,每个成员声明最开始应该都是私有地,同一包中其他类调用时将私有的换成包级私有的,如果程序很多地方都这么解决了问题,那么重新考虑一下设计的有没有问题。

第十四条:在共有类中使用访问方法而非共有域

就是提供set,get方法而不是将属性设成public的。在设计类的时候,考虑一下内部类。

第十五条:使可变性最小化

设计类的时候第一的想法就是将类设计成不可变的,属性私有、final,除非有明确的理由说服在将修饰符改掉。
如果明确的就是设计一个不可变类,如String、BigInteger。要遵循下面无条规则

  • 不要提供任何会修改对象状态的方法
  • 保证类不会被扩展。一种方法类加上final,另一种做法不提供共有的构造器。
  • 所有的域都是final的
  • 使所有的域都是私有的
  • 确保对于任何可变组件的互斥访问。如果类具有指向课表对象的域,则必须保证该类的客户端无法获取指向这些对象的引用。并且永远不要用客户端提供的对象引用来初始化这样的域。

不可变对象本质是线程安全的,他们不要求同步。
不可变对象的缺点是,对于每个不同的值都需要创建一个单独的对象。
类的构造器应该是完全初始化的对象。不要在构造器或静态工厂方法之外在提供额外的初始化方法,除非有令人信服的理由。

第十六条:组合由于集成

见过太多次的组合由于集成,看看是为什么。
集成打破了封装性,换句话说,子类依赖于其超类中特定贡呢给你的实现细节。如果超类发生了变化,子类可能会遭到破坏。

class InstruHashSet<E> extends HashSet<E> {
private int count = ; @Override
public boolean add(E e) {
count++;
return super.add(e);
} @Override
public boolean addAll(Collection<? extends E> c) {
count += c.size();
return super.addAll(c);
} public int getCount() {
return count;
} public static void main(String[] args) {
InstruHashSet<String> instruHashSet = new InstruHashSet<String>();
instruHashSet.addAll(Arrays.asList("f", "z", "k"));
System.out.println(instruHashSet.getCount());
}
}

最终的结果会是6。因为HashSet的addAll是循环调用add方法。
还有一个问题,有可能自定义的一个方法,在之后的版本中,自定义的方法名和超类的方法重名了,这时如果返回值不同,那么就尴尬了。
并不是说继承就应该不用,继承的正确用法应该是子类和父类就是一种层级的关系就像人-男人,这种情况下用继承是最好的。组合在这里用到了装饰者模式。

第十七条:要么就为继承而设计,并提供文档说明,要么就禁止继承

如果允许继承,构造器决不能调用可覆盖的方法。

class Seventeenth1{
public Seventeenth1(){
overrideMe();
} public void overrideMe(){}
} class Seventeenth2 extends Seventeenth1{
Date date;
public Seventeenth2(){
date = new Date();
} @Override
public void overrideMe() {
System.out.println(date);
} public static void main(String[] args) {
Seventeenth2 seventeenth2 = new Seventeenth2();
}
}

输出的结果是null。
对于实现了Cloneable或者Serializebale接口的类,也注意上面的问题。clone和readObject方法和构造器类似,因此都不可以调用可被覆盖的方法。

第十八条:接口优于抽象类

反正书上是这么说,但是用接口的利弊自己想吧,接口可以多实现,抽象类只能单继承,如果接口一开始设计有了问题,要修改接口是需要巨大代价的,但是抽象类单集成。

第十九条:接口只用于定义类型

在接口中定义各种常量,让实现类实现这个接口获取常量的做法不可取。可以定义常量类。如果是通过常量类的方式,导包的时候可以在包前加上static,这样就不用类名.常量名,直接常量名就可以了。

public class ConstantClass{
public static final String A = "a";
} import static ConstantClass.*;
class Test{
String getA(){
return A;
}
}

第二十条:类层次优于标签类

就是有层次结构的类就用集成的方式,别将一个类中定义各种乱七八糟的字段、方法让这个类既可以表示圆形又可以表示长方形。

第二十一条:用函数对象表示策略

第二十二条:优先考虑静态成员类

嵌套类是指被定义在类内部的类。分为四种,静态成员类,非静态成员类,匿名类,局部类。除了第一种,其他三种都是内部类。
静态成员类就是类内部的static生命的类,非静态成员类就是类内部非static生命的类,匿名类意会一下,局部类一般就是在方法中生命的类,出了方法就没有了。
静态成员类和静态变量方法什么的一样,可以脱离外部类而存在的。非静态成员类想创建出来必须先城建外部类的实例,在创建内部类。

Effective java -- 3 类和接口的更多相关文章

  1. Effective java笔记3--类和接口1

    一.使类和成员的可访问能力最小化 要想区别一个设计良好的模块与一个设计不好的模块,最重要的因素是,这个模块对于外部的其他模块而言,是否隐藏了内部的数据和其他的实现细节.一个设计良好的模块会隐藏所有的实 ...

  2. Java常用类、接口关系图谱

    呕心沥血画出此图,希望在使用Java类.接口时捋顺其关系,从而更好的组织程序逻辑---请看图 Object分出来的类都是其子类 Iterable接口分出的也是子接口 从继承关系分析,其父类实现的接口子 ...

  3. java 继承类与接口问题

    java 先extends 继承类,再implements 继承接口 public class DataBase extends ClassBase implements Ijiekou { }// ...

  4. Effective java笔记3--类和接口2

    三.接口优于抽象类 java提供两种机制,可以用来定义一个允许多个实现的类型:接口和抽象类.由于java只允许单继承,所以,抽象类作为类型定义受到了极大的限制. 已有的类可以很容易被更新,以实现新的接 ...

  5. Effective Java --使类和成员的可访问性最小化

    尽可能地降低可访问性 接口和成员变量访问级别四种访问级别: 私有的(private) --- 只有在生命该成员的顶层类内部才可以访问 包级私有的(package-private) --- 缺省的&qu ...

  6. 论java虚拟类和接口的区别

    如题:Abstract使数据成员虚拟化,而Interface则使方法成员虚拟化.

  7. Effective java笔记(三),类与接口

    类与接口是Java语言的核心,设计出更加有用.健壮和灵活的类与接口很重要. 13.使类和成员的可访问性最小化 设计良好的模块会隐藏起所有的实现细节,仅使用API与其他模块进行通信.这个概念称为信息隐藏 ...

  8. &lbrack;Effective Java&rsqb;第四章 类和接口

    声明:原创作品,转载时请注明文章来自SAP师太技术博客( 博/客/园www.cnblogs.com):www.cnblogs.com/jiangzhengjun,并以超链接形式标明文章原始出处,否则将 ...

  9. 《Effective Java 2nd》第4章 类和接口

    目录 第13条: 使类和成员的可访问性最小化 第14条:在公有类中使用访问方法而非公有域 第15条:使可变性最小化 第16条:复合优先于继承 第17条:要么为继承而设计,并提供文档说明,要么就禁止继承 ...

随机推荐

  1. Junit mockito 测试Controller层方法有Pageable异常

    1.问题 在使用MockMVC+Mockito模拟Service层返回的时候,当我们在Controller层中参数方法调用有Pageable对象的时候,我们会发现,我们没办法生成一个Pageable的 ...

  2. Android Studio插件之快速findViewById(butterknife和Android CodeGenerator的使用)

    首先在设置里面的Plugins里面下载安装插件: 安装之后会提示重启, 然后就是怎么使用了: butterknife的使用: 首先在build.gradle(app)里面添加这句话: compile ...

  3. android 史上最简单易懂的跨进程通讯&lpar;Messenger&rpar;&excl;

    不需要AIDL也不需要复杂的ContentProvider,也不需要SharedPreferences或者共享存储文件! 只需要简单易懂的Messenger,它也称为信使,通过它可以在不同进程中传递m ...

  4. &quot&semi;&lowbar;OBJC&lowbar;CLASS&lowbar;&dollar;&lowbar;AddFriendPageItem&quot&semi;&comma; referenced from&colon;

    该出错是指:有些头文件没有导入到  TARGETS  中的Build Phases - Compile Sources 中

  5. 灰度图像 Grayscale Binary&lowbar;image

    https://en.wikipedia.org/wiki/Grayscale https://zh.wikipedia.org/wiki/灰度图像 In photography and comput ...

  6. OPENVPN开启用户password认证

    一.服务端配置 1.改动openvpn的主配置文件,加入例如以下内容 [root@ttt openvpn]# cat /etc/openvpn/server.conf |more #########a ...

  7. 非常基本的SQL 内外连接

    有些问题一直很郁闷,例如:为什么会存在大约在同一时间连接这个东西.如果外键为空,创建问题的声明时,将有一个外键约束失败. 后来,在精心研究,恩.外部连接(左连接.正确的连接). 事实上都是非常基础的东 ...

  8. 微信小程序来了,小程序都能做些什么

    2017年的微信大动作就是微信小程序了,到底小程序都能做些什么?这是很多人关注的热点,小程序开发对企业又有什么帮助呢?下面让厦门微信小程序开发公司来为你就分析下.       微信小程序与APP的关系 ...

  9. Linux学习之CentOS&lpar;十四)----磁盘管理之 硬连接与软件连接&lpar;转&rpar;

    前言 在 Linux 底下的连结档有两种,一种是类似 Windows 的快捷方式功能的文件,可以让你快速的链接到目标文件(或目录),这种是软链接: 另一种则是透过文件系统的 inode 连结来产生新档 ...

  10. &period;NET Core实战项目之CMS 第四章 入门篇-Git的快速入门及实战演练

    写在前面 上篇文章我带着大家通过分析了一遍ASP.NET Core的源码了解了它的启动过程,然后又带着大家熟悉了一遍配置文件的加载方式,最后引出了依赖注入以及控制反转的概念!如果大家把前面几张都理解了 ...