欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

第4章 对象与类

程序员文章站 2022-05-07 15:20:57
...

1.在对象与对象变量之间存在着一个重要的区别。
例如 , 语句
Date deadline ; / / deadline doesn ' t refer to any object
定义了一个对象变量 deadline , 它 可 以 引 用 Date 类型的对象。
但是 , 一定要认识到 :
变量deadline 不是一个对象 , 实际上也没有引用对象。
此时 , 不能将任何Date 方法应用于这个变量上。
语句
s = deadline . toStringO ; / / not yet
将产生编译错误。
必须首先初始化变量 deadline , 这里有两个选择。
当然 , 可以用新构造的对象初始化这个变量 :
deadline = new Date ( ) ;
也让这个变量引用一个已存在的对象 :
deadline = birthday ;

2、java 日期类LocalDays之后深入研究。

3、在这个示例程序中包含两个类 : Employee 类和带有 public 访问修饰符EmployeeTest
类。 EmployeeTest 类包含了main 方法, 其中使用了前面介绍的指令 。源文件名是EmployeeTest . java, 这是因为文件名必须与 public 类的名字相匹配 。 在一个
源文件中,只能有一个公有类, 但可以有任意数目的非公有类 。
接下来, 当编译这段源代码的时候 ,
编译器将在目录下创建两个类文件 :
EmployeeTest .class 和 Employee . class
将程序中包含 main 方法的类名提供给字节码解释器 , 以便启动这个程序 :
java EmployeeTest
字节码解释器开始运行 EmployeeTest 类的 main 方法中的代码 。 在这段代码中 , 先后构
造了三个新 Employee 对象 , 并显示它们的状态 。

4.构造器与其他的方法有一个重要的不同。 构造器总是伴随着new 操作符的执行被调用
,而不能对一个已经存在的对象调用构造器来达到重新设置实例域的目的。

5、C + + 注释:
Java 构造器的工作方式与 C + + — 样 。 但是 , 要记住所有的 Java 对象都是在 Java 构造器的工作方式与 C + + — 样 。 但是 , 要记住所有的 Java 对象都是在堆中构造的 , 构造器总是伴随着 new 操作符一起使用 。 C + + 程序员最易犯的错误就是忘记 new 操作符 :

Employee number 007 ( " ] anie 5 Bond " , 100000 , 1950 , 1 , 1 ) ;// C + + , not Java

这条语句在 C + + 中能够正常运行, 但在Java 中却不行。

6、警告 : 请注意 , 不要在构造器中定义与实例域重名的局部变量
。 例如 , 下面的构造器将无法设置 salary。
public Employee ( St ring n , double s , . .
{
String name = n ; / / Error
double salary = s ; / / Error
}
这个构造器声明了局部变量 name 和 salary。 这些变量只能在构造器内部访问 。 这些变量屏蔽了同名的实例域有些程序设计者常常不假思索地写出这类代码,因为他们已经习惯增加这类数据类型 。 这种错误很难被检查出来, 因此 ,必须注意在所有的方法中不要命名与实例域同名的变量 。

7、警告 : 注意不要编写返回引用可变对象的访问器方法 。 在 Employee 类中就违反了这个设
计原则 , 其中的 getHireDay 方法返回了一个 Date 类对象 :

class Employee
{
private Date hireDay ;
public Date getHireDayO
{
return hireDay ; / / Bad

LocalDate 类没有更改器方法 , 与之不同 , Date 类有一个更改器方法 setTime , 可以
在这里设置毫秒数。Date 对象是可变的 , 这一点就破坏了封装性 !

8、一个方法可以访问所属类的所有对象的私有数据, 这令很多人感到奇怪! 例如, 下面看一下用来比较两个雇员的 equals 方法 。
class Employee
{
public boolean equals ( Employee other )
{
return name . equals ( other . name ) ;
}
}
典型的调用方式是
if ( harry , equals ( boss ) ) . . .
这个方法访问 harry 的私有域 , 这点并不会让人奇怪, 然而 , 它还访问了
boss 的私有域。 这是合法的 , 其原因是 boss 是 Employee 类对象 , 而 Employee 类的方法可以访问 Employee 类的任何一个对象的私有域。

9、final 修饰符大都应用于基本 ( primitive ) 类型域, 或不可变 ( immutable )类的域 ( 如果类中的每个方法都不会改变其对象 , 这种类就是不可变的类。 例如 , String 类就是一个不可变的类 ) 。对于可变的类,使用 final 修饰符可能会对读者造成混乱。
例如 ,
private final StringBuiIcier evaluations ;
在 Employee 构造器中会初始化为
evaluations = new StringBuilder ( ) ;
final 关键字只是表示存储在 evaluations 变量中的对象引用不会再指示其他 StringBuilder
对象 。 不过这个对象可以更改 :

public void giveGoldStarO
{
evaluations . append ( LocalDate . now ( ) + " : Gold star ! \ n " ) ;
}

10、静态方法是一种不能向对象实施操作的方法。可以认为静态方法是没有this参数(隐式参数)的方法,静态方法因此不能访问自身类的实例域,但是静态方法可以访问自身类中的静态域。非静态方法可以访问自身类的静态域吗?答案是当然的,非静态方法可以访问自身类的所有域。

11、直接通过类名或者类对象实例都可以调用静态方法,但是因为静态方法与类对象实例本身往往没有关系,所以通常建议用类名,而不是对象类调用静态方法。

12、提示 : 每一个类可以有一个 main 方法。 这是一个常用于对类进行单元测试的技巧 。 例如,可以在 Employee 类中添加一个 main 方法 。如果想要独立地测试 Employee 类 , 只需要执行
java Employee
如果 Employee 类是一个更大型应用程序的一部分,就可以使用下面这条语句运行程序
java Application
Employee 类的 main 方法永远不会执行 。

13、很多程序设计语言 ( 特别是 , C ++ 和 Pascal ) 提供了两种参数传递的方式 : 值调用和引用调用。 有些程序员 ( 甚至本书的作者 ) 认为 Java程序设计语言对对象采用的是引用调用,实际上 , 这种理解是不对的 。 由于这种误解具有一定的普遍性 , 所以下面给出一个反例来详细地阐述一下这个问题。首先, 编写一个交换两个雇员对象的方法 :
public static void swap ( Employee x , Employee y ) / / doesn ’ t work
Employee temp = x ;
x = y ;
y = temp ;
}
如果 Java 对对象采用的是按引用调用, 那么这个方法就应该能够实现交换数据的效果 :
Employee a = new Employee ( " Alice " , . . . ) ;
Employee b = new Employee ( " Bob " , . . . ) ;
swap ( a , b ) ;/ / does a now refer to Bob , b to Alice ?
但是, 方法并没有改变存储在变量 a 和 b 中的对象引用 。 swap 方法的参数 x和 y 被初始
化为两个对象引用的拷贝, 这个方法交换的是这两个拷贝 。
/ / x refers to Alice , y to Bob
Employee temp = x ;
x = y ;
y = temp ;
/ / now x refers to Bob , y to Alice
最终, 白费力气 。 在方法结束时参数变量X 和 y 被丢弃了 。 原来的变量 a 和 b 仍然引用这个方法调用之前所引用的对象。这个过程说明 : Java 程序设计语言对对象采用的不是引用调用, 实际上 , 对象引用是按值传递的 。

14、包、类路径、注释部分之后再研究。