Java核心技术I——基础点拾掇(第四章)

来源:互联网 发布:大数据相关职位 编辑:程序博客网 时间:2024/04/29 03:22

第四章:对象与类

在类之间,最常见的关系有:

(1)依赖(“users-a”)

(2)聚合(“has-a”)

(3)继承(“is-a”)

依赖(dependence):如果一个类的方法操作另一个类的对象,我们就说一个类依赖于另一个类。应该尽可能地将相互依赖减至最少。如果A类不知道B的存在,它就不会关心B的任何改变(这意味着B的改变不会导致A产生任何Bug)。用软件工程的术语来说,就是让类之间的耦合度最小。

聚合(aggregation):意味着类A的对象包含类B的对象。(也可以叫“关联”)

继承(inheritance):是一种用于表示特殊与一般关系的。如果类A扩展类B,类A不但包含从类B继承的方法,还会拥有一些额外的功能。

 

对象与对象变量:

对象对象变量之间存在着一个重要的区别。例如:

Date deadline;     //deadline doesn’t refer to any object

定义了一个对象变量deadline,它可以引用Date类型的对象。但是一定要认识到:变量deadline不是一个对象,实际上也没有引用对象。此时,不能将任何Date方法应用于这个变量上。

s = deadline.toString();    // not yet

将产生编译错误。

必须首先初始化变量deadline,这里有两个选择。当然,可以用新构造的对象初始化这个变量: deadline = new Date();

也可以让这个变量引用一个已存在的对象:deadline = birthday;

// 现在两个对象变量引用同一个对象。

一定要认识到:一个对象变量并没有实际包含一个对象,而仅仅是引用一个对象!

在Java中,任何对象变量的值(栈)都是对存储在另外一个地方(堆)的一个对象的引用。new操作符的返回值也是一个引用。

Date deadline = new Date();  有两个部分。表达式new Date()构造了一个Date类型的对象,并且它的值是对新创建对象的引用。这个引用存储在变量deadline中。

 

静态变量与静态方法:

静态方法时一种不能向对象实施操作的方法。

可以认为静态方法时没有this参数的方法(在一个非静态的方法中,this参数表示这个方法的隐式参数)。

因为静态方法不能操作对象,所以不能在静态方法中访问实例域。但是,静态方法可以访问自身类中的静态域。

使用静态方法的两种情况:

(1)一个方法不需要访问对象状态,其所需参数都是通过显示参数提供。

(2)一个方法只需要访问类的静态域。

工厂方法:静态方法的一种常见的用途。

Main方法:不需要使用对象调用静态方法。main方法不对任何对象进行操作。事实上,在启动程序时还没有任何一个对象。静态的main方法将执行并创建程序所需要的对象。

 

方法参数:按值调用(call by value) 按引用调用(callby reference)

Java程序设计语言总是采用按值调用。也就是说,方法得到的是所有参数值的一个拷贝,特别是,方法不能修改传递给他的任何参数变量的内容。

然而,方法参数共有两种类型:

(1)基本数据类型(数字、布尔值)

(2)对象引用。

一个方法不可能修改一个基本数据类型的参数。对象引用作为参数传递给方法后,方法得到的是对象引用的拷贝,而对象引用与它的拷贝同时引用同一个对象。所以,以对象引用作为参数能够改变对象内容。

(1)一个方法不能修改一个基本数据类型的参数。

(2)一个方法可以改变一个对象参数的状态。(对象引用)

(3)一个方法不能让对象参数引用一个新的对象。(不能让对象引用指向一个新的对象)

 

对象构造:

如果在构造器中没有显式地给域赋予初值,那么就会被自动地赋为默认值:数值为0、布尔值为false、对象引用为null。然而,只有缺少程序设计竟然的人才会这样做。的确,如果不明确地对域进行初始化,就会影响程序代码的可读性。

注释:这是域与局部变量的主要不同点。必须明确地初始化方法中的局部变量。但是,如果没有初始化类中的域,将会被初始化为默认值(0、false、null)。

 

仅当类没有提供任何构造器的时候,系统才会提供一个默认的构造器。如果在编写类的时候,给出了一个构造器,哪怕是很简单的,要想让这个类的用户能够采用 new ClassName()构造实例的话,就必须提供一个默认的构造器(即不带参数的构造器)。当然,如果希望所有域被赋予默认值,可以采用下列格式:

public ClassName() { );           // 如:单例模式

 

类设计技巧:

(1)一定要保证数据私有!绝对不要破坏封装性。数据的表示形式很可能会改变,但它们的使用方式却不会经常发生变化。当数据保持私有时,它们的表示形式的变化不会对类的使用者产生影响,即使出现Bug也易于检测。

(2)一定要对数据初始化!Java不对局部变量进行初始化,但是会对对象的实例域进行初始化。最好不要依赖于系统的默认值,而是应该显示地初始化所有的对象,具体的初始化方法可以是提供默认值,也可以是在所有构造器中设置默认值。

(3)不要在类中过多的使用基本类型!

(4)不是所有的域都需要独立的域访问器和域更改器!

(5)将职责过多的类进行分解!

(6)类名和方法名要能够体现他们的职责!命名类名的良好习惯是采用一个名词(Order)、前面有形容词修饰的名词(RushOrder)或动名词(ing)修饰名词(BillingAddress)。

0 0