项目5 面向对象的程序设计基础_第1页
项目5 面向对象的程序设计基础_第2页
项目5 面向对象的程序设计基础_第3页
项目5 面向对象的程序设计基础_第4页
项目5 面向对象的程序设计基础_第5页
已阅读5页,还剩262页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

Java程序设计案例教程

主编魏衍君

兴趣是最好的老师知识有限创意无限欢迎大家学习Java程序设计案例教程

项目5面向对象的程序设计基础5.1【任务9】设计学生类Students5.2【任务10】设计本科生类和研究生类

5.3【任务11】设计抽象类Book5.1【任务9】设计学生类Students

任务描述:

编写一个程序StudentsDemo,设计一个学生类,其属性有姓名、年龄、学位,其方法有各种属性的get和set方法,还要有相关数据的输出方法,并创建一个学生类的对象。通过该任务的学习,可以初步了解类和对象的基本概念,掌握和创建使用类生成对象的方法以及面向对象的编程思想和类的封装特性。

设计过程:

(1)在“记事本”中输入如下程序:

classStudents{//下面是Students类的成员变量和方法

publicStringname;

publicintage;

publicStringdegree;

publicStudents(Stringname1,intage1,Stringdegree1)//构造方法用于初始化类

{name=name1;age=age1;degree=degree1;this.getName();this.getAge();this.getDegree();}publicvoidsetName(Stringn){name=n;}//设置学生姓名publicvoidsetAge(inta){age=a;}//设置学生年龄

publicvoidsetDegree(Stringd){degree=d;}//设置学生的学位

publicStringgetName(){returnname;}//获取学生姓名

publicintgetAge(){returnage;}//获取学生成绩

publicStringgetDegree(){returndegree;}//获取学生学位publicvoidshow(){System.out.println("学生的姓名是:"+name);System.out.println("学生的年龄是:"+age);System.out.println("学生的学位是:"+degree+"\\n");}}publicclassStudentsDemo{publicstaticvoidmain(Stringargs[]){Studentss1=newStudents("张三",20,"大专");System.out.println("修改前张三个人信息:");s1.show();s1.setAge(28);s1.setDegree("博士");System.out.println("修改后张三个人信息:");s1.show();}}

(2)将文件保存在“D:\\myprogram”文件夹中,文件名为StudentsDemo.java。

(3)在“命令提示符”窗口内的“D:\\myprogram”提示符下,输入“javacStudentsDemo.java”命令,然后在新的命令行中,输入“javaStudentsDemo”命令,运行字节码程序,输出程序的运行结果,如图5-1-1所示。图5-1-1

程序StudentsDemo的运行结果

相关知识

5.1.1类

类是对一个或几个相似对象的描述,它把不同对象具有的共性抽象出来,定义为某类对象共有的变量和方法,从而使程序员实现代码的复用,所以说,类是同一类对象的原型。创建一个类,相当于构造一个新的数据类型,而实例化一个类就得到一个对象。Java为我们提供了大量的类库,如果从已知类库入手来构造自己的程序,不仅能有效地简化程序设计,而且能很好地学习面向对象程序设计方法。

类的声明

类声明包括关键字class﹑类名及类的属性。类名必须是合法的标识符,类的属性为一些可选的关键字。其声明格式如下:

[public|private|friendly|protected][abstract]

[final]classclassName[extendssuperclassName][implementsinterfaceNameList]

{…}

其中,第一项属于访问控制字符,它不仅针对于类,类的变量、方法的访问也有该项的限制,我们后面作专门的介绍。其他的修饰符说明如下:

abstract:声明该类不能被实例化。

final:声明该类不能被继承,即没有子类。

classclassName:关键字class告诉编译器表示类的声明以及类名是className。

extendssuperclassName:extends语句扩展superclassName为该类的父类。

implementsinterfaceNameList:声明类可实现一个或多个接口,可以使用关键字implements并且在其后面给出由类实现的多个接口名字列表,各接口之间以逗号分隔。

类的实体

实体是类的主要部分,包括变量的说明及该类所支持的方法,我们习惯称之为成员变量和成员方法。需要注意的是,除了实体中定义的变量与方法外,该类还继承了其父类的变量与方法。当然,对父类变量和方法的访问要受到访问控制条件的限制。实体说明的格式为:

classclassName{

variableDeclaration

methodDeclaration

}

1.变量

Java中变量的说明可以分为两种:类成员变量的说明和方法变量的说明。其变量声明格式为:

[public|protected|private][static][final]typevariableName

上述声明格式中,第一项指的是访问控制格式(后面介绍),另外的几项说明如下:

static:成员控制修饰符,说明该类型的变量为静态变量,或者称之为类变量。说明静态变量类型后,则该类的所有实例对象都可以对其共享,而且访问静态变量无须事先初始化它所在的类。

final:常量声明修饰符,与C/类似,用该符号声明后,在程序的运行过程中不能再改变它的值。实际使用中,final往往与static结合在一起使用。比如:

finalintINDEX=1000;

staticfinalintLOOP=10;

总之,从变量定义的不同位置及所使用的限定词来看,变量可以分为三类:实例变量、局部变量和静态变量。

(1)实例变量。如果在类的方法代码段之外声明且没有限定词static,则为实例变量。从它的定义我们可以看出,实例变量与类紧密相关,如果一个类有多个实例对象,那么每个实例对象都有自己的实例变量,之间并不影响。

(2)局部变量。如果在类的方法体之中声明,则为局部变量,这有点与C语言函数中定义的局部变量相似。由于局部变量是在方法体内所定义,因而只能在本方法中使用,无所谓访问控制,也不能用static修饰符加以说明。另外,需要注意的是,局部变量使用前必须初始化,这也是它与实例变量及后面要介绍的静态变量之间的不同之处。局部变量可以与实例变量同名而相互不影响。

(3)静态变量。如果将一个实例变量声明为static,则为静态变量,或称之为类变量。静态变量在类声明后就可以直接引用,但实例变量则不能,必须在实例化对象后才可以使用。

下面我们对实例变量与类变量加以详细说明,以加深读者的理解。比如可以如下来声明一个成员变量:

classMyClass{

publicfloatvariable1;

publicstaticintvariable2;

}

该例中声明了一个实例变量variable1和一个类变量variable2。今后当创建类的实例的时候,系统就会为该实例创建一个类实例的副本,但系统为每个类分配类变量仅仅只有一次,而不管类创建的实例有多少。当第一次调用类的时候,系统为类变量分配内存。所有的实例共享了类的类变量的相同副本。在程序中可通过一个实例或者类本身来访问类变量。例如:

MyClassA=newMyClass();

MyClassB=newMyClass();

A.variable1=100;

A.variable2=200;

B.variable1=300;

B.varable2=400;System.out.println("A.variable1="+A.variable1);System.out.println("A.variable2="+A.variable2);System.out.println("B.variable1="+B.variable1);System.out.println("B.variable2="+B.variable2);

当从类实例化新对象的时候,就得到了类实例变量的一个副本。这些副本跟新对象是联系在一起的。因此每实例化一个新MyClass对象的时候,就得到了一个和MyClass对象有联系的variable1的新副本。当一个成员变量用关键字static指定为类变量之后,其第一次调用的时候,系统就会为它创建一个副本,之后,类的所有实例均共享了该类变量的相同副本。所以上述程序段的输出结果为:

A.variable1=100

A.variable2=400

B.variable1=300

B.variable2=400

2.方法

Java程序通过方法完成对类和对象属性的操作。方法定义了在类成员变量上的一系列操作,它只能在类的内部声明并加以实现,其他的对象通过调用对象的方法得到该对象的服务。方法的定义包含了两部分内容:方法声明和方法体。

(1)方法声明。方法声明的一般格式如下:

[public|protected|private][static][final]

[abstract]

returnTypemethodName([paramList])[throwsexceptionList]

{…}

在方法声明中应包括方法名、方法的返回值类型、方法的修饰词、参数的数目和类型及方法可能产生的例外。从其声明格式中可以发现,不一定要全部显示并指明所有的信息,方法最基本的声明格式为:

returnTypemethodName()

{…}

一般声明格式中的第一项是访问控制属性,后面会有介绍。对其他几个修饰词说明如下:

static:说明该方法为静态方法。与变量的定义类似,静态方法也称作类方法,与之对应,其他的方法就称之为实例方法。静态方法属于类,所以只要对类作了声明,就可以调用该类的类方法,即使用时无须类的初始化。当然,实例方法只能在类的实例或子类的实例中调用。类方法只能操作类变量而不能访问定义在类中的实例变量,这是实际使用过程中经常出错的地方。例如:classA{intx;staticpublicintx(){returnx;}staticpublicvoidsetX(intnewX){x=newX();}}

…AmyX=newA();AanotherX=newA();myX.setX(1);anotherX.x=2;System.out.println("myX.x="+myX.x());System.out.println("anotherX.x="+anotherX.x());…

当编译的时候,编译器会给出以下的错误信息:

A.Java:4:Can’tmakeastaticreferncetononstaticvariablexinclassA.returnx;^

出现这个错误的原因是类方法不能访问实例变量。

实例成员和类成员之间不同点是类成员可以在类本身中访问,而不必实例化一个类来访问类成员。

下面再对上面的代码进行修改:

A.setX(1);System.out.println(″A.x=″+A.x());…

这里我们不用实例化类对象myX和anotherX就可以直接从类A中设置x并输出。这样同样可以得到类变量x的值。

abstract:说明一个方法是抽象方法,即该方法只有方法说明而没有方法体。抽象方法的实现须由该方法所在类的子类来实现。如果一个类包含一个或多个抽象方法,则该类必须为抽象类。抽象类不能被实例化。例如:classShape{abstractvoiddraw();}

该例中的说明方法draw()为抽象方法。

final:final方法类似于常量的定义,它说明了一个方法为终极方法,即它不能被子类重载。说明为final的方法往往与关键字private一起使用,避免出错。例如:

privatefinalmeth_final()

{…}Java

针对任何一个方法,返回类型是必需的,如果方法没有返回值,则返回类型为void。否则返回类型可以是各种数据类型,如int、float、String等。对于有返回值的方法,其方法体中至少有一条return语句,形式为:

return(表达式)

当调用该方法时,方法的返回值即为此表达式的值。

(2)方法重载。Java中方法的重载指的是多个方法共用一个名字(这样可实现对象的多态),同时,不同的方法要么参数个数不相同,要么参数类型不同。Java提供的标准类中包含了许多构造函数,并且每个构造函数允许调用者为新对象的不同实例变量提供不同的初始数值。比如,Java.awt.Rectangle就有三个构造函数:

Rectangle(){};

Rectangle(intwidth,intheight){};

Rectangle(intx,inty,intwidth,intheight){};

当传递不同的参数时,构造出来的对象的实例具有不同的属性。

(3)参数传递。在调用一个带有形式参数的方法时,必须为方法提供实际参数,完成实际参数与形式参数的结合,称为参数传递,然后用实际参数执行所调用的方法体。在Java中参数的传递是以传值的方式进行,即将实际参数的值传递给形式参数,而不是将实际参数的地址传递给形式参数。由于被调用方法没有访问实际参数,因而在改变形式参数值时,并没有改变实际参数的值。【例5-1】参数传递举例。publicclassExa1{staticvoidsum(Stringx,Stringy){Stringtemp;System.out.println(″形参改变之前″);System.out.println(″x=″+x+″″+″y=″+y);temp=x;x=y;y=temp;System.out.println(″形参改变之后″);System.out.println(″x=″+x+″″+″y=″+y);}publicstaticvoidmain(Stringargs[]){Stringa=″10″,b=″20″;System.out.println(″方法调用之前″);System.out.println(″a=″+a+″″+″b=″+b);Sum(″10″,″20″);System.out.println(″方法调用之后″);System.out.println(″a=″+a+″″+″b=″+b);}}运行结果:方法调用之前a=10b=20形参改变之前x=10y=20形参改变之后x=20y=10方法调用之后a=10b=20

【程序解析】

通过程序的运行结果可以看出:实际参数即a、b的值不受形式参数x、y的值的影响,即使形式参数的值改变了,实际参数的值也不会改变。

(4)构造方法。构造方法用来初始化新创建的对象。类可以包含一个或者多个构造方法,不同的构造方法根据参数的不同来决定要初始化的新对象的状态。所有的Java类都有构造方法,它用来对新的对象进行初始化。构造方法与类的名字是相同的。比如Stack类的构造方法的名字为Stack,而Rectangle类的构造方法的名字为Rectangle,Thread类的构造方法的名字为Thread。下面给出Stack类的构造方法:

publicStack(){items=newVector(10);}

Java支持对构造方法的重载,这样一个类就可以有多个构造方法,所有的构造方法的名字是相同的,只是所带参数的个数和类型相异而已。下面是类Stack的另一个构造方法,这个构造方法根据它的参数来初始化对象的大小。publicStack(intinitialSize){items=newVector(initialSize);}

从上面可以看出,两个构造方法都有相同的名字,但是它们有不同的参数列表。编译器会根据参数列表的数目以及类型来区分这些构造方法。所以,当创建对象的时候,要根据它的参数是否与初始化的新对象相匹配来选择构造方法。根据传递给构造方法参数的数目和类型,编译器可以决定要使用哪个构造方法。如对于下面的代码,编译器就可以知道应该使用单一的整型参数来初始化对象:

newStack(10);

与此相同,当给出下面代码的时候,编译器选择没有参数的构造方法或者缺省的构造方法进行初始化:

newStack();

另外,如果生成的类不为它提供构造方法,系统会自动提供缺省的构造方法。这个缺省的构造方法不会完成任何事情。下例给出类AnimationThread的构造方法,在其初始化过程中设置了一些缺省的数值,比如帧速度、图片的数目等。classAnimationThreadextendsThread{intframesPerSecond;intnumImages;Image[]images;AnimationThread(intfps,intnum){super("AnimationThread");this.framesPerSecond=fps;this.numImages=num;this.images=newImage[numImages];for(inti=0;i<=numImages;i++){…}

}…}

从该例来看,构造方法的实体跟一般方法的实体是相似的,均包含局部变量声明、循环以及其他的语句。该例的构造方法中出现了以下一条语句:

super(″AnimationThread″);

与关键字this相似(this表示当前对象),关键字super表示当前对象的父对象,所以使用super可以引用父类被隐藏的变量和方法。本例中调用了父类Thread的构造方法。使用中须注意的是,父类的构造方法必须是子类构造方法的第一条语句,因为对象必须首先执行高层次的初始化。构造方法说明中只能带访问控制修饰符,即只能使用public、protected及private中的任一个。

(5)变量和方法的访问控制。前面多次提到过对类、变量及方法的访问控制属性,比如有private、friendly、protected及public。Java中最低级的访问控制范围是类的级别,分为四种:同一个类、同一个包、不同包的子类及不同包的非子类。

类的访问控制权限只能为public和friendly,变量和方法的访问控制可以为上面四种中的任何一种。关于访问控制权限修饰符的作用,在5.1.3节进行详细介绍。

5.1.2对象

本项目开始的时候就讨论过类与对象的关系,大家知道,类是一个抽象的概念,而对象是实实在在存在的东西,是一个具体的概念,所以对象的使用就是某个类的实例化操作。与此对应,本节分两部分来介绍对象:对象的创建及对象的使用。

对象的创建

Java中创建新的对象必须使用new语句,其一般格式为:

classNameobjectName=new

className(parameterList);

此表达式隐含了三个部分,即:对象说明、实例化和初始化。

对象说明:上面的声明格式中,classNameobjectName是对象的说明;className是某个类名,用来说明对象所属的类;objectName为对象名。例如:

IntegeriVariable;

该语句说明iVariable为Integer类型。

实例化:new是Java实例化对象的运算符。使用命令new可以创建新的对象并且为对象分配内存空间。一旦初始化,所有的实例变量也将被初始化,即算术类型初始化为0,布尔逻辑型初始化为false,复合类型初始化为null。例如:

IntegeriVariable=newInteger(100);

此句实现将Integer类型的对象iVariable初始值设为100的功能。

初始化:new运算符后紧跟着一个构造方法的调用。前面介绍过,Java中的构造方法可以重构,因而通过给出不同的参数类型或个数就可以进行不同初始化工作。如例5-2,类Rectangle定义了一个矩形类,它有多个不同的构造方法,可以通过调用不同的构造方法来进行初始化。【例5-2】对象的初始化举例。importjava.util.*;importjavax.swing.*;importjava.awt.*;publicclassRectangle{publicintwidth=0;publicintheight=0;publicPointorigin;

publicstaticvoidmain(Stringargs[]){

Pointp=newPoint(20,20);

Rectangler1=newRectangle();

Rectangler2=newRectangle(p,80,40);

System.out.println("TheareaofRectangleis:"+r1.area());

System.out.println("TheareaofRectangleis:"+r2.area());

}publicRectangle(){origin=newPoint(0,0);}publicRectangle(Pointp){origin=p;}publicRectangle(intw,inth){this(newPoint(0,0),w,h);}publicRectangle(Pointp,intw,inth){origin=p;width=w;height=h;}publicvoidmove(intx,inty){origin.x=x;origin.y=y;}publicintarea(){returnwidth*height;}}classPoint{publicintx=0;publicinty=0;publicPoint(intx,inty){this.x=x;this.y=y;}}

该例中,我们定义了两个类Rectangle、Point,并调用了类Rectangle中的area()方法来求矩形的面积。方法Rectangle()不带参数,因而只是初始化原点坐标为(0,0),矩形的长、宽均为0;方法Rectangle(p,80,40)不仅初始化原点由类型Point()指定,同时还限定矩形的长、宽分别为80,40。

对象的使用

前面花了很大的篇幅介绍类,其目的就是为了掌握如何使用它。类是通过实例化为对象来使用的,而对象的使用是通过引用对象变量或调用对象的方法来实现的。与相类似,对象变量和方法是通过运算符“.”来实现的。1.变量的引用对象变量引用的一般格式为objectName.variableName;例如:classexample{intx;}examplea=newexample();a.x=100;

变量的引用在Java中还有一种很特殊的情况,即可以使用表达式指定变量所在的对象,例如:

intz=newexample().x;

这个语句创建了一个新的example对象,并且得到了它的成员变量x。需要注意的是,在这条语句被执行后,程序不再保留对象expmple的引用。这样,对象example就被取消引用,因而通过上述语句并不能达到初始化对象的目的。

2.对象方法的引用

与对象变量一样,对象方法的引用的一般格式为:

objectName.methodName([argumentList]);

例如在例5-2中调用对象Rectangle中的area()方法计算矩形的面积:System.out.println(“TheareaofRectangle1is:”+r1.area());System.out.println(“TheareaofRectangle1is:”+r2.area());

虽然通过直接引用对象变量可以改变对象的属性,但是它没有任何意义(比如,在例5-2中,使用Rectangle类的构造方法,可以创建不同的矩形,如果设置其高为height、宽width是负值,程序并不认为其非法)。所以,较好的做法是:不直接对变量进行操作,而由类提供一些方法,对变量的引用可以通过这些方法来进行,以确保给定变量的数值是有意义的。这样一来,Rectangle类将提供setWidth、setHeight、getWidth以及getHeight方法来设置或者获得宽度和高度。设置变量的方法将在调用者试图将width和height设置为负数的时候给出一个错误提示。这样能够更好地体现数据的封装和隐蔽。例如,加上上述的几个方法后,例5-2变为publicclassRectangle{……publicvoidsetWidth(intwidth){if(width<0)System.out.println(″illegalnumber!″);elsethis.width=width;}publicvoidsetHeight(intheight){……}publicintgetWidth(){returnwidth;}publicintgetHeight(){returnheight;}publicvoidmove(intx,inty){origin.x=x;origin.y=y;}publicintarea(){

returnwidth*height;

}}

5.1.3类的封装

Java是一个面向对象的程序设计语言,面向对象编程的基本单元是类。我们说类是对对象的一个抽象,同时类也为对象进行了封装。所谓封装也就是说类的设计者只是为使用者提供类对象可以访问的部分(包含类的成员变量和方法),而对于类中其他成员变量和方法隐藏起来,用户不能访问。这种数据隐藏机制和封装机制为程序的编制和系统的维护提供了方便,我们不必知道程序实现的细节,而只要知道类可以访问的部分,排除错误更为方便。

所谓封装,指以下几个方面:

(1)在类的定义中设置对对象中的成员变量和方法进行访问的权限。

(2)提供一个统一供其他类引用的方法。

(3)其他对象不能直接修改本对象所拥有的属性和方法。

隐藏和封装机制是面向对象程序设计的特性,那么如何进行数据的隐藏和封装呢?Java为对象变量提供4种访问权限:public、protected、private和friendly。

对象的可见性和作用域

对于类而言,它有成员变量和方法。对于类中的成员变量,它是属于整个类的,在创建对象时,自动在内存区域分配一块空间作为对象的属性出现。同样,类的方法中也有变量,这些变量的运行范围只是在方法体内,如果出了方法体,那么这些变量就不起作用。

属于类中的成员变量或方法是否就可以被其他类访问呢?前面给出的例子中为类、方法和成员变量的定义中常常要用到“public”这个关键字,它的意思是允许其他类对其所定义的类、方法和成员变量进行访问,如果不想让其他类对其进行访问,或者是只允许类中的方法来访问当前类的成员变量和方法,那么就可使用private来定义。

这里就涉及方法和成员变量的生存期问题,也就是说这些变量在程序中的哪些区域有定义。

【例5-3】引用私有方法和修改私有成员变量。

classdef{

privateintx,y,z=0;//定义私有变量

privatevoidmethod1(){//定义私有方法

intx=3,y=4,z;

z=x*y;

System.out.println(″z=″+z);

}publicvoidshow(){System.out.println(″z=″+z);

}}publicclassChange1{publicstaticvoidmain(Stringargs[]){defss=newdef();ss.method1();//直接引用私有方法出现错误ss.z=12;//直接修改私有变量是不允许的ss.show();}}程序编译结果:>JavacChange1.javaChange1.java:15:method1()hasprivateaccessindefss.method1();//直接调用私有方法出现错误^Chnage1.java:16:zhasprivateaccessindefss.z=12;//直接修改私有变量是不允许的^

2个错误

【程序解析】程序要直接修改私有变量是不允许的,只有类本身和方法可以对私有变量进行访问,这也就是我们常说的,数据封装后,类外的方法是不能访问私有变量的,达到数据安全的目的。

【例5-4】修改例5-3,使其能够引用方法并修改成员变量。

classdef{

privateintx,y,z=0;

publicvoidmethod1(){

intx=3,y=4,z;

z=x*y;

System.out.println(″z=″+z);

}publicvoidshow(){System.out.println(″z=″+z);}}publicclassChange2{publicstaticvoidmain(Stringargs[]){intz=20;defss=newdef();ss.method1();//引用ss对象的method1()方法ss.show();}}程序运行结果:z=12z=0

【程序解析】程序中将method1()方法的访问权限由private改为public,然后引用method1()方法,通过method1()方法对def类中的私有成员变量z进行访问。

通过这个例子可以看出,对于类中的成员变量和方法,如果允许其他类对其进行访问,可以将其访问权限设置为public;如果要防止其他类对其进行访问,可以尽量设置为private。

下面分别讲述访问权限修饰符的作用。

public

public顾名思义是公开的、公众的,也就是说如果一个类被修饰为public,那么这个类就是公共类。公共类不但可供它所在包中的其他类使用,也可供其他包中的类使用,在程序中可以用import语句引入其他包中的public类。那些被public定义的类中成员变量或方法可以供其他类进行访问,这些类、方法和成员变量可以用来供其他类访问。

在Java中,一个程序文件只能定义一个public类,其他类可以是没有修饰的类。

【例5-5】使用import引入已经定义的、属性为public的Account类,引用其方法。

publicclassAccount{//定义公共类Account

Stringname;

Stringaddress;

publicdoublebalance;//定义该成员变量是公共的

publicvoiddisplay(){//定义公共方法display

System.out.println(″name:″);System.out.print(name);System.out.println(″Address:″);System.out.print(address);System.out.println(″balance:″);System.out.print(balance);}}

定义了公共类Account以及公共成员变量balance和方法display(),将此文件保存为Account.java。

引入Account类并引用Account类定义的方法

importAccount;//引入公共类Account

publicclassUseraccount{

publicstaticvoidmain(Stringargs[]){

Accountmyaccount=newAccount();//成绩类对象myaccount

=″张三″;

myaccount.address=″郑州市黄河路19号″;

myaccount.balance=123.40;//引用myaccount对象的balance成员变量

myaccount.display();//引用display()方法,显示输入内容

}

}

程序运行结果:

name:张三

address:郑州市黄河路19号

balance:123.4

private

如果不想让其他类进行访问,采取什么方法呢?就是对其设置private访问权限。

【例5-6】定义Scope类的私有方法,使用类外的方法来引用此私有方法,查看程序运行情况。

classScope{

privateintx=10;

Scope(){

intx=1000;

}privatevoida(){//设置为私有方法

intx=200;

x*=4;

System.out.println(″Aofamethodis″+x);}privatevoidb(){//设置为私有方法

x*=2;

System.out.println(″Bofamethodis″+x);}}publicclassSamp2{

publicstaticvoidmain(Stringargs[]){

intx=100;

System.out.println(″xofmainmethodis″+x);Scopeb1=newScope();b1.a();b1.b();System.out.println(″xofmainmethodis″+x);}}程序编译结果:>javacSamp2.java

Samp2.java:22:a()hasprivateaccessinScope

b1.a();

^

Samp2.java:23:b()hasprivateaccessinScope

b1.b();

^

2个错误

【程序解析】在这里对Scope类的a()方法和b()方法设置为私有属性,所以不能对其方法进行访问,而如果要访问,只能通过类本身所定义的方法。

例如修改Scope类中定义的构造方法,在构造方法中引用方法a()和方法b(),修改程序如下:

classScope{

privateintx=10;

Scope(){

intx=1000;

a();//调用a()方法

b();//调用b()方法}privatevoida(){//设置为私有方法

intx=200;

x*=4;

System.out.println(″Aofamethodis″+x);}

privatevoidb(){//设置为私有方法

x*=2;

System.out.println(″Bofamethodis″+x);

}

}

【程序解析】当创建对象时,系统自动引用构造方法,而在构造方法中添加调用a()和b()方法,这样就可以使用类中的方法来访问类中的私有成员变量和方法。

protected

使用protected定义的成员变量或方法具有二重性,类本身、子类或包中的方法可以访问它们,而对于其他类没有访问权限。

【例5-7】定义类的protected方法,通过创建对象来引用此方法。

classMax

{

privateintx,y;//定义私有变量

protectedintplay(ints,intt)//定义protected方法{intm;x=s;y=t;m=(x>y)?x/y:y/x;returnm;}}publicclassGetNum{publicstaticvoidmain(Stringargs[]){

intresult;

Maxss=newMax();

result=ss.play(5,45);

System.out.println(″result=″+result);

}}

程序运行结果:

result=9

【程序解析】对play()方法设置的protected属性在程序引用中可以像使用public修饰的权限方法一样来引用。

friendly

如果在通常条件下,成员变量或方法名前都没有设定如public、private等访问权限关键字,则通常称此成员变量或方法为friendly,这意味着这些成员变量或方法对于包内的所有类而言它们是可以访问的,但对于包外的类,则不能对它们进行访问。

【例5-8】使用方法的默认访问权限来引用此方法。publicclassX1{X1(){//X1类构造器System.out.println(″Thisisaconstruct″);}voiddoing(){System.out.println(″Couldyoutellme″);}}//将此文件保存为X1.javaimportX1;//引用X1类publicclassX2{staticvoidstore(){System.out.println(″Thisisastoreprocessing″);}publicstaticvoidmain(Stringargs[]){X1y=newX1();y.doing();store();}}程序运行结果:ThisisaconstructCouldyoutellmeThisisastoreprocessing

【程序解析】类X1与类X2在编译后系统自动将它们放在一个包内。对于X1类中的doing()方法而言,如果不进行访问权限设定,则通过“importX1”方法引入,使得X1类对象y可以调用doing()方法,即“y.doing();”。但是如果在X1类中对doing()方法强加private访问权限(如:privatevoiddoing();),则当使用y对象调用doing()方法时,编译会出现错误提示信息。

任务进阶

【进阶任务19】创建并应用People类

设计过程:

(1)在“记事本”中输入如下程序:

classPeople

{

floatheight,weight;

Stringhead,ear,hand,foot,mouth;

voidspeak(Strings)

{

System.out.println(s);}}publicclassPeopleDemo{publicstaticvoidmain(Stringargs[]){Peoplezhubajie,sunwukong;//声明对象zhubajie=newPeople();//为对象分配内存sunwukong=newPeople();zhubajie.height=1.80f;//对象给自己的变量赋值zhubajie.head="大头";zhubajie.ear="一双大耳朵";sunwukong.height=1.62f;//对象给自己的变量赋值sunwukong.weight=1000f;sunwukong.head="金发飘飘";System.out.println("zhubajie的身高:"+zhubajie.height);System.out.println("zhubajie的头:"+zhubajie.head);System.out.println("sunwukong的重量:"+sunwukong.weight);System.out.println("sunwukong的头:"+sunwukong.head);zhubajie.speak("俺老猪我想娶媳妇");//对象调用方法System.out.println("zhubajie现在的头:"+zhubajie.head);sunwukong.speak("老孙我重1000斤,我想骗八戒背我");//对象调用方法System.out.println("sunwukong现在的头:"+sunwukong.head);}}

(2)将文件保存在“D:\\myprogram”文件夹中,文件名为PeopleDemo.java。

(3)在“命令提示符”窗口内的“D:\\myprogram”提示符下,输入“javacPeopleDemo.java”命令,然后在新的命令行中,输入“javaPeopleDemo”命令,运行字节码程序,输出程序的运行结果,如图5-1-2所示。图5-1-2

程序PeopleDemo的运行结果【进阶任务20】创建并应用梯形类设计过程:(1)在“记事本”中输入如下程序:classLader//梯形类{floatShangDi,Gao;staticfloatXiaDi;Lader(floatx,floaty,floath)//构造函数{ShangDi=x;XiaDi=y;Gao=h;}floatGetXiaDi(){returnXiaDi;}//获取下底voidSetXiaDi(floatb){XiaDi=b;}//修改下底floatGetShangDi(){returnShangDi;}//获取上底voidSetShangDi(floatb){ShangDi=b;}//设置上底floatGetGao(){returnGao;}//获取高voidSetGao(floatb){Gao=b;}//修改高publicfloatarea(){//求梯形的面积floatresult;result=(ShangDi+XiaDi)Gao/2;returnresult;}}publicclassLaderDemo{publicstaticvoidmain(Stringargs[]){//分别创建2个梯形类的对象laderOne和laderTwoLaderladerOne=newLader(3.0f,10.0f,20),laderTwo=newLader(2.0f,3.0f,10);laderOne.SetXiaDi(100);//通过对象操作类变量

System.out.println("laderOne的XiaDi:"+laderOne.GetXiaDi());

System.out.println("laderTwo的XiaDi:"+laderTwo.GetXiaDi());

laderOne.Gao=30;laderTwo.SetXiaDi(60);

System.out.println("laderOne的ShangDi:"+laderOne.GetShangDi());

System.out.println("laderOne的XiaDi:"+laderOne.GetXiaDi());

System.out.println("laderOne的Gao:"+laderOne.GetGao());

System.out.println("laderOne的面积:"+laderOne.area());

System.out.println("laderTwo的ShangDi:"+laderTwo.GetShangDi());

System.out.println("laderTwo的XiaDi:"+laderTwo.GetXiaDi());

System.out.println("laderTwo的Gao:"+laderTwo.GetGao());

System.out.println("laderTwo的面积:"+laderTwo.area());}}

(2)将文件保存在“D:\\myprogram”文件夹中,文件名为LaderDemo.java。

(3)在“命令提示符”窗口内的“D:\\myprogram”提示符下,输入“javacLaderDemo.java”命令,然后在新的命令行中,输入“javaLaderDemo”命令,运行字节码程序,输出程序的运行结果,如图5-1-3所示。图5-1-3

程序LaderDemo的运行结果第三章624三、分支程序与循环程序设计休息一下,巩固所学的知识5.2【任务10】设计本科生类和研究生类

任务描述:

编写一个程序UseStudents,设计本科生类(Undergraduate)和研究生类(Graduate),两个类都由学生类派生。在本科生类中增加属性:选修专业(Specialty),在研究生类中增加属性:研究方向(Studydirection)。并分别创建这几个类的对象。通过该任务的学习,可以初步了解类的继承和多态的基本概念,并掌握类的继承和类的多态的使用方法。

设计过程:

(1)在“记事本”中输入如下程序:

classStudents{//下面是Students类的成员变量和方法

publicStringname;publicintage;publicStringdegree;publicStudents(Stringname1,intage1,Stringdegree1)//构造方法用于初始化类{name=name1;age=age1;degree=degree1;}publicvoidsetName(Stringn){name=n;}//设置学生姓名publicvoidsetAge(inta){age=a;}//设置学生年龄

publicvoidsetDegree(Stringd){degree=d;}//设置学生的学位

publicStringgetName(){returnname;}//获取学生姓名

publicintgetAge(){returnage;}//获取学生成绩

publicStringgetDegree(){returndegree;}//获取学生学位

publicvoidshow()

{System.out.println("学生的姓名是:"+name);System.out.println("学生的年龄是:"+age);System.out.println("学生的学位是:"+degree+"\\n");}}classUndergraduateextendsStudents{

//下面是Undergraduate类的成员变量和方法,是Students父类的一个子类

publicStringSpecialty;//选修专业

publicUndergraduate(Stringname1,intage1,Stringdegree1,StringSpecialty1)

{//构造方法用于初始化类

super(name1,age1,degree1);

Specialty=Specialty1;

}

publicvoidsetSpecialty(Strings){Specialty=s;}//设置学生的选修专业

publicStringgetSpecialty(){returnSpecialty;}//获取选修专业

publicvoidshow()

{System.out.println("学生的姓名是:"+name);System.out.println("学生的年龄是:"+age);System.out.println("学生的学位是:"+degree);System.out.println("学生的选修专业是:"+Specialty+"\\n");}}

classGraduateextendsStudents{

//下面是Graduate类的成员变量和方法,是Students父类的一个子类

publicStringStudydirection;//研究方向

publicGraduate(Stringname1,intage1,Stringdegree1,StringStudydirection1)

{//构造方法用于初始化类

super(name1,age1,degree1);

Studydirection=Studydirection1;

}

publicvoidsetStudydirection(Strings){Studydirection=s;}//设置学生的研究方向

publicStringgetStudydirection(){returnStudydirection;}//获取研究方向

publicvoidshow()

{

System.out.println("学生的姓名是:"+name);

System.out.println("学生的年龄是:"+age);

System.out.println("学生的学位是:"+degree);

System.out.println("学生的研究方向是:"+Studydirection+"\\n");}}

publicclassUseStudents{

publicstaticvoidmain(Stringargs[]){

Studentss1=newStudents("张三",18,"大专");

Undergraduates2=newUndergraduate("李四",20,"本科","学士");

Graduates3=newGraduate("王五",28,"硕士","Java程序设计");

s1.show();

s2.show();

s3.show();}}

(2)将文件保存在“D:\\myprogram”文件夹中,文件名为UseStudents.java。

(3)在“命令提示符”窗口内的“D:\\myprogram”提示符下,输入“javacUseStudents.java”命令,然后在新的命令行中,输入“javaUseStudents”命令,运行字节码程序,输出程序的运行结果,如图5-2-1所示。图5-2-1

程序UseStudents的运行结果

相关知识

5.2.1类的继承

继承是面向对象程序设计的一个重要特征,它是通过继承原有类的基础,派生出新类,进而开发出更为复杂的数据类型。新开发的对象既有新定义的行为特征,又包含有原有类定义的行为特征。

继承的概念

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论