JAVA面向对象程序设计实验指导书
(三) 编写显示当前日期和时间的程序 1.编写Applet 类文件LX3_3.java
(1)程序功能:该程序通过使用一个自定义类Time,实现显示当前日期和时间的功能,程序运行结果应与图3.3 类似。
图3.3
(四) 使用修饰符
有时需要公开一些变量和方法,有时需要禁止其他对象使用变量和方法,这时可以使用修饰符来
实现这个目的。 常用的修饰符如下。
[public] [private] [protected] [package] [static] [final] [transient] [volatile] 不同修饰符的访问控制权限如表3.1 所示。 表3.1 修饰符 public private protected package 类 √ √ √ √ 子类 √ √ 包 √ √ √ 所有类和包 √
1.程序功能:通过两个类StaticDemo、LX3_4说明静态变量/方法与实例变量/方法的区别。 2.编写类文件LX3_4.java,程序源代码如下。 class StaticDemo {
static int x; int y; public static int getX() { return x; }
public static void setX(int newX) { x = newX; }
public int getY() { return y; }
public void setY(int newY) { y = newY; } }
public class LX3_4 {
- 12 -
JAVA面向对象程序设计实验指导书 public static void main(String[] args) {
System.out.println(\静态变量x=\
System.out.println(\实例变量y=\非法,编译时将出错 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=\System.out.println(\实例变量a.y=\System.out.println(\静态变量b.x=\System.out.println(\实例变量b.y=\} }
3.对上面的源程序进行编译,会出现如图3.4 所示的出错提示。
图3.4
4.将源程序中的出错语句删除或使用解释符//隐藏起来,例如, //System.out.println(\实例变量y=\
5.重新编译并运行该程序,结果如图3.5 所示。
图3.5
static 声明的成员变量/方法被视为类的成员变量/方法,而不把它当作实例对象的成员变量/方法。换句话说,静态变量/方法是类固有的,可以直接引用,其它成员变量/方法仅仅被声明,生成实例对象后才存在,才可以被引用。基于这样的事实,也把静态变量/方法称为类变量/方法,非静态变量称为实例变量/方法。
从实验结果可以得出以下几点结论:
·类的静态变量可以直接引用,而非静态变量则不行。类的静态变量相当于某些程序语言的全局变量。
·静态方法只能使用静态变量,不能使用实例变量。因为对象实例化之前,实例变量不可用。 ·类的静态变量只有一个版本,所有实例对象引用的都是同一个版本。 ·对象实例化后,每个实例变量都被制作了一个副本,它们之间互不影响。
(五) 方法中参数传递的练习
在其它语言中,函数调用或过程调用时参数有传值调用和传地址调用之分。在Java中,方法中的参数传递可以分为传值调用或对象方法调用等方式。传值调用即传递的参数是基本数据类型,调用方法时在方法中将不能改变参数的值,这意味着只能使用它们。对象调用是指先调用对象,再调
- 13 -
JAVA面向对象程序设计实验指导书
用对象的方法,这种方式可以修改允许存取的成员变量。所以,如果不想改变参数的值,可以采用传值调用的方法。如果想改变参数的值,可采用对象调用的方法,间接修改参数的值。
1.编写一个传值调用的程序文件LX3_5.java。
(1) 程序功能:程序首先给整型变量x和y 赋一个初值10, 然后使用传值调用方式调用方法ff1 对x和y 做乘方及输出x和y 的乘方值,最后再输出x和y 的乘方值。
思考:方法的参数传递有哪些方式?区别时什么? (六) 类的继承性练习
1. 进一步理解继承的含义 新类可从现有的类中产生,并保留现有类的成员变量和方法并可根据需要对它们加以修改。新类还可添加新的变量和方法。这种现象就称为类的继承。
当建立一个新类时,不必写出全部成员变量和成员方法。只要简单地声明这个类是从一个已定义的类继承下来的,就可以引用被继承类的全部成员。被继承的类称为父类或超类(superclass),这个新类称为子类。
Java 提供了一个庞大的类库让开发人员继承和使用。设计这些类是出于公用的目的,因此,很少有某个类恰恰满足你的需要。你必须设计自己的能处理实际问题的类,如果你设计的这个类仅仅实现了继承,则和父类毫无两样。所以,通常要对子类进行扩展,即添加新的属性和方法。这使得子类要比父类大,但更具特殊性,代表着一组更具体的对象。继承的意义就在于此。
2. 创建公共类LX3_7_P 3.创建继承的类
(1) 程序功能:通过LX3_7_P 类产生子类LX3_8, 其不仅具有父类的成员变量xm (姓名)、xh( 学号),还定义了新成员变量xy(学院)、xi(系)。在程序中调用了父类的print 方法,同时可以看出子类也具有该方法。
4.了解成员变量的隐藏方式
所谓隐藏是指子类重新定义了父类中的同名变量,在子类Line 中重新定义了x 为x1,y 为y1, 隐藏了父类Point 中的两个成员变量x 和y。子类执行自己的方法时,操作的是子类的变量,子类执行父类的方法时,操作的是父类的变量。在子类中要特别注意成员变量的命名,防止无意中隐藏了父类的关键成员变量,这有可能给程序带来麻烦。
5.了解成员方法的覆盖方式
通过继承子类可以继承父类中所有可以被子类访问的成员方法,但如果子类的方法与父类方法同名,则不能继承,此时称子类的方法覆盖了父类的方法,简称为方法覆盖(override)。方法覆盖为子类提供了修改父类成员方法的能力。例如,子类可以修改层层继承下来的Object 根类的toString 方法,让它输出一些更有用的信息。下面的程序显示了在子类Circle 中添加toString 方法,用来返回圆半径和圆面积信息。
6.This、super和super()的使用 说明this、super和super()的用法。程序首先定义Point(点)类,然后创建点的子类Line(线)。最后通过LX3_10 类输出线段的长度。
程序中通过super(a,b)调用父类Point 的构造方法为父类的x和y 赋值。在子类Line 的setLine 方法中,因为参数名和成员变量名相同,为给成员变量赋值,使用this 引用,告诉编译器是为当前类的成员变量赋值。在length 和toString 方法中使用父类成员变量时,使用super 引用,告诉编译器使用的是父类的成员变量。
(七) 类的多态性练习
1. 理解类的多态性 类的继承发生在多个类之间,而类的多态只发生在同一个类上。在一个类中,可以定义多个同名的方法,只要确定它们的参数个数和类型不同。这种现象称为类的多态。 多态使程序简洁,为程序员带来很大便利。在OOP 中,当程序要实现多个相近的功能时,就给相应的方法起一个共同的名字,用不同的参数代表不同的功能。这样,在使用方法时不论传递什么参数,
只要能被程序识别就可以得到确定的结果。 类的多态性体现在方法的重载(overload)上,包括成员方法和构造方法的重载。
2. 方法的重载 :方法的重载是指对同名方法的不同使用方式。
- 14 -
JAVA面向对象程序设计实验指导书 3.构造方法的重载 构造方法的名称和类同名,没有返回类型。尽管构造方法看起来和一般的成员方法没有差别,但它不是方法,也不是类的成员。因此,构造方法不能直接调用,只能由new操作符调用。 构造方法对于类是十分重要的,对象的初始化任务要靠构造方法来完成。
重载构造方法的目的是提供多种初始化对象的能力,使程序员可以根据实际需要选用合适的构造方法来初始化对象。
(1) 编写构造方法RunDemo 的重载程序文件LX3_12,源代码如下。 class RunDemo {
private String userName, password; RunDemo() {
System.out.println(\全部为空!\}
RunDemo(String name) { userName=name;
}
RunDemo(String name, String pwd) {
this(name); password=pwd; check(); }
void check() { String s=null;
if (userName!=null)
s=\用户名:\用户名不能为空!\if (password!=\口令无效!\
else s=s+\口令:********\public class LX3_12 {
public static void main(String[] args) { new RunDemo(); new RunDemo(\new RunDemo(null,\
new RunDemo(\} }
(2)编译并运行程序,分析运行结果。
(3)三个构造方法,其中 第一个无参构造方法RunDemo() 的实际作用是对成员变量赋缺省初值,由于userName 和password
都是String 类,所以它们的缺省初值为null。 第二个构造方法RunDemo(String) 只有一个参数,用来对成员变量userName 赋初值。 第三个构造方法RunDemo(String, String) 有两个参数,并有更多的内容,首先调用this(name),
其实际作用就是调用当前类的构造方法RunDemo(String nam e);然后对成员变量password 赋值;最后调用check 方法来检查userName 和password,类似于一般程序的口令验证。 重载构造方法的执行由对象根据实际参数的个数、类型和顺序确定。
(八) 了解并使用Java 的系统包 1. API 包、接口、异常处理的作用
包是类和接口的集合。利用包可以把常用的类或功能相似的类放在一个包中。Java 语言提供系统包,其中包含了大量的类,可以在编写Java 程序时直接引用它们。为便于管理和使用它们,将这些类分为了不同的包。包又称类库或API 包,所谓API(Application Program I nterface)即应用程序接口。API包—方面提供丰富的类与方法供大家使用,如画图形、播放声音等,另一方面又负责和系统软硬件打交道,圆满实现用户程序的功能。所有Java API 包都以“java.”开头,以区别用户创
- 15 -
JAVA面向对象程序设计实验指导书
建的包。
接口解决了Java 不支持多重继承的问题,可以通过实现多个接口达到与多重继承相同的功能。 处理程序运行时的错误和设计程序同样重要,只有能够完善处理运行时出错的程序,软件系统才能长期稳定地运行,异常处理就是说明如何处理程序运行时出错的问题。
2.上网浏览Java API文档 在地址http://222.207.36.27/se/java/docs/api/index.html上,可以看到Java系统提供的Java API 文档,类文档的内容主要是:类层次、类及用途描述、成员变量列表、构造方法列表、成员方法列表、从类层次上继承的方法列表、成员变量的详细说明、构造方法详细说明、成员方法详细说
明。在这里可以看到Java 提供的Java API 文档的最新内容。如图4.1 所示。
图3.1 在右上方选择Class 标题,并在左下角框中移动滑块,选择object 类,可以看到object 类的所有方法和构造方法。如图4.2 所示。
(九) 使用接口技术 1.接口的定义与作用
接口可以看作是没有实现的方法和常量的集合。接口与抽象类相似,接口中的方法只是做了声明,而没有定义任何具体的操作方法。使用接口是为了解决Java 语言中不支持多重继承的问题。单继承可使语言本身结构简单,层次清楚,易于管理,安全可靠,避免冲突。但同时限制了语言的功能。为了在实际应用中实现多重继承的功能,Java 使用了接口技术,一个类可以实现多个接口以达到使用公用常量和一些常用的方法。
2.实现MouseListener 和MouseMotionListener 两个接口 (1)编写实现接口的程序文件LX4_3.java,源代码如下。 import java.applet.Applet; import java.awt.*;
import java.awt.event.*;
public class LX4_3 extends Applet implements MouseListener, MouseMotionListener {
int x1, y1, x2, y2;
- 16 -