Java核心技术学习笔记_1(对象与类)

Create by westfallon on 8/9

前言

作为一名本科生,在自己学习了一些框架的使用,同时做了几个小型项目之后,感觉到自己在最基础的 java 语言部分还掌握的不够深入,于是打算将java语言重新复习一遍,并将重点记录下来。

参考书籍: 机械工业出版社《java核心技术》

对象与类

面向对象程序设计(Object Oriented Programming,简称OOP)是当今主流的程序设计范型。Java是完全面向对象的,必须熟悉OOP才能编写Java程序。

  • 类(class)是构造对象的模版或蓝图。由类构造(construct)对象的过程称为创建类的实例(instance)
  • 封装(encapsulation,有时称为 数据隐藏)在形式上看是指将数据和行为组合在一个包中,并对对象的使用者隐藏了数据的实现方式。
  • 实现封装的关键在于绝对不能让类中的方法直接访问其他类的实例域,程序仅通过对象的方法于对象数据进行交互,这是提高重用性和可靠性的关键。
  • Java中,所有类都源自于Object类
  • 通过扩展一个类来建议另外一个类的过程叫做继承

对象

  • 对象的三个主要特征
    • 对象的行为(behavior): 可以对对象施加哪些操作,或可以对对象施加哪些方法
    • 对象的状态(state): 当施加那些方法时,对象如何响应
    • 对象标识(identity): 如何辨别具有相同行为与状态的不同对象

类之间的关系

  • 在类之间,最常见的关系有
    • 依赖("uses-a"),如果一个类的方法操纵另一个类的对象,我们说一个类依赖于另一个类
    • 聚合("has-a"),聚合意味着类A的对象包含类B的对象
    • 继承("is-a"),类A扩展类B,A不仅包含B的方法,还可以有一些额外的功能,叫做A继承B
  • 我们应该尽可能将相互依赖的类减至最少,即让类之间的耦合度最小

对象与对象变量

  • 对象变量并没有实际包含一个对象,而仅仅引用一个对象
  • 在Java中,任何对象变量的值都是对储存在另外一个地方的一个对象的引用。new操作符返回的也是一个引用。可以讲Java中的对象变量看作C++的对象指针。
  • 所有的Java对象都储存在堆中。当一个对象包含另一个对象时,这个变量依然包含着指向另一个堆对象的指针。

封装

  • 如何封装
    • 私有的数据域
    • 公有的域访问器方法
    • 公有的域更改器方法
  • 好处
    • 可以改变内部实现,除了该类的方法之外,不影响其他代码
    • 更改器方法可以执行错误检查
  • 注意:不要编写返回引用可变对象的访问器方法,如果需要返回一个可变对象的饮用,应该先对它进行克隆

静态域与静态方法

  • 如果将域定义为static,每个类中只有一个这样的域。而每个对象对于所有的实例域都有一份自己的拷贝
  • 静态方法是一种不能向对象实施操作的方法,所以不能在静态方法中访问实例域。但是静态方法可以访问自身类中的静态域
  • 在以下两种情况下使用静态方法
    • 一个方法不需要访问对象状态,其所需的参数都是通过显式参数提供(例如Math.pow)
    • 一个方法只需要访问类的静态域

static的历史

  • 最初 C引进关键字 static 是为了表示推出一个块后依然存在的局部变量。在这种情况下,术语 "static" 是有意义的:变量一直存在,当再次进入该块时依然存在。
  • 随后,static 在 C 中有了第二层含义,表示不能被其他文件访问的全局变量和函数。
  • 最后,C++ 第三次重用了这个关键字,与前面的含义完全不一样,这里表示:属于类且不属于类对象的变量和函数,与 Java 相同

方法参数

  • 按值调用(call by value)表示方法接收的是调用者提供的值。按引用调用(call by reference)表示方法接收的是调用者提供的变量地址
  • Java中总是按值调用,也就是说,方法得到的是所有参数值的一个拷贝

初始化块(initialization block)

  • 在一个类的声明中,可以包含多个代码块。只要构造类的对象,这些块就会被执行
  • 如果对类的静态域进行初始化的代码比较复杂,可以使用静态的初始化块。在类第一次加载的时候,将会对静态域进行初始化

对象析构与finalize方法

  • C++中有显式的析构器方法,放置一些当对象不再使用时需要执行的清理代码,常见是回收分配给对象的储存空间
  • Java有自动的垃圾回收器,不需要人工回收内存,所以Java不支持析构器
  • finalize方法在垃圾回收器清除对象之前调用,在实际应用中不要依赖于使用finalize回收任何短缺的资源,因为很难知道这个方法什么时候才能调用

  • 使用包的主要原因是确保类名的唯一性
  • C++中必须使用#include将外部特征的声明加载进来,因为C++编译器无法查看任何文件的内部,除了正在编译的文件以及在头文件中明确包含的文件
  • Java编译器可以查看任何文件的内部,只要告诉它去哪里查看就好了
  • 在Java中,通过显式地给出包名,如java.util.Data,就可以不使用import;而在C++中,无法避免使用#include

类设计技巧

  • 一定要保证数据私有
  • 一定要对数据初始化
  • 不要在类中使用过多的基本类型
  • 不是所有的域都需要独立的域访问器和域更改器
  • 将职责过多的类进行分解
  • 类名和方法名要能够体现它们的职责
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。