Download presentation
Presentation is loading. Please wait.
1
第四章 类 和 对 象
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)就是定义这些类。 类作为抽象的数据类型用于创建类的对象。 程序的执行,表现为一组对象之间的交互通信。对象之间通过公共接口进行通信,从而完成系统功能。对象的公共接口是该对象的应用程序编程接口(Application Programming Interface,API),把对象的内部详细信息隐藏起来,使得对象变得抽象,将这种技术称为数据的抽象化。 Java语言是完全面向对象的语言,程序的结构由一个以上的类组成。所有的过程都被封装起来,并将它们称之为方法。
5
4.1.2 用类实现抽象数据类型:时钟类 类作为一种抽象的数据类型,封装了对象的数据属性和动态行为,被用来定义类的对象。 时钟类的设计:
下面我们将通过一个具体的实例来理解什么是类,如何定义类、创建对象和使用对象。 时钟类的设计: (1) 数据属性: 时(int hour); 分 (int minute); 秒(int second)。 (2) 行为: 设置时间 setTime() ; 显示时间 toUniversalString() 、 toStandardString() ; 走时 (暂时不考虑);
6
4.1.2 用类实现抽象数据类型:时钟类(续) 例4-1 时钟类的实现。
该例子包含两个文件Time1.java和TimeTest1.java。 Time1.java是用于定义时钟类。 TimeTest1类是一个用于测试时钟类的包含main方法的主类,在main方法中将创建Time1类的一个对象,并调用对象的公共方法。
7
4.1.2 用类实现抽象数据类型:时钟类(续) Time1.java文件的代码如下:
import java.text.DecimalFormat; 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时制格式显示时间 以12时制格式显示时间
public String toUniversalString(){ //toUniversalString方法以24时制格式显示时间 DecimalFormat twoDigits = new DecimalFormat( "00" ); return twoDigits.format( hour ) + ":" + twoDigits.format( minute ) + ":" + twoDigits.format( second ); } public String toStandardString(){ //toStandardString方法以12时制格式显示时间 return ( (hour == 12 || hour == 0) ? 12 : hour % 12 ) + ":" + twoDigits.format( minute ) + ":" + twoDigits.format( second ) + ( hour < 12 ? " AM" : " PM" ); 以12时制格式显示时间
9
4.1.2 用类实现抽象数据类型:时钟类(续) 创建Time1类的对象time TimeTest1.java文件的代码:
import javax.swing.JOptionPane; public class TimeTest1 { public static void main( String args[] ){ Time1 time = new Time1(); String output = "The initial universal time is: " + time.toUniversalString() + "\nThe initial standard time is: " + time.toStandardString(); time.setTime( 13, 27, 6 ); output += "\n\nUniversal time after setTime is: " + time.toUniversalString() + "\nStandard time after setTime is: " + time.toStandardString(); time.setTime( 99, 99, 99 ); output += "\n\nAfter attempting invalid settings: " + "\nUniversal time: " + time.toUniversalString() + "\nStandard time: " + time.toStandardString(); JOptionPane.showMessageDialog( null, output, "时钟类测试", JOptionPane.INFORMATION_MESSAGE ); System.exit( 0 ); } 创建Time1类的对象time 调用时钟类的toUniversalString()方法 调用时钟类的toStandardString()方法
10
4.1.2 用类实现抽象数据类型:时钟类(续) 程序运行的结果为:
11
4.1.3 类成员:构造函数、方法和域 定义类的语法格式如下: [类的修饰符] class 类名 [extends 父类名] {
…… //类体 }
12
4.1.3 类成员:构造函数、方法和域 (续) 1.域 一个类的数据属性由它的成员变量(域field)定义。在类中声明一个域的形式为: [域修饰符] 类型 域名;
13
4.1.3 类成员:构造函数、方法和域(续) 2. 方法 3. 构造函数
方法一般是对类中的数据成员进行操作。如果类中的数据成员是private型的,则往往定义一个public的方法来设置数据成员的值或读取数据成员的值。 3. 构造函数 Time1类包含一个构造函数Time1(),构造函数的名和类名是一样的。构造函数一般用于初始化某个类的对象。在程序创建Time1类的对象时,new运算符为该对象分配内存,并调用构造函数来初始化该对象,也就是通过调用Time1类的构造函数,在构造函数中给对象的各成员变量赋初值。
14
4.2 类的作用域 Java中用于定义类的作用域的修饰符有两个:
public(公共作用域):一个具有公共作用域的类在封装它的包外面是可见的; package(包作用域):一个具有包作用域的类只是在封装它的包中是可见的。如果一个类声明的前面没有public关键字,则此类默认为包作用域。 例如: class C1{ //…成员 } public class C2{
15
4.2 类的作用域(续) 例如: package examplePkg1; class C3{ //…成员 }
16
4.2 类的作用域(续) 假如在C4类声明的前面加上public,如下所示: package examplePkg2;
public class C4{ //…成员 }
17
4.3 成员访问控制 成员访问控制是用来控制类中成员的访问范围,由修饰符声明。表4-1列出了常见的成员访问控制修饰符。
表4-1 成员访问控制修饰符 修 饰 符 作 用 public 说明公共成员,可以在类外被使用 protected 说明保护成员,在同一包中或子类中被使用 package(缺省值) 说明包作用域成员,该成员只能在同一包中被使用 private 说明私有成员,该成员只能在类中访问 例4-2 成员访问控制示例
18
4.4 方法 4.4.1 方法的声明与局部变量 4.4.2 方法的参数传递 4.4.3 使用set和get方法
4.4.4 方法重载(overloading)
19
4.4.1 方法的声明与局部变量 方法声明的格式为: [修饰符] 返回类型 方法名([形式参数表]) { …… //方法体 }
20
4.4.1 方法的声明与局部变量(续) 方法声明中的符号含义:
修饰符:方法访问控制常见的有public、protected和privated。 返回类型:一个方法必须声明其返回类型,如果无返回值,则必须声明其返回类型为void。一个方法可以返回简单数据类型或任何引用类型的值,也可以返回任何类的对象。一个方法通过return语句返回并将返回值紧跟return语句之后。如果一个方法返回类型为void。这个方法也必须包含一个return语句,只是在return语句之后不再带有返回值。 方法名可以是任何合法的Java标识符。 形式参数:当编写一个方法时,要声明该方法所需要的若干参数和这些参数的类型。这是在声明一个方法时,通过列出它的参数表来完成的。参数表指明每个参数的名字和类型,各参数之间用逗号分开。在方法体中,可以直接用这些参数名来引用参数的值。
21
4.4.1 方法的声明与局部变量(续) 方法体:方法体中包含了实现这个方法具体功能的代码。
方法体中声明的变量,只在方法内使用。即它们是该方法的局部变量。 如果方法声明的局部变量与封装该方法的类所声明的一个实例变量同名,则在该方法的作用域中,局部变量屏蔽实例变量。若要在该方法中访问被屏蔽的实例变量,可在其名称前加上关键字this和点运算符(),形式为: this.变量名;
22
4.4.1 方法的声明与局部变量(续) 例如: class C1{ int i; method1(){ int i=0; int j;
this.i=i+10; j=5; } 实例变量i 局部变量i 取局部变量i的值 通过this.i调用实例变量i
23
4.4.2 方法的参数传递 Java的参数传递方式是通过值来传递的,也称为“值传递”。对于这种值传递要区分如下两种情况:
①当方法的参数为简单数据类型时,则将实参的值传递给形参; ②当方法的参数为复合数据类型(对象)时,则将实参的地址传给形参。
24
4.4.3 使用set和get方法 如果类中声明了private成员变量,则只能通过该类的方法来操作这些成员变量。类常常提供公有方法以允许该类的用户设置或者读取private实例变量。 例4-3 set和get方法的使用
25
4.4.4 方法重载(overloading) Java支持方法的重载,方法的重载定义为在一个类中定义多个同名的方法。下面举例说明方法的重载。 要注意到重载的方法参数必须有所区别: ①参数的类型不同。 ②参数的顺序不同。这里是指一个方法有多个不同类型参数的情况,改变参数的顺序,也算是一种区分方法。 ③参数的个数不同。如例子中的三个重载的方法参数的个数分别是一个、两个和三个。
26
4.4.4 方法重载(overloading)(续)
例4-4 方法的重载 Time3.java文件的部分代码: …… //三个重载的setTime方法 public void setTime(int h){ setTime(h,0,0); } public void setTime(int h,int m){ setTime(h,m,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 ); 带有一个参数的setTime方法 带有两个参数的setTime方法 带有三个参数的setTime方法
27
4.5 初始化类的对象:构造函数 构造方法用于为类的新建的对象分配内存空间和进行初始化,如例4-1在Time1类中创建了一个构造函数(不带任何参数)。在构造函数中对三个成员变量进行了初始化。构造函数只能在创建对象时用new命令调用。定义必须构造函数时,注意两点: ①构造方法必须与其类名相同; ②构造方法没有返回值,但可以有参数,并且可以重载。
28
4.5 初始化类的对象:构造函数(续) 不带参数的构造函数 带一个参数的构造函数 带两个参数的构造函数 带三个参数的构造函数
例4-5举例说明构造函数的重载。 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 ); 不带参数的构造函数 带一个参数的构造函数 带两个参数的构造函数 带三个参数的构造函数 带一个参数为对象的构造函数
29
4.6 this this定义为被调用的方法的当前对象的引用。this引用仅能出现在类中的方法中。 例4-6 this的使用
例子中SimpleTime类的构造方法的三个参数名与SimpleTime类三个成员变量名相同。在这种情况下,局部变量在该方法作用域中屏蔽了同名的域。我们可以使用this来显式地引用屏蔽的域。通过this不但可以引用成员变量,也可通过this引用方法,包括构造函数。本例子中通过this引用方法。
30
4.7 垃圾收集 Java平台允许创建任意个对象(当然会受到系统资源的限制),而且当对象不再使用时自动会被清除,这个过程就是所谓的“垃圾收集”。当对象不再被引用的时候,对象就会被作为垃圾收集的对象而清除。为了使对象不再被引用,可以通过设置执行指向某一对象的引用为null。例如: Time1 time=new Time1(); Time=null; 1.垃圾收集器 2.撤销方法finalize
31
4.8 static方法和域 当声明一个成员变量时,可以指定成员变量是属于一个类的所有对象共享static (称为类的变量),还是属于一个类的各个对象所拥有( 称为实例变量,是类的实例拥有)。类的变量又称为静态成员,以关键字static声明。 例如: static int count; 类的静态成员的使用格式一般为: 类名.静态变量名; 类名.静态方法名(); 例4-7 静态方法和域的应用
32
4.9 类的组合 一个类中的成员可以是其他类的引用,这叫类的组合。 例4-8 类的组合
33
4.10 包的创建和访问 包的创建 包的使用
34
包的创建 建立一个包时,使用package语句。package语句必须是整个java文件的第一个语句。创建package语句格式: package 包名; 例如: 将在当前目录下创建一个包,包名为cn.edu.sytu.it.ch04,Time1放在此包中。 package cn.edu.sytu.it.ch04; public class Time1 {┅} ┅
35
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; 例4-9 包的创建及使用
36
小结 本章介绍了面向对象程序设计的重要概念——类和对象。类是一种抽象的数据类型,用来表示具有相同性质的一类事物。类封装了对象的属性和方法。类的实例化产生了对象。 一个类的成员包括域、方法和构造函数。 方法和构造函数都可以进行重载。 为了使一个类的所有对象共享同一个变量的值,可以将成员变量定义成静态static的。 在定义类时可以通过访问控制符来限定其它类对该类及类的成员的访问。 类和类之间的访问也可通过包来进行控制。
37
[作业] 书上本章习题中: 1. 2. 3. 4. 6. 9. 10. 11.
Similar presentations