2.1 : 对象交互

体现面向对象设计理念制造一个时钟Clock,如何识别出Clock中需要的对象?

很明显,我们抽象出两个对象“显示器”,一个用来表达Hour,一个用来表达Minute,而这两个对象有一些共同点,也有一些数据上的不同点。例如:都有一个数值上限(Minute超过59后,重置为0,Hour超过23后,重置为0)等 .

所以我们可以设计一个Display类,用来构造这两个对象,再组合起来构成Clock

Clock类内部也需要有操作:当Minute到达上限后,需要通知Hour执行increase() 操作 我们希望类的设计:每一个类与对象都尽可能独立,所以两个对象的交互,我们应该交给Clock,而不是在Minute或者Hour中添加操作来执行,这样使得Display设计没有很好的适用性。

Display
数据:value(数值),limit(上限)
increase():用来增加数值value,并判断是否到达上限limit
getValue():用来获取当前数值
Clock
数据:Hour(Display对象),Minute(Display对象)
start():检测Minute是否重置为0,判断是否执行Hour.increase()

  1. public class Display {
  2. private int value = 0;
  3. private int limit = 0;
  4. public Display(int limit){
  5. this.limit = limit ;
  6. }
  7. public void increase(){
  8. value++ ;
  9. if (value == limit){
  10. value = 0;
  11. }
  12. }
  13. public int getValue(){
  14. return value;
  15. }
  16. public static void main(String args[]){
  17. //主函数测试
  18. }
  19. }
  1. public class Clock {
  2. private Display hour = new Display(24);
  3. private Display min = new Display(60);
  4. public void start(){
  5. while (true) {
  6. min.increase();
  7. if (min.getValue() == 0) {
  8. hour.increase();
  9. }
  10. System.out.printf("%02d : %02d\n", hour.getValue(), min.getValue());
  11. }
  12. }
  13. public static void main(String args[]){
  14. Clock clock = new Clock();
  15. clock.start();
  16. }
  17. }

两个思考:

  1. 如果Display的increase函数在发现翻转后,返回boolean值表示翻转了,是不是一个好的设计?
  2. 如何让Hour与Minute做直接交互?让表示Minute对象翻转时,直接调用Hou的increase函数,代码如何修改?

2.2 : 访问属性

封装 = 数据+ 操作

  • 就是把数据和对这些数据的操作放在一起,并且用这些操作把数据掩盖起来。
  • 封装是面向对象的基本概念之一,也是最核心的概念。

    Private只能当前类的内部访问与使用,其他类不能访问,其所针对的范围是类而不是对象
    Public任何类的定义与函数初始化都可以调用,访问,定义变量

我们有一个非常直截了当的手段来保证在类的设计的时候做到封装:

  1. 所有的成员变量必须是**private**,这样就避免别人任意使用你的内部数据;
  2. 所有public的函数,只是用来实现这个类的对象或类自己要提供的服务,而不是用来直接访问数据的。除非对数据的访问就是这个类及对象的服务。简单地说,给每个成员变量提供一对用于读写的get/set函数也是不合适的设计。

编译单元:一个Java文件的编译范围,一个编译单元仅允许由一个public关键字函数
无关键字类:当一个类没有Public或者private关键字时,默认friendly类型,适用范围为当前包(package)


2.3 :包(package)

:Java的类库管理机制,它借助文件系统的目录来管理类库,一个包就是一个目录
包的作用:为了更好地组织类,Java 提供了包机制,用于区别类名的命名空间。

  1. package 包名;
  2. //例 :一个Something.java 文件它的内容
  3. import 包名.类名;
  4. // 引入其他包的类,建议精确引入
  5. import 包名.*;
  6. // 使用通配符*,引入这个包的所有类
  7. package net.java.util;
  8. // 一个点代表一个文件层级
  9. // 它的路径应该是 net/java/util/Something.java 这样保存的
  10. public class Something{
  11. ...
  12. }

2.4 :Static

类是描述,对象是实体。在类里所描述的成员变量,是位于这个类的每一个对象中的。 而如果某个成员有static关键字做修饰,它就不再属于每一个对象,而是属于整个类的了。

通过每个对象都可以访问到这些类变量和类函数,但是也可以通过类的名字来访问它们。 类函数由于不属于任何对象,因此也没有办法建立与调用它们的对象的关系,就不能访问任何非static的成员变量和成员函数了。

Static类变量

  • 非成员变量,不属于任何一个对象,而是属于类的变量
  • 仅初始化一次,初始化为类装载对象的时候

Static类函数

  • 仅能直接访问同为Static的函数
  • 访问成员函数需要通过对象名调用d1.add