1.使类和成员的可访问性最小化

  • 封装(数据私有化,方法公开化)/对外提供可调用的,稳定的功能
  • 可访问性应该明确
修饰符 本类 同包类 子类 其他类
public
protected
默认
private
  • 实例域绝不能是公有的
  • 包级私有的顶级类只在某一个类内部被用到,就可以使用成为它的嵌套类

2.使可变性最小化(不可变对象)

  • 遵循规则

      1. 不要提供任何会修改对象状态的方法2. 保证类不会被扩展3. 所有域都要是final,且为私有4. 确保对于任何可变组件的互斥访问。
    复制代码
  • 优点

      1. 线程安全不可变对象是线程安全的,在线程之间可以相互共享,不需要利用特殊机制来保证同步问题,因为对象的值无法改变。2. 易于构造、使用和测试不可变对象为其他对象提供了大量的构件
    复制代码
  • 缺点

      1. 需要为每一个不同的值提供不同的对象。如果创建的对象比较大,那么所产生的代价就有点高了2. String -> StringBuilder(可变配套类)
    复制代码
  • 总结

      1. 坚决不要为每个get方法编写一个相应的set方法
    复制代码

3.复合优先于继承

  • 原因

      1. 继承打破了封装性。子类信赖于其超类中特定功能的实现细节。超类的实现有可能会随着发行版本的不同而有变化,子类有可能会被破坏2. 复合优点a.不破坏封装,整体类与局部类之间松耦合,彼此相对独立b.具有较好的可扩展性c.支持动态组合。在运行时,整体对象可以选择不同类型的局部对象d.整体类可以对局部类进行包装,封装局部类的接口,提供新的接口3. 复合缺点a.整体类不能自动获得和局部类同样的接口b.创建整体类的对象时,需要创建所有局部类的对象
    复制代码
  • 总结

      1. 只有当子类和父类确实存在子类型关系时,使用继承才是恰当的2. 继承会把父类所有的缺陷继承过来3. 复合是has a, 继承是is a。
    复制代码

4.要么为继承而设计,提供文档说明,要么禁止继承

  • 注意父类中各方法之间的相互调用,特别是可被覆盖的方法。一定要在文档中说明其自用性。(Interator的remove方法)
  • 类必须提供适当的钩子,以便能进入到它的内部工作流程中。可以是受保护的方法,也可以是受保护的域。(AbstractList的removeRange)
  • 对于为了继承而设计的类,唯一的测试方法就是编写子类。经验表明,三个子类通常可以测试一个可扩展的类。
  • 构造器、静态工厂方法和其他具有构造对象功能的方法决不能调用可被覆盖的方法(例子:)
  • 为了继承而设计类的时候,Cloneable和Serializable接口出现了特殊的困难。(readResolve应是受保护的方法)
  • 通过完全消除类中的可覆盖方法的自用特性,也可以创建”能够安全地进行子类化“的类。(文档说明/不会调用可覆盖的方法)

5.接口优先于抽象类

  • 优点

      1.现有类可以很容易的实现更新,通过实现新的接口2.接口是定义混合类型的理想选择3.接口允许我们构造非层次结构的类型框架
    复制代码
    public interface Songer{void song();}public interface SongWriter{Song writeSong();}pulbic interface SongerWriter extends Songer,SongWrite{void act();}
    复制代码
  • 缺点

      在版本演变中很难通过新添加接口方法进行功能添加,但是抽象类可以很轻松搞定这种事
    复制代码
  1. 总结

     当演变的容易性比比灵活性和功能性更为重要时,应该用抽象类定义类型
    复制代码

6.接口只用于定义类型

  • 常量接口模式是对接口的不良使用。
  • 会导致使用者对接口含义的模糊,而且使用选择了实现该接口,那么后续不在需要这些常量的时候,我们不能删除该接口。(二进制兼容性)
public interface EarthConstants{double EARTH_RADIUS = XXXXX.XXXXX;}public final class EarthConstants{private EarthConstants(){}public static final double EARTH_RADIUS = XXXXX.XXXXX;}
复制代码

7.类层次优先于标签类

  • 标签类过于冗长、容易出错,并且效率低下。
  • 类层次逻辑清晰,便于维护

8.用函数对象表示策略

  • 利用对象引用实现函数指针的功能,可以实现策略模式。

9.优先考虑静态成员类

  • 原因

      1. 非静态成员类的每个实例都隐含着与外围类的一个外围实例想关联。在其被创建时,关联关系也建立了,这个关系不能被修改了。
    复制代码
  • 优点

      1.内部类包括:成员类、局部类、匿名类。2.静态类不能访问外部类的非静态成员和非静态方法(不管是public还是private的);3.静态类的实例不需要先实例化外部类成员,可直接实例化。
    复制代码
  • 成员类、局部类、匿名类

      1. 成员类a.从技术上来说,可以分为两种:成员内部类和成员嵌套类。b.成员内部类即这里说的成员类,全称是非静态成员内部类c.成员嵌套类即上面的静态嵌套类d.可以直接调用外部类的方法e.定义一个Adapter,他允许外部类的实例被看作是另一个不相关的类的实例(Map中的KeySet、entrySet)
    复制代码
    public class Main{public class MemberClass{}//成员内部类,常简称为成员类
    }
    复制代码
      2. 局部类a.任何可以声明局部变量的地方都可声明局部类b.只有在非静态环境中使用才会与外部类实例关联c.注意到了吧,可以同名,编译后,形成诸如:外部类名称+$+同名顺序+局部类名称(Test$1AA.class/Test$2AA.class/Test$3AA.class)
    复制代码
    public class Test {{class AA{    // 块内局部类}
    }
    public Test(){class AA{    // 构造器内局部类}
    }
    public static void main(String[] args){}
    public void test(){class AA{    // 方法内局部类}
    }
    }
    复制代码
      c.匿名类(成员匿名类/局部匿名类)没有类名,不能使用继承,实现接口等特性只有在使用的时候才会初始化,并与外部类实例建立联系可以出现在代码中的任何允许表达式出现地方必须保持简短才能保证程序良好的阅读性常见使用:创建对象过程:Thead、Runnable,静态工厂方法内部
    复制代码
    public class Test {InterfaceA a = new InterfaceA() {    //成员匿名类
    };
    public static void main(String[] args){InterfaceA a = new InterfaceA() {    //局部匿名类
    };
    // 以上两种是通过实现接口实现匿名类,称为接口式匿名类,也可以通过继承类
    Test test = new Test(){};    //继承式匿名类
    // 还可以是位于参数上
    new Thread(new Runnable() {@Overridepublic void run() {}
    }).start();// 属于局部匿名类一种
    }
    private interface InterfaceA{}
    }
    复制代码
  • 总结

      1. 成员类:位于类内部但不包括位于块、构造器、方法内,且有名称的类。2. 局部类:位于块、构造器、方法内的有名称类。 3. 匿名类:类内无名称类,又可细分为:成员匿名类和局部匿名类。
    复制代码

转载于:https://juejin.im/post/5bb2eed06fb9a05d0530b5fe

《effective java》类和对象相关推荐

  1. java类与对象实验_JAVA类与对象实验报告

    <JAVA类与对象实验报告>由会员分享,可在线阅读,更多相关<JAVA类与对象实验报告(6页珍藏版)>请在人人文库网上搜索. 1.面向对象程序设计实验报告实验三.类与对象(1) ...

  2. 杨校老师课堂之Java类与对象、封装、构造方法

    杨校老师课堂之Java类与对象.封装.构造方法 本篇文章内容如下: 面向对象 类与对象 三大特征--封装 构造方法 教学目标 能够理解面向对象的思想 能够明确类与对象关系 能够掌握类的定义格式 能够掌 ...

  3. 从Java类到对象的创建过程都做了些啥?内存中的对象是啥样的?

    转载自   从Java类到对象的创建过程都做了些啥?内存中的对象是啥样的? 先回顾一下Java程序执行的过程: Java程序执行时,第一步系统创建虚拟机进程,然后虚拟器用类加载器Class Loade ...

  4. java类和对象程序_Java类与对象程序设计基础

    Java类与对象程序设计基础 一.实验目的: 通过编制一个独立应用程序,使得学生掌握Java的系统所提供类的引用方法:通过编制一个完整的应用程序,使得学生对Java的应用程序的基本构成和基本算法熟练掌 ...

  5. java类与对象 演练 查找并修改姓名

    java类与对象 演练 查找并修改姓名 视频 https://www.ixigua.com/i6870489659168784903/ 思路 先定义一个类 类中有一个名字数组 提前给这个数组一些默认值 ...

  6. java类与对象 演练 客户姓名添加与查看

    java类与对象 演练 客户姓名添加与查看 视频 https://www.ixigua.com/6870483106223096327?logTag=_YUmIb2rn9-6JpoNipj9r 类的定 ...

  7. 最大公约数与最小公倍数( 初学Java 类与对象 )

    最大公约数与最小公倍数( java 类与对象的运用 ) Problem Description 输入两个正整数,求它们的最大公约数与最小公倍数. Input 输入两个正整数,两个整数之间用空格分开. ...

  8. Java类和对象(如何理解类和对象)

    Java类和对象 一.什么是对象? 1.什么是对象的属性? 2.什么是对象的行为 二.什么是类? 三. 类和对象的关系 四.类的定义 1.类的定义格式 2.类的定义示例 五.对象的使用 1.对象的创建 ...

  9. 【Java类和对象】

    Java类和对象 在Java简介中就有介绍到,Java是一门面向对象的编程语言,在面向对象的编程语言中,肯定离不开对象这个概念,而对象则是类的实例,所以也肯定离不开类这个概念.简单的来说就是,在Jav ...

  10. java类和对象在内存的表现形式

    Java内存分配与管理是Java的核心技术之一,不管学习任何一门语言,我们要知其然,知其所以然,本文主要分析下Java中类和对象在内存中的表现形式,方便我们对其有更深了解.一般Java在内存分配时会涉 ...

最新文章

  1. SparkStreaming靠什么征服了字节跳动?
  2. java学习笔记16--I/O流和文件
  3. CG CTF CRYPTO Keyboard
  4. stm32 复位到内部bootloader
  5. javascript --- [FormData的使用] 文件上传进度条展示 文件上传图片即使预览
  6. 二、操作系统——用信号量机制实现进程互斥、同步、前驱关系(详解)
  7. apache日志导入mysql,将Apache访问日志记录到Mysql数据库中
  8. python类的定义和创建_Python类对象的创建和使用
  9. 什么是MARC数据?
  10. 0024-CENTOS6.5安装CDH5.12.1(一)
  11. SQL:MySQL中建立一个新的数据表
  12. 软件测试(测试用例)—写用例无压力
  13. 韦东山freeRTOS系列教程之【第八章】事件组(event group)
  14. 嵌入式研发人员的核心竞争力浅谈
  15. Chrome 各版本下载地址大全
  16. cdn加速的原理及步骤
  17. mac之间快速传递文件-from-jianshu-狂奔的胖蜗牛
  18. 我的世界服务器修改npc指令,我的世界自定义npc指令 | 手游网游页游攻略大全
  19. 新年寄语 —— 奋斗2020
  20. 关于腾讯云服务器使用FTP详细配置教程

热门文章

  1. zendopcache代替APC效果不错
  2. SecureCRT自动登录
  3. 一个电脑白痴和***的对话!
  4. Wsus存储更新文件的磁盘已满
  5. Unity Dotween官方案例学习
  6. 【kafka】confluent_kafka重置offset
  7. 破解石碑(区间动规)
  8. ios学习笔记——Block块小结
  9. response.getWriter().write 传递中文乱码
  10. SQL设置语言,返回中文”星期几”格式