Presentation is loading. Please wait.

Presentation is loading. Please wait.

第4章 类 和 对 象.

Similar presentations


Presentation on theme: "第4章 类 和 对 象."— Presentation transcript:

1 第4章 类 和 对 象

2 教学目标 理解数据抽象和数据隐藏 创建类 能够创建和使用对象 能够控制对实例变量和方法的访问 方法的重载 构造函数的使用
理解this引用的用法 理解Java的垃圾收集机制 static方法和域的使用 类的组合 包的创建和使用

3 4.1 面向对象程序设计的思想 4.1.1 OOP思想 4.1.2 用类实现抽象数据类型:时钟类 4.1.3 类成员:构造函数、方法和域

4 4.1.1 OOP思想 面向对象编程技术 将数据及对数据的操作封装在一起而形成了类,类是描述相同类型的对象集合。 面向对象编程(object-oriented programming,OOP)就是定义这些类。 类作为抽象的数据类型用于创建类的对象。 程序的执行,表现为一组对象之间的交互通信。对象之间通过公共接口进行通信,从而完成系统功能。对象的公共接口是该对象的应用程序编程接口,把对象的内部详细信息隐藏起来,使得对象变得抽象,将这种技术称为数据的抽象化。 Java语言是完全面向对象的语言,程序的结构由一个以上的类组成。所有的过程都被封装起来,并将它们称之为方法。

5 4.1.2 用类实现抽象数据类型:时钟类 类作为一种抽象的数据类型,封装了对象的数据属性和动态行为,被用来定义类的对象。 时钟类的设计:
下面我们将通过一个具体的实例来理解什么是类,如何定义类、创建对象和使用对象。 时钟类的设计: (1) 数据属性: 时(int hour); 分 (int minute); 秒 (int second)。 (2) 行为: 设置时间 setTime() ; 显示时间 toUniversalString() 、 toStandardString() ; 走时run() ;

6 4.1.2 用类实现抽象数据类型:时钟类(续) 例4-1 时钟类的实现。
该例子包含两个文件Time1.java和TimeTest1.java。 Time1.java是用于定义时钟类。 TimeTest1类是一个用于测试时钟类的包含main方法的主类,在main方法中将创建Time1类的一个对象,并调用对象的公共方法。

7 4.1.2 用类实现抽象数据类型:时钟类(续) Time1.java文件的代码如下: 时
public class Time1 extends Object { private int hour; private int minute; private int second; public Time1(){ setTime( 0, 0, 0 ); } public void setTime( int h, int m, int s ){ hour = ( ( h >= 0 && h < 24 ) ? h : 0 ); minute = ( ( m >= 0 && m < 60 ) ? m : 0 ); second = ( ( s >= 0 && s < 60 ) ? s : 0 ); 构造方法 设置时间

8 4.1.2 用类实现抽象数据类型:时钟类(续) 以24时制格式显示时间 public String toUniversalString(){ return hour + ":" + minute + ":" + second ; } public String toStandardString(){ return ( (hour == 12 || hour == 0) ? 12 : hour % 12 ) + ":" + minute + ":" +second+( hour < 12 ? " AM" : " PM" ); 以12时制格式显示时间

9 创建Time1类的第一个对象并赋给引用变量time1
TimeTest1.java文件的代码: //TimeTest1.java import javax.swing.JOptionPane; public class TimeTest1 { public static void main( String args[] ){ Time1 time1 = new Time1(); String output = "time1对象建立后\n24时制格式时间: " + time1.toUniversalString() + "\n12时制格式时间: " + time1.toStandardString(); time1.setTime( 13, 27, 6 ); output += "\n 用setTime方法( 13, 27, 6 )修改time1对象后"+ "\n24时制格式时间: " + time1.toUniversalString() + "\n12时制格式时间: " + time1.toStandardString(); Time1 time2 = new Time1(); time2.setTime( 11, 27, 12 ); output += "\n\ntime2对象 \n24时制格式时间: " + time2.toUniversalString() + " \n12时制格式时间: " + time2.toStandardString(); time2.setTime( 99, 89, 99 ); //设置对象time2的值 //显示对象time2的值 创建Time1类的第一个对象并赋给引用变量time1 通过引用变量time1 调用第一个Time1对象的的成员方法 创建Time1类的第二个对象并赋给引用变量time2 通过引用变量time1 调用第一个Time1对象的的成员方法

10 4.1.2 用类实现抽象数据类型:时钟类(续) 程序运行的结果为:
output += "\n 用setTime方法( 99, 89, 99 )修改time2对象后\n24时制格式时间: " + time2.toUniversalString() + "\n12时制格式时间:: " + time2.toStandardString(); JOptionPane.showMessageDialog( null, output, "时钟类测试:建立了两时钟对象", JOptionPane.INFORMATION_MESSAGE ); System.exit( 0 ); } 程序运行的结果为:

11 4.1.3 类成员:构造函数、方法和域 定义类的语法格式: 例 [类的修饰符] class 类名 [extends 父类名] {
…… //类体 } public class Time1 extends object{ ……

12 4.1.3 类成员:构造函数、方法和域 (续) 1.域 一个类的数据属性由它的成员变量(域field)定义。在类中声明一个域的形式为:
[域修饰符] 类型 域名; 例: private int hour; private int minute; private int second; 定义在类的每一个数据成员都有一个缺省值.

13 类中的数据成员的缺省值 0.0F 0.0D null 缺省数值 false ‘\u 0000’ 数据类型 关键字 布尔型 boolean
字符型 char ‘\u 0000’ 字节型 byte 短整型 short 整型 int 长整型 long 浮点型 float 0.0F 双精度型 double 0.0D 引用类型 类、接口 null

14 4.1.3 类成员:构造函数、方法和域(续) 2. 方法(method) 3. 构造方法(constructor)
方法一般是对类中的数据成员进行操作。如果类中的数据成员是private型的,则往往定义一个public的方法来设置数据成员的值或读取数据成员的值。 3. 构造方法(constructor) Time1类包含一个构造函数Time1(). 构造方法名同类名。 构造方法一般用于初始化某个类的对象。 在程序创建Time1类的对象时,new运算符为该对象分配内存,并调用构造函数来初始化该对象,也就是通过调用Time1类的构造函数,在构造函数中给对象的各成员变量赋初值。

15 4.2 类的作用域 定义类的作用域的修饰符(modifier):
public(公共作用域):一个具有公共作用域的类在封装它的包外面是可见的; package(包作用域,缺省值):一个具有包作用域的类只是在封装它的包中是可见的。 sub1\ 当前路径D:\javaExamples C22 C21 sub3\ sub4\ C3 C1 类的使用: C1 sub1.C21 sub1.C22 sub3.sub4.C3

16 4.2 类的作用域(续) 例如:如何声明类的作用域 public class C1{ //…成员 } ….
sub1\ 当前路径D:\javaExamples C22 C21 sub3\ sub4\ C3 C1

17 4.2 类的作用域(续) classpath= D:\javaExamples 例如:如何声明类放入相应的包中
public class C1{ //…成员 } sub1\ 当前路径D:\javaExamples C22 C21 sub3\ sub4\ C3 C1 package sub1; public class C21{ //…成员 } class C22 {….} package sub3.sub4; class C3{ //…成员 }

18 4.3 成员访问控制(member access specifier)
成员访问控制是用来控制类中成员的访问范围,由修饰符声明。表4-1列出了常见的成员访问控制修饰符。 表4-1 成员访问控制修饰符 修 饰 符 作 用 public 说明公共成员,可以在类外被使用 protected 说明保护成员,在同一包中或子类中被使用 package(缺省值) 说明包作用域成员,该成员只能在同一包中被使用 private 说明私有成员,该成员只能在类中访问 例4-2 成员访问控制示例

19 例4-2 成员访问控制示例 public class Time1 extends Object {
//TimeTest2.java public class TimeTest2 { public static void main( String args[] ){ Time1 time = new Time1(); time.hour = 7; //error time.minute = 15; //error time.second = 30; //error } public class Time1 extends Object { private int hour; // private int minute; // private int second; // public Time1(){ ...... } public void setTime( int h, int m, int s ){ public String toUniversalString(){ public String toStandardString(){

20 例4-3 成员访问控制示例2 public class accessModifier { private int a; int b;
protected double c; public char d; public void setA(int a1) {a=a1;} } class accessModifierTest { public static void main( String args[] ){ accessModifier obj = new accessModifier(); obj.setA(1); obj.b = 2; obj.c = 1.5; obj.d='#'; accessModifier和accessModifierTest类在同一个无名包中

21 4.4 初始化类的对象:构造方法 构造方法用于为类的新建的对象分配内存空间和进行初始化. 定义必须构造方法时,注意两点:
①构造方法与类名相同; ②构造方法没有返回类型,但可以有参数,并且可以重载。 构造方法只能在创建对象时用new命令调用。

22 4.4 初始化类的对象:构造方法 如果一个类中未定义构造方法,则编译时系统提供一个缺省的无参的构造方法,其方法体为空。
public 类名( ) { } 用new创建类的对象的语句: new 类名(…. )

23 4.4 初始化类的对象:构造函数(续) 不带参数的构造函数 带一个参数的构造函数 带两个参数的构造函数 带三个参数的构造函数
例4-4举例说明构造函数的重载。 Time4.java文件的部分代码: …… //5个重载的构造函数 public Time4(){ setTime( 0, 0, 0 ); } public Time4( int h ) { setTime( h, 0, 0 ); public Time4( int h, int m ){ setTime( h, m, 0 ); public Time4( int h, int m, int s ) { setTime( h, m, s ); public Time4( Time4 time ){ setTime( time.hour, time.minute, time.second ); 不带参数的构造函数 带一个参数的构造函数 带两个参数的构造函数 带三个参数的构造函数 带一个参数为对象的构造函数

24 //TimeTest4.java import javax.swing.*; public class TimeTest4 { public static void main( String args[] ){ Time4 t1 = new Time4(); // 00:00:00 Time4 t2 = new Time4( 2 ); // 02:00:00 Time4 t3 = new Time4( 21, 34 ); // 21:34:00 Time4 t4 = new Time4( 12, 25, 42 ); // 12:25:42 Time4 t5 = new Time4( t4 ); // 12:25:42 ……. }

25 4.5 this this:定义为被调用的方法的当前对象的引用。 this引用仅能出现在类中的方法体中。 例4-5 this的使用

26 class SimpleTime { private int hour, minute, second; ...... public SimpleTime( int hour, int minute, int second ){ this.hour = hour; this.minute = minute; this.second = second; } public String buildString(){ return "this.toStandardString(): " + this.toStandardString() + "\ntoStandardString(): " + toStandardString(); public String toStandardString(){ DecimalFormat twoDigits = new DecimalFormat( "00" ); return twoDigits.format( this.hour ) + ":" + twoDigits.format( this.minute ) + ":" + twoDigits.format( this.second );

27 4.5 this(续) 例子说明如何隐式地和显式地使用this引用。
例子中SimpleTime类的构造方法的三个参数名与SimpleTime类三个成员变量名相同。在这种情况下,局部变量在该方法作用域中屏蔽了同名的域。我们可以使用this来显式地引用屏蔽的域。 通过this不但可以引用成员变量,也可通过this引用方法,包括构造函数。本例子中通过this引用方法。

28 //5个重载的构造函数 public Time4(){ this( 0, 0, 0 ); } public Time4( int h ) { this( h, 0, 0 ); public Time4( int h, int m ){ this( h, m, 0 ); public Time4( int h, int m, int s ) { setTime( h, m, s ); public Time4( Time4 time ){ this( time.hour, time.minute, time.second );

29 4.6使用set和get方法 例4-6 set和get方法的使用

30 public class Time2 { ...... public void setHour( int h ){ //setHour方法 hour = ( ( h >= 0 && h < 24 ) ? h : 0 ); } public void setMinute( int m ){ //setMinute方法 minute = ( ( m >= 0 && m < 60 ) ? m : 0 ); public void setSecond( int s ){ //setSecond方法 second = ( ( s >= 0 && s < 60 ) ? s : 0 ); public int getHour(){ //getHour方法 return hour; public int getMinute(){ //getMinute方法 return minute; public int getSecond(){ // getSecond方法 return second;

31 GradeBook类的设计: course name teacher GradeBook(….)
Set and get course Name Set and get teacher

32 4.7 垃圾收集(Garbage Collector)
Java平台允许创建任意多个对象(当然会受到系统资源的限制),而且当对象不再使用时自动会被清除,这个过程就是所谓的“垃圾收集”。当对象不再被引用的时候,对象就会被作为垃圾收集的对象而清除。为了使对象不再被引用,可以通过设置执行指向某一对象的引用为null。例如: Time1 time=new Time1(); time=null; 1.垃圾收集器 调用System.gc()方法,将显式地运行垃圾收集程序. 2.撤销方法finalize 在对象被回收空间之前,调用对象的finalize()方法.

33 4.8 static方法和域 当声明一个成员变量时, 例如: static int count; 类的静态成员的一般使用格式为:
可以指定成员变量是属于 一个类的各个对象所拥有( 称为实例变量)。 还是属于一个类的所有对象共享(或称为类范围的变量).属于类范围的成员称为静态成员,以关键字static声明。 例如: static int count; 类的静态成员的一般使用格式为: 类名.静态变量名; 类名.静态方法名(); 例4-7静态方法和域的应用

34 public class Employee { private String lastName;
private String firstName; private String lastName; private static int count = 0; public Employee( String first, String last ){ firstName = first; lastName = last; ++count; System.out.println( "Employee constructor: " + firstName + " " + lastName ); } protected void finalize(){ --count; System.out.println( "Employee finalizer: " + firstName + " " + lastName + "; count = " + count ); public String getFirstName(){ return firstName; public String getLastName(){ return lastName; public static int getCount(){ return count; }

35 import javax.swing.*; public class EmployeeTest { public static void main( String args[] ){ String output = "Employees before instantiation: " + Employee.getCount(); Employee e1 = new Employee( "Susan", "Baker" ); Employee e2 = new Employee( "Bob", "Jones" ); output += "\n\nEmployees after instantiation: " + "\nvia e1.getCount(): " + e1.getCount() + "\nvia e2.getCount(): " + e2.getCount() + "\nvia Employee.getCount(): " + Employee.getCount(); output += "\n\nEmployee 1: " + e1.getFirstName() + " " + e1.getLastName() + "\nEmployee 2: " + e2.getFirstName() + " " + e2.getLastName(); e1 = null; e2 = null; System.gc(); // 显式地运行垃圾收集程序 output += "\n\nEmployees after System.gc(): " + Employee.getCount(); JOptionPane.showMessageDialog( null, output, "静态方法和域", JOptionPane.INFORMATION_MESSAGE ); System.exit( 0 ); }

36 4.8 static方法和域 运行结果

37 static方法的方法体中使用的成员必须是static 成员
注意: static方法的方法体中使用的成员必须是static 成员 class P { …. static public void main(…) { f2(…); } static void f2(…) { …..

38 4.9 类的组合(Composition) 例4-8 类的组合 类的组合:一个类中的成员可以是其他类的引用。
组合是类之间的 “has a”的关系. 例4-8 类的组合

39 4.10 包(package)的创建和访问 包的创建 包的使用

40 4.10.1 包的创建 package语句建立包。 package语句必须是整个java文件的第一个语句。 创建package语句格式:
例如: 将在当前目录下创建一个包,包名为 cn.edu.sytu.it.ch04,Time1.class放在此包中。 package cn.edu.sytu.it.ch04; public class Time1 {┅} 无名包: …. Time1.java Time1.java

41 4.10.2 包的使用 import语句:导入用户的源代码文件中使用的其他包中的类, 这些类和当前类不在同一个包中。 例如:
import cn.edu.sytu.it.ch04.Time1; import cn.edu.sytu.it.ch04.*; *表示导入整个包,即导入整个子包cn.edu.sytu.it.ch04中的所有类,但不包括cn.edu.sytu.it.ch04中的子包。 如果没有使用import语句导入某个包,但又想使用它的某个类,也可以直接在所需要的类名前加上包名前缀。 例如,要使用类Time1类创建一个对象time,语句如下: cn.edu.sytu.it.ch04.Time1 time= new cn.edu.sytu.it.ch04.Time1(); 例4-9 包的创建及使用

42 小结 本章介绍了面向对象程序设计的重要概念——类和对象。类是一种抽象的数据类型,用来表示具有相同性质的一类事物。类封装了对象的属性和方法。类的实例化产生了对象。 一个类的成员包括域、方法和构造函数。 方法和构造函数都可以进行重载。 在定义类时可以通过访问控制符来限定其它类对该类及类的成员的访问。 为了使一个类的所有对象共享同一个变量的值,可以将成员变量定义成静态static的。 类和类之间的访问也可通过包来进行控制。

43 [作业与实验] 作业 书P77: 1 2 4 9 实验 1. 完善时钟类的设计,使包含走时等功能。 2 (实验6)

44 走时功能的设计 //完成走n秒 //完成走1秒 public void run( int n) { public void run() {
for (int i=0;i<n;i++) run(); } //完成走1秒 public void run() { //延迟 1秒 try { Thread.sleep(1000); } catch (InterruptedException e) { System.out.println(" wake up!"); second++; if (second>=60) { minute++; second=0; if (minute>=60) { minute=0; hour++; if (hour>=24) hour=0;


Download ppt "第4章 类 和 对 象."

Similar presentations


Ads by Google