
第10章关于对象的思考Liang,Introduction toJava Programming,EighthEdition,(c)2011Pearson Education,Inc.Allrightsreserved.0132130807
Liang, Introduction to Java Programming, Eighth Edition, (c) 2011 Pearson Education, Inc. All rights reserved. 0132130807 1 第10章 关于对象的思考

动因你可以通过前两章看到面向对象程序设计的优点。本章将演示如何使用面向对象范式解决问题。在研究这些例子之前,我们首先介绍几个支持这些示例的语言特征Liang,Introduction toJava Programming.EighthEdition,(c)2011Pearson Education,Inc.Allrightsreserved.0132130807
Liang, Introduction to Java Programming, Eighth Edition, (c) 2011 Pearson Education, Inc. All rights reserved. 0132130807 2 动 因 你可以通过前两章看到面向对象程序设计的优 点。本章将演示如何使用面向对象范式解决问 题。在研究这些例子之前,我们首先介绍几个 支持这些示例的语言特征

学习目标从不可变类创建不可变对象以保护对象的内容(第10.2节)(第10.3节)。判断类中出现的变量的作用域(第10.4节)。使用关键字this指代调用对象自己(第10.5节)。应用类的抽象类来开发软件(第10.6节)探索面向过程范式和面向对象范式的不同之处(第10.7节)。开发用于建模对象之间组合关系的类使用面向对象范式设计程序(第10.8-10.10节)按照类的设计原则来设计类(第10.11节)Liang,Introduction toJava Programming,EighthEdition,(c)2011Pearson Education,Inc.Allrightsreserved.0132130807
Liang, Introduction to Java Programming, Eighth Edition, (c) 2011 Pearson Education, Inc. All rights reserved. 0132130807 3 学习目标 从不可变类创建不可变对象以保护对象的内容 (第10.2节)。 判断类中出现的变量的作用域 (第10.3节)。 使用关键字this指代调用对象自己 (第10.4节)。 应用类的抽象类来开发软件 (第10.5节)。 探索面向过程范式和面向对象范式的不同之处 (第10.6节)。 开发用于建模对象之间组合关系的类 (第10.7节)。 使用面向对象范式设计程序 (第10.8-10.10节)。 按照类的设计原则来设计类 (第10.11节)

不可变对象和类如果一旦创建一个对象那么不能再改变它的内容,这种对象被称为不可变对象(immutableobject),而它的类就被称为不可变类(immutableclass)。如果删掉前面例子中Circle类的set方法,那么该类就变成不可变类,因为半径是私有的,所以没有set方法它的值就不能再改变一个类所有数据都是私有的且没有修改器,并不意味着它一定是不可变类。例如:下面的Student类,它的所有数据域都是私有的,而且也没有set方法,但它不是一个不可变的类。Liang,Introduction toJava Programming.EighthEdition,(c)2011Pearson Education,Inc.Allrightsreserved.0132130807
Liang, Introduction to Java Programming, Eighth Edition, (c) 2011 Pearson Education, Inc. All rights reserved. 0132130807 4 不可变对象和类 如果一旦创建一个对象那么不能再改变它的内容,这种对 象被称为不可变对象(immutable object),而它的类就被 称为不可变类(immutable class)。如果删掉前面例子中 Circle类的set方法,那么该类就变成不可变类,因为半径 是私有的,所以没有set方法它的值就不能再改变。 一个类所有数据都是私有的且没有修改器,并不意味着它 一定是不可变类。例如:下面的Student类,它的所有数据 域都是私有的,而且也没有set方法,但它不是一个不可变 的类

举例publicclassBirthDatefprivate int year;public class student (private int month;private int id;private int day;private BirthDate birthDate;public student(int ssn,public BirthDate(int newYear,int year,int month, int day) (int newMonth, int newDay)3id = ssn;year = newYear;birthDate - new BirthDate(year, month,day);month = newMonth;1day = newDayipublic int getId()(1return id;1publicvoid setYear(int newYear)(public BirthDate getBirthDate()(year = newYear;return birthDate;1public class Test (public static void main(stringl args)(Studentstudent=new Student(111223333,1970,5,3);BirthDate date= student.getBirthDate();date.setYear(2oio)i // Now the student birth year is changed!1Liang,Introduction toJavaProgramming.EighthEdition,(c)2011PearsonEducation,Inc.Allrightsreserved.0132130807
Liang, Introduction to Java Programming, Eighth Edition, (c) 2011 Pearson Education, Inc. All rights reserved. 0132130807 5 举 例 public class Student { private int id; private BirthDate birthDate; public Student(int ssn, int year, int month, int day) { id = ssn; birthDate = new BirthDate(year, month, day); } public int getId() { return id; } public BirthDate getBirthDate() { return birthDate; } } public class BirthDate { private int year; private int month; private int day; public BirthDate(int newYear, int newMonth, int newDay) { year = newYear; month = newMonth; day = newDay; } public void setYear(int newYear) { year = newYear; } } public class Test { public static void main(String[] args) { Student student = new Student(111223333, 1970, 5, 3); BirthDate date = student.getBirthDate(); date.setYear(2010); // Now the student birth year is changed! } }

什么样的类是不可变的?要使一个类成为不可变的,它必须标记所有数据域都是私有的,没有提供修改器的方法以及没有提供会返回一个指向可变数据域的引用的访问器方法Liang.Introduction to JavaProgramming.EighthEdition,(c)2011Pearson Education,Inc.Allrightsreserved.0132130807
Liang, Introduction to Java Programming, Eighth Edition, (c) 2011 Pearson Education, Inc. All rights reserved. 0132130807 6 什么样的类是不可变的? 要使一个类成为不可变的,它必须标记所有数据域都 是私有的,没有提供修改器的方法以及没有提供会返 回一个指向可变数据域的引用的访问器方法

变量的作用域实例变量和静态变量的作用域是整个类。可以在类内的任何地方声明它们局部变量的作用域是从它声明的地方开始一直到所包含这个局部变量的模块结束。一个局部变量必须在使用前显式地初始化Liang,Introduction toJava Programming,EighthEdition,(c)2011Pearson Education,Inc.Allrightsreserved.0132130807
Liang, Introduction to Java Programming, Eighth Edition, (c) 2011 Pearson Education, Inc. All rights reserved. 0132130807 7 变量的作用域 实例变量和静态变量的作用域是整个类。可以 在类内的任何地方声明它们。 局部变量的作用域是从它声明的地方开始一直 到所包含这个局部变量的模块结束。一个局部 变量必须在使用前显式地初始化

this关键字关键字this是指向调用对象本身的引用名。关键字this的一种常见用法就是引用类的隐藏数据域(hiddendatafields)关键字this的另一种常见用法是让构造方法调用同一个类的另一个构造方法。Liang,Introduction toJava Programming,EighthEdition,(c)2011Pearson Education,Inc.Allrightsreserved.0132130807
Liang, Introduction to Java Programming, Eighth Edition, (c) 2011 Pearson Education, Inc. All rights reserved. 0132130807 8 this关键字 关键字this是指向调用对象本身的引用名。关 键字this的一种常见用法就是引用类的隐藏数 据域(hidden data fields)。 关键字this的另一种常见用法是让构造方法调 用同一个类的另一个构造方法

引用隐藏数据域public class Foof假设f1和f2是Foo的两个对象。private int i = 5;private static double k=O;调用f1.setI(10)其实就是执行this.i=1o,这里this是指f1void setI(int i)this.i =i调用f2.setI(45)其实就是执行this.i=45,这里this是指f2static void setK(doublek)Foo.k = k;Liang.Introduction to JavaProgramming.EighthEdition,(c)2011Pearson Education,Inc.Allrightsreserved.0132130807
Liang, Introduction to Java Programming, Eighth Edition, (c) 2011 Pearson Education, Inc. All rights reserved. 0132130807 9 引用隐藏数据域 public class Foo { private int i = 5; private static double k = 0; void setI(int i) { this.i = i; } static void setK(double k) { Foo.k = k; } } 假设f1和f2是Foo的两个对象。 调用 f1.setI(10) 其实就是执行 this.i = 10, 这里 this 是指 f1 调用 f2.setI(45) 其实就是执行 this.i = 45, 这里 this 是指 f2

调用重载的构造方法public class circle {private double radius;public circle(double radius) (this.radius = radius;1显式使用this来引用被创建对象的数据域radiuspublic circle()this(1.0);1使用this来调用另一个构造方法public double getArea() (n this.radius this.radius * Math.PI;return111每个实例变量都属于一个this表示的实例,通常这个this是被忽略的。Liang,Introduction toJava Programming,EighthEdition,(c)2011Pearson Education,Inc.All10rightsreserved.0132130807
Liang, Introduction to Java Programming, Eighth Edition, (c) 2011 Pearson Education, Inc. All rights reserved. 0132130807 10 调用重载的构造方法 public class Circle { private double radius; public Circle(double radius) { this.radius = radius; } public Circle() { this(1.0); } public double getArea() { return this.radius * this.radius * Math.PI; } } 每个实例变量都属于一个 this 表示的实例,通常这个 this 是被忽略的。 显式使用 this 来引用被创建对象的数 据域 radius 使用 this 来调用另一个构造方法