实验四 类的高级特性
一、实验目的
通过实验验证类的高级特性的相关语法,掌握类的静态属性、静态方法,包,掌握抽象类和接口的定义和实现方法。
二、实验要求
1. 了解Java 系统包的结构。 2. 掌握创建自定义包的方法。 4 掌握抽象类的定义和使用方法。
3. 掌握使用系统接口的技术和创建自定义接口的方法。
三、实验设备
计算机、JCreator 、JDK
四、实验内容 Ⅰ基本指导
(-)静态方法和静态变量
static 声明的成员变量、方法称为静态方法和静态成员,静态方法和静态成员被视为类的成员变量、类的成员方法,而不把它当作实例对象的成员变量和方法。换句话说,静态变量、静态方法是类固有的,可以直接引用,其它成员变量、成员方法仅仅被声明,生成实例对象后才存在,才可以被引用。基于这样的事实,也把静态变量、静态方法称为类变量、方法,非静态变量称为实例变量、实例方法。
下面给出类StaticDemo和对应测试类StaticDemoTest,分别存放在文件StaticDemo.java和StaticDemoTest.java中,仔细阅读程序,观察程序的运行结果,理解static方法和变量的使用方法。
1.类StaticDemo
//该程序验证静态方法和静态变量的特点 //StaticDemo.java文件 public class StaticDemo {
private static int x; //静态变量 private 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; } }
阅读该程序,总结下列问题:
1)如何定义一个静态的方法和静态的常量,我们使用的关键字是什么?与实例常量和方法的定义有何区别?
2.输入StaticDemo类的测试类文件StaticDemoTest.java,仔细阅读程序,观察运行结果,体会静态方法和静态变量的用法和特征。
//StaticDemoTest.java
public class StaticDemoTest {
public static void main(String[] args) {
//注意静态方法getX()访问的方式:类名.方法名();
System.out.println(\静态变量x=\StaticDemo.getX());
//访问实例方法
// System.out.println(\实例变量y=\非法,编译时将出错
StaticDemo a= new StaticDemo(); StaticDemo b= new StaticDemo();
//再次访问静态方法,通过对象名.方法名(); a.setX(1);
System.out.println(\后,a和b对x的取值是:\ System.out.println(\静态变量a.x=\ System.out.println(\静态变量b.x=\
b.setX(3);
System.out.println(\后,a和b对x的取值是:\ System.out.println(\静态变量a.x=\ System.out.println(\静态变量b.x=\
a.setY(2); //访问实例方法 b.setY(4);
//输出对象a、b 的属性:x,y的值
System.out.println(\的最后的值为”);
System.out.println(\静态变量a.x=\System.out.println(\实例变量a.y=\ System.out.println(\静态变量b.x=\ System.out.println(\实例变量b.y=\} }
阅读并运行类StaticDemoTest,思考下列问题:
1)对于类StaticDemo中定义的静态方法getX();我们分别使用了类名.静态方法名()和对象名. 静态方法名()两种方式进行调用,编译该类,查看是否有错误,如果没有错误则说明两种方式都可以调用静态方法。
2)在程序中我们将“System.out.println(\实例变量y=\”进行了注释,删去注释符号,重新编译该类,观察是否有编译错误,如果有说明什么问题?(提示:我们通过类名.实例方法名()调用了实例方法)。
3) 删去“System.out.println(\实例变量y=\”或者为此语句添加注释,重新编译运行此类,仔细查看输出结果,对象a的x、y的值是多少?对象b的x、y的值是多少?a、b两个对象的静态变量x的值一直保持相同,而y是分别不同的,这表示静态变量是所有对象共享的,而实例变量是各个对象自有的。
4)将类StaticDemo中的Static方法:setX,按照下列语句进行修改:
public static void setX(int newX) {//静态方法 x = newX + y; }
重新保存并编译类StaticDemo,有没有编译错误,如果有,说明其无法访问类的实例变量y,但是可以访问静态变量x;这表示什么含义?
5)撤销对类StaticDemo中的Static方法setX的修改,修改方法setY。
public void setY(int newY) {//实例方法 y = newY+x; }
重新保存并编译类StaticDemo,有没有编译错误,如果有,说明实例方法setY无法访问类的静态变量x,如果没有,表示其可以访问类的静态变量。
Static小结:
·类的静态变量可以直接引用,而非静态变量则不行。类的静态变量相当于某些程序语言的全局变量。 ·静态方法只能使用静态变量,不能使用实例变量。因为对象实例化之前,实例变量不可用。 ·类的静态变量只有一个版本,所有实例对象引用的都是同一个版本。 ·对象实例化后,每个实例变量都被制作了一个副本,它们之间互不影响。 ·静态变量只被初始化一次。
(二)掌握接口技术
Java不支持多继承性,即一个类只有一个直接父类。为了克服单继承性的缺点,Java使用了接口,一个类可以实现多个接口。Java中的接口是一系列方法的声明,是一些方法特征的集合,一个接口只有方法的特征没有方法的实现,因此这些方法可以在不同的地方被不同的类实现,而这些实现可以具有不
同的行为。Java 接口的方法只能是抽象的和公开的,Java接口不能有构造函数,Java接口可以有public,静态的和final变量。
1.建立文件Student.java,观察并运行下列程序,了解并总结接口的用法。 //定义接口student public interface Student {
public abstract void sleep(); //学生睡觉 public abstract void read();//读书 public abstract void write(); //写 }
保存并编译该类,观察是否有问题。 思考:
1) 总结如何定义一个接口?
2) 查看接口中的方法的声明方式,接口中的方法都是抽象方法,没有方法实现
2.建立文件PhysicsStudent.java,描述物理系学生,其实现接口Student,程序代码如下所示。 public class PhysicsStudent implements Student {
public void sleep() {//实现接口中的抽象方法sleep
// TODO: 在这添加你的代码 System.out.println(\}
public void read() {//实现接口中的抽象方法read
// TODO: 在这添加你的代码
System.out.println(\我正在读物理力学\ }
public void write() {//实现接口中的抽象方法write
// TODO: 在这添加你的代码
System.out.println(\我正在写物理论文\} }
保存并编译该文件,并为该文件建立测试类文件InterfaceTest.java,源代码如下所示:
public class InterfaceTest {
public static void main(String []args){
PhysicsStudent tom = new PhysicsStudent(); tom.read();//调用类中实现的read方法 tom.write(); tom.sleep(); }
}
对测试类文件InterfaceTest.java,保存并编译,运行该类观察输出结果,并完成下列思考。 1) 如何实现一个接口?
2) 若某个类要实现一个接口,需要在类中完成那些工作? 3) 运行PhysicsStudent类的对象tom.write(),其完成什么工作。
(三)创建自己的包
1.自定义包的声明方式:
package 自定义包名
声明包语句必须添加在源程序的第一行,表示该程序文件声明的全部类都属于这个包。
2.根据下列代码,分别在两个不同的目录创建源程序文件Girl.java和PackageTest.java,观察并运行程序,理解包的用法。
//Girl.java package edu.lytu.yxl;// //打包 class Parents{ int father; int mother; }
class Son { int son1; }
public class Girl { int girl1; }
//PackageTest.java
import edu.lytu.yxl.Girl; public class PackageTest{
public static void main(String[] args){ Girl mygirl=new Girl(); //Son mySon=new Son(); } }
保存并编译两个源文件,思考下列问题:(注意产生的class文件的位置)
1) 程序编译有错误么?如果有错误,为什么出现错误?(需要设置classpath)
2)对jcreator进行设置,菜单配置-选项-jdk配置文件,选中右边的jdk版本菜单,点击编辑,在弹出窗口中点击添加-添加路径,把你的girl.java所在的路径添加进去。分别编译两个文件。
3)PackageTest.java中son那行的注释去掉,编译有错误吗?为什么?
恢复son那行的注释将两个文件放在同一文件夹下,编译看有错误吗?
1)如果注释掉PackageTest.java中的第一行,重新保存编译两个文件,还会出现编译错误么?为什