第四章 类和接口

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

  • 封装:降低耦合,提高重用性
  • 实例域决不能是公有的
  • 公有类不应该包含公有域(除非公有静态final域),要确保公有静态final域所引用的对象都是不可变的

14. 在公有类中使用访问方法而非公有域

15. 使可变性最小化

使类成为不可变,需要遵循下面五条规则:

  1. 不要提供任何会修改对象状态的方法
  2. 保证类不会被扩展,一般让类成为final
  3. 所有的域都是final的
  4. 所有的域都是私有的
  5. 确保对任何组件的互斥访问

16. 组合优于继承

  • 继承违背了封装的原则
  • 使用继承要考虑子类是否和超类存在子类型的关系

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

18.接口由于抽象类

区别

  • 抽象类允许包含某些方法的实现,在java8之后接口也允许了默认方法和静态方法
  • 抽象类是单继承,接口是多实现
  • 现有的类可以很容易被更新,以实现新的接口
  • 接口是定义混合类型的理想选择
  • 接口允许我们构造非层次结构的类型框架

19. 接口只用于定义类型,最好不要用来定义常量

20.

缺点

  • 充斥着样板代码,破坏了可读性
  • 标签类过于冗长、容易出错、效率低下

    改进

  • 子类型化能更好的表示多种风格对象的单个数据类型

    1. 子类型化能更好的表示多种风格对象的单个数据类型
    2. 在子类中定义属于该类的数据域
  • 类层次还有一个好处,增强灵活性,方便编译时类型检查。类层次能够很好的反映类型之间本质上的层次关系

21. 用函数对象表示策略

  1. 函数指针的主要用途就是实现策略(Strategy)模式。

  2. 为了在Java中实现这种模式,要声明一个接口来表示该策略,并且为每个具体策略声明一个实现了该接口的类。

  3. 当一个具体策略只被使用一次时,通常使用匿名类来声明和实例化这个具体策略类。

  4. 当一个具体策略是设计用来重复使用的时候,它的类通常就要被实现为私有的静态成员类,并通过公有的静态final域被导出,其类型为该策略接口

  5. java8的lambda表达式,函数式编程也是属于这个范畴

22. 优先考虑静态成员类

嵌套类

指被定义在另一个类的内部的类。嵌套类存在的目的应该只是为他的外围类(enclosing class)提供服务。如果嵌套类将来可以回用于其他的某个环境中,他就应该是顶层类(top-level class)

分类

嵌套类分为四种:静态成员类(static member class)、非静态成员类(nonstatic member class)、匿名类(anonymous class)和局部类(local class)。
内部类:非静态成员类(nonstatic member class)、匿名类(anonymous class)和局部类(local class)

静态成员类

静态成员类是最简单的一种嵌套类。
最好把他看做是普通的类,只是碰巧被声明在另一个类的内部而已,他可以访问外围类的所有成员,包括声明为私有的成员。
静态内部类是外围类的一个静态成员,与其他的静态成员一样,也最受同样的可访问性规则。如果他被声明为私有的,他就只能在外围类的内部才可以被访问,等等。

  • 注意:如果一个类要被声明为static的,只有一种情况,就是静态内部类。如果在外部类声明为static,程序会编译都不会过。

非静态成员类

从语法上讲,静态成员类和非静态成员类之间唯一的区别是:静态成员类的声明中包含修饰符static。尽管他们语法非常相似,但是这两种嵌套类有很大的不同。
非静态成员类的每个实例都隐含着与外围类的一个外围实例(enclosing instance)想关联。在非静态成员类的实例方法内部,可以调用外围实例上的方法,或者利用修饰过的this构造获得外围实例的引用。如果嵌套类的实例可以在他外围实例的情况下,要想创建非静态成原来的实例是不可能的

匿名类

  1. 第一种常见用法就是动态的创建函数对象(function object)
  2. 第二种常见的用法是创建过程对象(process object),比如Runnable、Thread或者TimerTask实例。
  3. 第三种常见的用法是在静态工厂内部

局部类

局部类是四种嵌套类中用的最少的类。在任何“可以声明局部变量”的地方,都可以声明局部类,并且局部类也遵守同样的作用域规则。局部类与其他三种嵌套类中的每一种都有一些共同的属性。与成员类一样,局部类有名字,可以被重复使用。与匿名类一样,只有当局部类实在非静态环境中定义的时候,才有外围实例,它们也不能包含静态成员。与匿名类一样,它们必须简短以便不会影响到可读性

使用总结

  1. 如果一个嵌套类需要在单个方法之外仍然可见的,或者它太长了,不适合于放在方法内部,就应该使用成员类。
  2. 如果成员类的每个示例都需要一个指向外围实例的引用,就要把成员类做成非静态的;否则,就做成静态的。
  3. 假设这个嵌套类属于一个方法的内部,如果你只需要在一个地方创建实例,并且已经有了一个预置的类型可以说明这个类的特征,就要把它做成匿名类;否则,就做成局部类

猜你喜欢

转载自blog.csdn.net/u010634897/article/details/81463387