第4章 面向对象编程 主要任务: 理解面向对象编程的基本概念 了解类的封装方法 如何创建类和对象 了解成员变量和成员方法的特性

Slides:



Advertisements
Similar presentations
网络应用程序设计 2014 JavaBean. JavaBean 及其属性 JavaBean 就是一种 Java 的组件技术 JavaBean 是 Java 类 JavaBean 通过约定的方法名实现属性功能 简单属性 void setXxx(Type value) Type getXxx() boolean.
Advertisements

7.1 内置对象概述及分类 JSP 视频教学课程. JSP2.2 目录 1. 内置对象简介 1. 内置对象简介 2. 内置对象分类 2. 内置对象分类 3. 内置对象按功能区分 3. 内置对象按功能区分 4. 内置对象作用范围 4. 内置对象作用范围.
面向侧面的程序设计 方林博士 本文下载地址:
第3章 使用类和对象编程 软 件 学 院 朱士明 副教授.
项目三 Java面向对象程序设计 任务一 了解面向对象程序设计的基本概念 任务二 掌握类的使用方法 任务三 熟悉对象的创建与使用方法
第4章 Java中的几个关键字 Java 语言编程技术.
西南科技大学网络教育系列课程 高级语程序设计(Java) 第四章 类与对象.
第3章 面向对象的编程技术.
第四章 类 和 对 象.
第四章 对象与类 掌握面向对象程序设计语言的特点 理解对象、类,类和对象的关系 掌握类,成员变量,方法的定义 掌握构造方法的定义
3.2 Java的类 Java 类库的概念 语言规则——程序的书写规范 Java语言 类库——已有的有特定功能的Java程序模块
配合< Java面向对象程序设计>例子源代码一起使用
JAVA 编 程 技 术 主编 贾振华 2010年1月.
Java的面向对象程序设计.
Java程序设计教程 第一讲 Java概述.
Oracle数据库 Oracle 子程序.
第二章 JAVA语言基础.
第二部分 Java语言基础篇 第4章 Java语言与面向对象 (之一).
第五章 Java面向对象编程基础 类:现实世界中实体的抽象集合。 5.1定义类 定义类的过程就是定义类的属性和服务的过程;
第14章 c++中的代码重用.
全国计算机等级考试 二级基础知识 第二章 程序设计基础.
类与对象 Java 实用技术4 类与对象
第10讲 Java面向对象编程基础(4) 教学目标 主要内容.
第六章 JAVA语言中的面向对象特性 6.1 类 6.2 对象 6.3 面向对象的特性 6.4 抽象类、接口和Inner Class.
第四章 Java面向对象程序设计.
3.3 Java的非访问控制符 Java的非访问控制符 static 静态修饰符 修饰属性和方法 abstract 抽象修饰符 修饰类和方法
第5章 Java中类、对象、接口 及包的概念 5.1 类的基本概念 5.2 类的继承概念 5.3 抽象类和接口 5.4 包.
JAVA 面向对象基础知识 主要内容: 1.面向对象基本概念 2.Java的类与对象 3.成员变量与封装 成员方法.
EBNF与操作语义 请用扩展的 BNF 描述 javascript语言里语句的结构;并用操作语义的方法描述对应的语义规则
第5章 面向对象程序设计 本章要点 5.1 面向对象程序设计概述 5.2 Java语言的面向对象程序设计 5.3 方法的使用和对象数组
2018/11/15 面向对象与多线程综合实验-GUI设计 教师:段鹏飞.
Java Applet 介绍.
EBNF 请用扩展的 BNF 描述 C语言里语句的结构; 请用扩展的 BNF 描述 C++语言里类声明的结构;
Java习题解析.
走进编程 程序的顺序结构(二).
辅导课程六.
第一单元 初识C程序与C程序开发平台搭建 ---观其大略
第二章 Java语言基础.
用event class 从input的root文件中,由DmpDataBuffer::ReadObject读取数据的问题
宁波市高校慕课联盟课程 与 进行交互 Linux 系统管理.
宁波市高校慕课联盟课程 与 进行交互 Linux 系统管理.
C++语言程序设计 C++语言程序设计 第七章 类与对象 第十一组 C++语言程序设计.
C语言程序设计 主讲教师:陆幼利.
EBNF与操作语义 请用扩展的 BNF 描述 javascript语言里语句的结构;并用操作语义的方法描述对应的语义规则
简单介绍 用C++实现简单的模板数据结构 ArrayList(数组, 类似std::vector)
$9 泛型基础.
C++复习3 ----类的继承与派生.
C#面向对象程序设计 $6 深入理解类.
本节内容 类成员的访问控制 视频提供:昆山爱达人信息技术有限公司 官网地址: 联系QQ: QQ交流群 : 联系电话:
第二章 Java语法基础.
iSIGHT 基本培训 使用 Excel的栅栏问题
本节内容 结构体 视频提供:昆山爱达人信息技术有限公司 官网地址: 联系QQ: QQ交流群 : 联系电话:
Chapter 18 使用GRASP的对象设计示例.
多层循环 Private Sub Command1_Click() Dim i As Integer, j As Integer
C++语言程序设计 C++语言程序设计 第八章 继承 C++语言程序设计.
辅导课程十五.
第二章 Java基本语法 讲师:复凡.
第7章 模板 陈哲 副教授 南京航空航天大学 计算机科学与技术学院.
本节内容 C语言的汇编表示 视频提供:昆山爱达人信息技术有限公司 官网地址: 联系QQ: QQ交流群 : 联系电话:
C++语言程序设计 C++语言程序设计 第一章 C++语言概述 第十一组 C++语言程序设计.
本节内容 动态链接库 视频提供:昆山爱达人信息技术有限公司 官网地址: 联系QQ: QQ交流群 : 联系电话:
C++语言程序设计 C++语言程序设计 第九章 类的特殊成员 第十一组 C++语言程序设计.
C++语言程序设计 C++语言程序设计 第九章 类的特殊成员 第十一组 C++语言程序设计.
第2章 Java语言基础.
第8章 创建与使用图块 将一个或多个单一的实体对象整合为一个对象,这个对象就是图块。图块中的各实体可以具有各自的图层、线性、颜色等特征。在应用时,图块作为一个独立的、完整的对象进行操作,可以根据需要按一定比例和角度将图块插入到需要的位置。 2019/6/30.
创建、启动和关闭Activity 本讲大纲: 1、创建Activity 2、配置Activity 3、启动和关闭Activity
使用Fragment 本讲大纲: 1、创建Fragment 2、在Activity中添加Fragment
C++语言程序设计 C++语言程序设计 第九章 类的特殊成员 第十一组 C++语言程序设计.
事件处理 例: import java.applet.Applet; import java.awt.*;
Summary
Presentation transcript:

第4章 面向对象编程 主要任务: 理解面向对象编程的基本概念 了解类的封装方法 如何创建类和对象 了解成员变量和成员方法的特性 第4章 面向对象编程 主要任务: 理解面向对象编程的基本概念 了解类的封装方法 如何创建类和对象 了解成员变量和成员方法的特性 学习使用OOP方式进行程序设计

本章主要内容 1.面向对象基本概念 2.Java的类与对象 3.成员变量与封装 4.成员方法

4.1 面向对象基本概念 Java是完全面向对象编程语言。面向对象编程(OOP)是一种全新的编程理念,如果从来没有过OOP编程经验,你需要从基本概念开始。 什么是对象?类又是什么?它们之间有什么关系?对象是如何通过消息和外部通讯的? 下面的内容就讨论这些问题。

4.1.1 对象 在开发软件的信息世界中,对象定义为相关数据和方法的集合。 4.1.1 对象 在开发软件的信息世界中,对象定义为相关数据和方法的集合。 对象是现实世界对象的抽象模型。从现实世界对象中抽象出来的对象使用数据和方法描述其现实世界中的状态和行为特征,一般通过变量描述其状态,通过方法实现其行为。 变量是一种有名称的数据实体,而方法则是和对象相关的函数或过程。

4.1.2 封装 封装的含义是把类设计成一个黑箱,使用者只能看见类中定义的公共方法,而看不到方法实现的细节,也不能直接对类的数据进行操作,迫使用户通过接口去访问数据,这种封装正是OOP设计者追求的理想境界。 相关数据和方法封装到一个包里,为程序员带来了两个好处:模块化和数据隐藏。

4.1.3 消息 对象的行为由方法来实现,消息传递是对象之间进行交互的主要方式。 构成消息的三个要素是: ☆接收消息的对象 4.1.3 消息 对象的行为由方法来实现,消息传递是对象之间进行交互的主要方式。 构成消息的三个要素是: ☆接收消息的对象 ☆接收消息后进行处理的方法 ☆方法所需要的参数

4.1.4 类 类就是对象的软件图纸、模板或原型,它定义了同类对象共有的变量和方法。 4.1.4 类 类就是对象的软件图纸、模板或原型,它定义了同类对象共有的变量和方法。 类和对象二者不太容易区分。一方面,由于软件对象都是现实对象或抽象概念的电子模型,另一方面,经常不加区分地将对象和类统称为“对象”。 Java编程就是设计类,可以采用自定义方法或继承方法设计一个类,然后使用它的实例对象完成具体的功能。

4.1.5 继承 继承(inheritance)不但可以发生在同一个层次上,也可以发生在不同层次上。所有层次的类都是从Object类那里直接或间接地衍生下来的。Object仅提供了所有的类在Java虚拟机上运行时所需要的基本状态和方法。一般来说,层次越高,类就越抽象,反之类就越具体。 继承使父类的代码得到重用,在继承父类提供的共同特性基础上添加新的代码,使编程不必一切都从头开始,有效提高了编程效率。

4.1.6 接口 接口(interface)可以看成是为两个不相关的实体提供交流途径的设备,例如语言就是两个人进行交流的接口。在Java中,接口就是为两个不相关的类提供交流的设备。接口非常类似于协议(protocol一种共同行为的约定),是一个包含方法定义和常量值的集合。 接口不需要建立继承关系,就可以使两个不相关的类进行交互。接口提取了类的某些共同点,声明一些能被多个类实现的方法,但不给出方法体。接口由类的声明语句中的implements关键字引入,并在类体中实现接口的方法。

例4.1 设计一个Applet小程序,使其可以进行简单的加法运算。 // 源程序名:Addition.java import java.awt.*; import java.awt.event.*; import java.applet.Applet;

public class Addition extends Applet implements ActionListener { Label label1=new Label("+"); Label label2=new Label("="); TextField field1=new TextField(6); TextField field2=new TextField(6); TextField field3=new TextField(6); Button button1=new Button("相加");

public void init() { // 初始化 add(field1); add(label1); add(field2); add(label2); add(field3); add(button1); button1.addActionListener(this); }

public void actionPerformed(ActionEvent e) { // 处理按钮事件 int x=Integer.parseInt(field1.getText())+Integer.parseInt(field2.getText()); field3.setText(Integer.toString(x)); // 数值转换为字符串 }

现在让我们使用面向对象的思想来分析一下Addition.java源程序的结构 : 前面3行是说明语句,分别引入Java系统包awt和applet语句。 语句import java.applet.Applet引入了applet中的Applet类, 语句import java.awt.* 引入了awt包中的所有类, 语句import java.awt.event.* 引入了awt的event包的所有类。

第4行开始是程序的主体,声明了Addition类,它继承自Applet类。继承不是目的而是一种手段,作为Applet的一个子类,具有Applet的共性。继承的状态和方法往往不足以实现程序的要求,必须根据题目的具体要求,由用户添加各种对象和方法,改造成满足题目要求的程序。Java编程就是基于这样的思想。 第4行是类声明语句public class Addition extends Applet implements ActionListener 说明Addition是继承自Applet的公共子类,并建立了一个单击事件监听器ActionListener接口,在程序运行时可监听发生了什么事件,并负责调用相应的事件处理方法作出响应。这个框架出来后,剩下的任务就是设计成员变量和成员方法了。

第5到10行声明了Addition类的6个对象数据。两个标签对象用于显示运算符号;三个文本域对象用于接受用户的输入;一个按钮对象用于执行加法运算。 第11行到19行是Addition类包含方法init的声明和实现语句。 类中所有的对象行为都由这个类来控制,这种控制是通过改造继承下来的init方法实现的。类所包含的方法相当于传统编程语言的过程或函数,可完成一定的功能。 init是一个不需要返回值的方法,init方法属于Applet,Addition对它进行了修改,由它实现将上面添加的各个对象加入到Addition的显示区,并给按钮对象注册事件监听器(Addition)。 第20行到23行是actionPerformed事件处理方法的声明和实现语句

4.2 Java的类与对象 Java程序的所有数据类型都是用类来实现的,Java语言是建立在类这个逻辑结构之上,所以Java是一种完全面向对象的程序设计语言。 类是Java的核心,Java程序都由类组成,一个程序至少要包含一个类,也可以包含多个类。对象是类的实例,Java程序中可以使用标识符表示对象,并通过对象引用类中的变量和方法。

4.2.1 类的创建 类通过关键字class来创建,下面的声明语句格式给出了可能出现的符号和顺序: 4.2.1 类的创建 类通过关键字class来创建,下面的声明语句格式给出了可能出现的符号和顺序: [public] [abstract] [final] <class> <类名> [extends 父类] [implements 接口] { <类体(成员变量和成员方法)> } 其中,[]表示为可选项,<>表示为必选项。关键字含义说明如下:

1.class 类名 class关键字告诉编译器这是一个类,类名是可以自由选取但必须是合法的标识符。

2.public(公共的) 在没有任何修饰符的缺省情况下,类只能被同一个源程序文件或同一个包中的其它类使用,如例4.3中的MyBox只能被ClassDemo2使用。加上public修饰符后,类可以被任何包中的类使用,称为公共类。有关包的概念请参考后面章节的内容(目前可把包当作一个源程序文件)。

3.Abstract(抽象的) 有时,定义的类代表了一个抽象的概念,就不能用它来实例化一个对象。 同样在OOP中,可能建立了一个不需要产生对象的类。例如,java.lang包中的Number类代表了数这个抽象概念,可以用它在程序中产生一个数的子类,如Interger或Float,但从Number中直接生成对象是没有意义的。 abstract说明的类称为抽象类,不能用它实例化一个对象,它只能被继承。

4.final(最终的) final说明的类称为最终类。一个最终类不可能有子类,也就是说它不能被继承。为什么要把一个类说明为最终类呢?有两点理由:为了提高系统的安全性和出于对一个完美类的偏爱。 黑客常用的一个攻击技术是设计一个子类,然后用它替换原来的父类。子类和父类很相象,但做的事情却大不一样。为防止这样的事情发生,你可以把你的类声明为最终类,不让黑客有机可乘。

5.Extends(继承)父类名 extends告诉编译器创建的类是从父类继承下来的子类,父类必须是Java系统类或已经定义的类。 从父类继承,可以提高代码的重用性,不必从头开始设计程序。大部分情况下应该利用继承的手段编程,只在没有合适的类可以继承时才自己设计类。

6.Implements(实现)接口名 implements告诉编译器类实现的接口,接口必须有定义,一般为系统类。

例4.2 下面这个Applet程序将在页面上输出两个矩形,并伴有文字输出。见图:

public void init() { import java.awt.*; import java.applet.Applet; public class Class1 extends Applet { private int x, y, width, height; public void init() { width=60; height=60; }

public void setPosition(int xPos, int yPos) { x=xPos; y=yPos; } public void paint(Graphics g) { setPosition(20,20); g.drawRect(x, y, width, height); g.drawString("矩形 1 的 X 位置: "+x, 20,100); g.drawString("矩形 1 的 Y 位置: "+y, 20,120);

setPosition(170,20); g.drawRect(x, y, width, height); g.drawString("矩形 2 的 X 位置: "+x, 170,100); g.drawString("矩形 2 的 Y 位置: "+y, 170,120); }

4.2.2 对象的创建 类是对象的产品模板。在现实世界里,我们使用的是产品而不是产品的图纸。同样道理,Java运行的应该是用类创建的实例化对象。 一个典型的Java程序会创建很多对象,它们通过消息传递进行相互交流,共同完成程序的功能。一旦任务完成,对象就会被垃圾收集器收回,完成它从创建、使用到清除的生命三步曲。 下面介绍对象的创建过程。先看一个例子。

例4.3 下面这个程序是改写后的例4.2,输出结果与图4.2一样。 import java.awt.*; import java.applet.Applet; public class Class2 extends Applet { MyBox b1=new MyBox(); MyBox b2=new MyBox(170,20,60,60);

public void paint(Graphics g) { b1.setPosition(20,20); b1.setSize(60,60); b1.draw(g); g.drawString("矩形 1 的 X 位置: "+b1.getX(), 20, 100); g.drawString("矩形 1 的 Y 位置: "+b1.getY(), 20, 120); b2.draw(g); g.drawString("矩形 2 的 X 位置: "+b2.getX(), b2.getX(), b2.getY()+80); g.drawString("矩形 2 的 Y 位置: "+b2.getY(), b2.getX(), b2.getY()+100); }

class MyBox { private int x, y, width, height; MyBox() { x=0; y=0; width=0; height=0; }

MyBox(int xPos, int yPos, int w, int h) { x=xPos; y=yPos; width=w; height=h; } public void setPosition (int xPos, int yPos) {

public void setSize (int w, int h) { width=w; height=h; } public int getX() { return x;

public int getY() { return y; } public void draw(Graphics g) { g.drawRect(x, y, width, height);

首先必须拥有一个合适的类才能创建一个合适的对象,有了合适的对象才能完成合适的工作。下面的三条语句分别创建了三个对象: 下面给出创建对象和使用对象的方法说明 1.创建对象与构造方法 首先必须拥有一个合适的类才能创建一个合适的对象,有了合适的对象才能完成合适的工作。下面的三条语句分别创建了三个对象: Lable label1=new Label("标签"); TextField field1=new TextField(10); MyBox b1=new MyBox(20,20,100,100);

创建对象语句 创建对象语句有三个组成部分:声明对象、实例化、初始化。 格式为: <类名> <对象名>=new <类名>([参数列表])

创建对象 创建对象相当于定义一个变量,既可采用上述方法,也可以把上述步骤分开进行,先声明对象,再实例化对象,进行初始化。 (1)声明对象 <类名> <对象名> 如:MyBox b2 (2)实例化和初始化 <对象名>= new <类名>([参数列表]) 如,MyBox b2=new MyBox(20,20,100,100);

2.对象初始化的说明 (1)系统如何对变量初始化 前面介绍变量是可知,变量声明后没有赋值,在使用变量时会出现错误。当用new创建了一个对象时,系统会为对象中的变量进行初始化。 (2)构造方法的作用与构成 构造方法对于类是十分重要的,new操作符为对象分配内存后将调用类的构造方法确定对象的初始状态,初始化所有变量。也就是说,对象的初始化任务要靠构造方法来完成。

例4.3中定义的两个构造方法: MyBox() { x=0; y=0; width=0; height=0; } MyBox(int xPos, int yPos, int Width, int Height) { x=xPos; y=yPos; width=Width; height=Height;

构造方法比较 第一个是缺省的构造方法MyBox(),没有任何参数,它把MyBox类的4个成员变量赋值为0。 第二个构造方法MyBox(int, int, int, int) 有4个参数,创建对象时可以传递4个参数给MyBox类赋初值。 MyBox() 和MyBox(int, int, int, int) 同为类MyBox的构造方法,方法名相同而参数不同,这是类的多态性的体现。程序可以根据参数的不同,自动调用正确的构造方法。不同的构造方法可以为程序员提供更加灵活的选择。

3.对象的使用 创建对象时,一个对象的所有变量和方法代码(包含对象的类的变量和方法)都被读到专为它开辟的内存区域中。为了让解释器知道代码的内存地址,使用对象的任何成员时都要加上引用。即在变量和方法的前面加上对象名,并用圆点分隔。格式为: <对象名>.<变量名> <对象名>.<方法名>

4.清除对象 使用new操作符创建对象后,Java虚拟机自动为该对象分配内存并保持跟踪。Java虚拟机能判断出对象是否还被引用,对不再被引用的对象释放其占用的内存。这种定期寻找不再使用的对象并自动释放对象占用内存的过程称为垃圾收集。Java虚拟机实际上是利用变量生存期来管理内存的,对象的引用被保存在变量中,当程序跳出变量所在的区域后,它就会被自动清除。

OOP的基本思想 OOP的基本思想:抽象、封装、继承等。 封装是抽象的具体实现。封装就是用操作方法把数据封闭到类中,形成以数据为核心,以方法为外壳的类。封装能保护类的数据免受外界的更改,消除了由此带来的对程序的不可知影响。封装的结果是形成了独立的和完整的程序模块,它们之间通过被授权的操作方法来传递消息,达到改变对象状态的目的,这是提高程序健壮性的有力保证。

4.3 成员变量与封装 成员变量描述了类和对象的状态,有时也称为属性、数据、域(field)。 对成员变量的操作实际上就是改变类和对象的状态,使之能满足程序的需要。与类相似,成员变量也有很多修饰符,用来控制对成员变量的访问,实现对类和对象的封装。

4.3.1成员变量的声明 例4.4 显示当前日期和时间,运行结果见图:

import java.awt.Graphics; import java.applet.Applet; import java.util.Calendar; class Time { private Calendar t; private int y, m, d, hh, mm, ss;

Time (){ t=Calendar.getInstance(); y=t.get(t.YEAR); m=t.get(t.MONTH)+1; d=t.get(t.DATE); hh=t.get(t.HOUR_OF_DAY); mm=t.get(t.MINUTE); ss=t.get(t.SECOND); }

public String getDate() { return y+" 年"+m+"月"+d+"日"; } public String getTime() { String s=hh+" 时"+mm+"分"+ss+"秒"; return s;

public class ShowTime extends Applet { Time t=new Time(); public void paint(Graphics g) { g.drawString("当前日期:"+t.getDate(),50,40); g.drawString("当前时间:"+t.getTime(),50,80); }

4.3.2 成员变量的修饰 成员变量的声明语句有如下格式: [public] [private] [protected] [package] // 访问控制修饰符 [static] [final] [transient] [volatile]<数据类型> <成员变量名称>

1.访问控制权限 (1)public 公共变量 由public修饰的变量称为公共变量,,可被任何包中的任何类访问,只有在确认任何外部访问都不会带来不良后果的情况下才将成员声明为公共的。公共变量对任何类都是可见的,因此它没有秘密可言,不具有数据保护功能。 (2)private私有变量 由private修饰的变量称为私有变量,只能被声明它的类所使用,拒绝任何外部类的访问。私有变量是不公开的,它们得到了最好的保护,这是对类进行封装时使用的主要方法。

(3)protected 受保护变量 由protected修饰的变量称为受保护变量,可被声明它的类和派生的子类以及同一个包中的类访问。 (4)package包变量 由package修饰的变量称为包变量,在声明时常常省略package关键字,即没有修饰符的成员被视为包成员。包成员可被声明它的类和同一个包中的其它类(包括派生子类)所访问,在其它包中的子类则不能访问父类的包成员。

2.static 静态变量 static声明的成员变量被视为类的成员变量,而不把它当作实例对象的成员变量。换句话说,静态变量是类固有的,可以直接引用,其它成员变量仅仅被声明,生成实例对象后才存在,才可以被引用。基于这样的事实,也把静态变量称为类变量,非静态变量称为实例变量。相应地,静态方法称为类方法,非静态方法称为实例方法。

例4.5 静态变量的使用。 class StaticDemo { static int x; int y; 例4.5 静态变量的使用。 class StaticDemo { static int x; int y; static public int getX() { return x; } static public void setX(int newX) { x = newX;

public int getY() { return y; } public void setY(int newY) { y = newY;

public class ShowDemo { public static void main(String[] args) { System.out.println("静态变量x="+StaticDemo.getX()); System.out.println("实例变量y="+StaticDemo.getY()); // 非法,编译时将出错 StaticDemo a= new StaticDemo(); StaticDemo b= new StaticDemo();

a.setX(1); a.setY(2); b.setX(3); b.setY(4); System.out.println("静态变量a.x="+a.getX()); System.out.println("实例变量a.y="+a.getY()); System.out.println("静态变量b.x="+b.getX()); System.out.println("实例变量b.y="+b.getY()); }

对上面的源程序进行编译会出现如图所示结果,不能进行运行该程序。

将源程序中的出错语句删除或使用解释符//隐藏起来如: //System.out.println(“实例变量y=”+StaticDemo.getY()); // 非法,编译时将出错,再进行编译,即可执行该程序,结果如图所示。

从输出结果中可以得出以下几点结论 : ·类的静态变量可以直接引用,例如在程序中直接使用了StaticDemo.getX(),而非静态变量则不行。类的静态变量相当于某些程序语言的全局变量。 ·静态方法只能使用静态变量,不能使用实例变量。 ·类的静态变量只有一个版本,所有实例对象引用的都是同一个版本。 ·对象实例化后,每个实例变量都被制作了一个副本,它们之间互不影响。

3.final 最终变量 一旦成员变量被声明为final,在程序运行中将不能被改变。这样的成员变量就是一个常量。例如: final double PI=3.14159; 该语句声明一个常量PI,如果在后面试图重新对它赋值,将产生编译错误。另外,常量名一般用大写字母。常量和直接量一样不占用内存空间。

4.transient 过渡变量 5.volatile 易失变量 Java语言目前对transient修饰符没有明确说明,它一般用在对象序列化(object serialization)上,说明成员变量不许被序列化。 5.volatile 易失变量 volatile声明的成员变量为易失变量,用来防止编译器对该成员进行某种优化。这是Java语言的高级特性,仅被少数程序员使用。

4.4 成员方法 对象的行为由类的方法实现,其它对象可以调用一个对象的方法,通过消息的传递实现对该对象行为的控制。 4.4 成员方法 对象的行为由类的方法实现,其它对象可以调用一个对象的方法,通过消息的传递实现对该对象行为的控制。 下面讨论如何通过方法影响对象的行为。

4.4.1 成员方法的设计 类的设计集中体现在成员方法的设计上。良好的设计可以使类更加强壮,功能更加完善。成员方法的设计应该从类的整体行为出发,能正确响应外部消息,自然地改变对象的状态,并符合相对独立性、结构清晰、可重用性强等编程要求。 来看下面的例子:

例4.6 方法对对象行为的影响,运行结果见图:

import java.awt.*; import java.applet.Applet; class DrawShape { private int x, y, shape; public void setPos(int xPos, int yPos) { x=xPos; y=yPos; }

public void setShape(int choice) { shape=choice; } public void draw(Graphics g) { if (shape ==1) g.drawRect(x, y, 60, 60); else if (shape ==2) g.drawOval(x, y, 60, 60); else g.drawString("形状参数不对!", 20, 120);

public class M1 extends Applet { final int BOX=1, OVAL=2; DrawShape a=new DrawShape(); public void paint(Graphics g) { a.setPos(40,20); a.setShape(BOX); a.draw(g); a.setPos(200,60); a.setShape(OVAL); }

4.4.2 成员方法的声明与修饰 成员方法相当于其它语言的函数或过程,是命令语句的集合。成员方法的声明一般放在成员变量的声明之后,声明语句的格式和顺序如下: [public] [private] [protected] [package] // 访问控制修饰符 [static] [final] [abstract] [native] [synchronized] 返回值类型 方法名(参数表)[throws 异常类型]

不同含义的修饰符 : 1.final 最终方法 方法被声明为最终方法后,将不能被子类覆盖,即最终方法能被子类继承和使用但不能在子类中修改或重新定义它。这种修饰可以保护一些重要的方法不被修改,尤其是那些对类的状态和行为有关键性作用的方法被保护以后,可以避免未知情况的发生。 在OOP中,子类可以把父类的方法重新定义,使之具有新功能但又和父类的方法同名、同参数、同返回值,这种情况称为方法覆盖(override)。

2.abstract 抽象方法 一个抽象类可以含有抽象方法。所谓抽象方法是指不能实现的方法,因为它没有方法体,所以抽象方法不能出现在非抽象类中。 为什么要使用抽象类和抽象方法呢?一个抽象类可以定义一个统一的编程接口,使其子类表现出共同的状态和行为,但各自的细节是不同的。子类共有的行为由抽象类中的抽象方法来约束,而子类行为的具体细节则通过抽象方法的覆盖来实现。这种机制可增加编程的灵活性,也是OOP继承树的衍生基础。

3.native 本地方法 用其它语言编写的方法在Java中称为本地方法。如果你有一个用其它语言如C++ 写成的函数,希望在Java中能利用这些资源,你可以编写本地方法。 SDK提供了Java本地接口JNI(Java Native Interface),使得Java虚拟机能运行嵌入在Java程序中的其它语言的代码。这些语言包括C/C++、Fortran、汇编语言等等。 嵌入外部语言代码出于以下几点考虑:Java系统包不提供对平台依赖性程序的支持时;想利用现有的其它语言资源时;出于运行速度的要求而使用其它语言开发的运行模块。

4.synchronized 同步方法 同步方法用于多线程编程。多线程在运行时,可能会同时存取一个数据。为避免数据的不一致性,应将方法声明为同步方法,对数据进行加锁,以保证线程的安全。详细内容请参考第8章。 5.throws 异常类型 程序在运行时可能发生异常现象。每一个异常都对应着一个异常类,如果希望方法忽略某种异常,可将其抛出,使程序得以继续运行。在前面介绍的例中就使用过抛出异常throws IOException(输入/输出异常),有关异常处理的详细内容请参考第6章。

6.返回值类型 Java要求一个方法必须声明它的返回值类型。如果方法没有返回值就用关键字void作为返回值类型,否则应使用基本数据类型或对象类型说明返回值类型,如下面的语句: public int getX(); void setXY(int x, int y); public String getName(); protected Object clone(); 其中,getX的返回值为int类型,setXY没有返回值,getName的返回值是String类。而clone的返回值则为Object类。

7.方法名 方法名可以是任何有效的Java标识符。方法名可以和成员变量同名,也可以和成员方法同名。同一个类中的方法同名现象在OOP中称为方法重载(overload),重载使一个类的多个方法享有同一个名称,可以减轻程序员的负担。 8.参数表 方法的调用者正是通过参数表将外部消息传递给方法加以处理的。在参数表中要声明参数的类型,并用逗号分隔多个参数。

4.4.3 方法体 方法体包含在一对大括号中,即使方法体中没有语句,一对大括号也是必不可少的。使用各种语句结构组成方法主体,实现程序的功能,是设计方法体的目的。下面这段程序是一个处理格式化字符串的方法: public String toString(int[] arr) { int i, n=arr.size(); StringBuffer s=new StringBuffer();

s.append("["); for (i=0; i<n; i++) { s.append (Integer.toString(arr[i])); if (i<n-1) s.append(","); } s.append("]"); return s.toString();

4.4.4 消息传递 一个对象和外部交换信息主要靠方法的参数来传递。当然,如果允许的话,外部对象也可以直接存取一个对象的成员变量。出于整体考虑,大部分还是通过参数来传递。在Java中,可传递的参数包括任何数据类型,前面已经使用了基本数据类型的参数传递、数组的传递和对象的传递。 在其它语言中,函数调用或过程调用有传值调用和传地址调用之分。

例4.7 参数传递示例1 class P1 { public static void main(String[] args) { 例4.7 参数传递示例1 class P1 { public static void main(String[] args) { int x=10, y=10; doPower(x, y); System.out.println("x="+x+", y="+y); } static void doPower(int passX, int passY) { passX=passX*passX; passY=passY*passY; System.out.println("passX="+passX+", passY="+passY);

例4.8 参数传递示例2 class P2 { public static void main(String[] args) { 例4.8 参数传递示例2 class P2 { public static void main(String[] args) { Power p=new Power(); p.doPower(10,10); System.out.println("x="+p.x+", y="+p.y); } class Power { int x, y; void doPower(int passX, int passY) { x=passX*passX; y=passY*passY;

4.4.5 Java编程小结 ·源程序的文件名和程序中定义的主类名应保持一致,包括字母大小写的匹配。 ·Java严格区分大小写,例如applet和Applet代表了不同的含义。 ·语句以分号结束。 ·程序中可加注释,用双斜杠“//”引导,“/* */”可包含多行注释。 ·注意设计一般类与主类,一般类可以有多个,主类只能有一个,源程序名与主类名相同。