4章.docx

上传人:b****4 文档编号:4666073 上传时间:2022-12-07 格式:DOCX 页数:20 大小:25.74KB
下载 相关 举报
4章.docx_第1页
第1页 / 共20页
4章.docx_第2页
第2页 / 共20页
4章.docx_第3页
第3页 / 共20页
4章.docx_第4页
第4页 / 共20页
4章.docx_第5页
第5页 / 共20页
点击查看更多>>
下载资源
资源描述

4章.docx

《4章.docx》由会员分享,可在线阅读,更多相关《4章.docx(20页珍藏版)》请在冰豆网上搜索。

4章.docx

4章

第4章类和对象

本章主要介绍Java语言中类的定义及类的访问控制、成员的定义及成员的访问控制、对象的创建、数组的创建及使用。

第4章类和对象

4.1OO(Object-oriented)基本概念

4.2类的定义

4.3域(成员变量/字段)声明

4.4方法的定义

4.5类变量的初始化形式

4.6类对象的初始化形式

4.7数组

4.7.1数组的创建形式

4.7.2(一组)数组的应用

4.7.3多维数组

4.8对象的撤消(清除)

4.9小结

4.1OO(Object-oriented)基本概念

1.类(Class)

类是一组具有共同的属性特征和行为特征的对象的抽象。

(1)属性(Attribute)

是描述对象静态特征的一个数据项。

(2)服务(Service)

是描述对象动态特征(行为)的一个操作序列。

2.对象(Object)

对象是一组数据(属性)及对这组数据属性的一组操作(行为)构成的有标识的独立实体。

类与对象的关系:

抽象与具体的关系。

类是产生对象的模板,而对象是类的一个实例。

3.封装(encapsulation)

是指通过类机制把对象的数据和对数据的操作(行为)封装在一起成为一个独立的系统单位。

4.2类的定义

4.1.1类的定义形式

Java程序由类构成,类由类头和类体组成,其一般形式为:

[<修饰符>]class<类名>

{<每个字段的声明>

<每个方法的定义>

}//类定义结束

其中类的修饰符有2种:

(1)访问控制符

public、private或缺省来指定类的访问权限。

如:

publicclassObject{....}

(2)非访问控制符

abstract、final分别用来声明抽象类和最终类。

如:

publicfinalclassSystem{....}

下面我们定义一个平面上的点类Point,如下:

//文件名:

Point.java

publicclassPoint

{privateintx,y;//坐标

publicvoidsetPoint(inta,intb)

{x=a;y=b;}

publicvoidmove(intdx,intdy)

{x+=dx;y+=dy;}

publicintgetX(){returnx;}

publicintgetY(){returny;}

publicStringtoString()

{return“(“+x+”,”+y+”)”;}

}

4.1.2类的访问控制修饰符及访问权限

和C++不同,访问权限有二层,外层为类的访问权限,由类访问控制符来指定。

内层是成员的访问权限,由成员访问控制符指定。

类的访问控制符有:

(1)public及公有访问权限

如:

publicclassA{...}

classC

{Aobj=newA();...}

公有类可被任何程序包中的所有类引用。

引用是指在类中或者在它们的方法体内,都可以创建该类的对象、访问这个类内可见的成员变量和调用它的方法。

(2)缺省及包访问权限

如:

classB{...}//B是友类

classD

{Bobj=newB();...}

缺省时声明的类称友类,友类具有包访问权限。

友类只可被同一个程序包内的所有类引用。

一般将相关的类放到同一个程序包内,在包内它们能自由访问,对外隐藏,可实现“内外有别”的封装机制。

说明1点:

同一个编译单元(Java源文件)的类属于同一个程序包。

(3)private及私有访问权限(后续介绍)

私有类具有私有访问权限。

私有类只能被外部类访问。

因此,只有内部类才允许声明为私有类,而普通类或包含内部类的外部类是不允许声明为私有类。

classOuter

{Innerobj=newInner();//合法

privateclassInner//私有的内部类

{.....}

}

classX

{Outer.Innerobj;...}//非法

4.3域/成员变量/字段(field)

4.3.1域(field)的声明

一般来说,类体包括一个或几个域的声明。

域的声明形式:

[访问控制修饰符][修饰符]<类型><变量名表>;

其中[]中的项可以省略。

4.3.2域的访问控制符及访问权限

(1)public

公有域可被任何类访问。

即在其它类体内或者是方法体内,可以对该成员变量进行读或写。

(2)protected

保护域可被本类访问,也可被同一包内的其它类访问,还可被其它包内的该类的子类访问。

备注:

包及包的使用方法在下一章介绍。

(3)缺省

缺省域可被本类及同一包内的其它类访问。

(4)private

私有域只能被本类的所有方法访问。

它常用来描述那些需要隐藏起来的数据信息,其他类只有通过调用该类的公有方法才能访问到它们,这就是所谓的面向对象的“数据封装和信息隐藏”的基本思想。

下面定义的是时间类Time。

classTime

{privateinthour,minute,second;

publicTime(){hour=minute=second=0;}

publicTime(inth,intm,ints)

{setTime(h,m,s);}

publicvoidsetHour(inth)//设置小时

{hour=h>=0&&h<24?

h:

0;}

publicvoidsetMinute(intm)//设置分

{minute=m>=0&&m<60?

m:

0;}

publicvoidsetSecond(ints)//设置秒

{second=s>=0&&s<60?

s:

0;}

publicvoidsetTime(inth,intm,ints)

{setHour(h);setMinute(m);setSecond(s);}

publicintgetHour(){returnhour;}

publicintgetMinute(){returnminute;}publicintgetSecond(){returnsecond;}

}//Time定义结束

4.3.3成员变量(域)的类型

2种:

静态域(类变量)和非静态域(实例变量)

用static声明的域称类变量,未用static声明的域称实例变量。

注意:

不同的对象关于静态域只有一个副本,在程序加载时系统就为它分配内存了,而不同的对象关于实例变量有不同的副本,在对象创建时才生成。

下面是圆类Circle的定义:

publicclassCircle

{publicfinalstaticdoublePI=Math.PI;//类变量

privateintradius;//实例变量

publicstaticdoublegetPI(){returnPI;}

publicvoidsetRadius(intr){radius=r;}

publicintgetRadius(){returnradius;}

publicdoublegetArea()

{returnPI*radius*radius;}

}

关于成员变量说明2点:

(1)有两种访问类变量的方法:

类名.类变量名

对象名.类变量名

下面是访问实例变量的唯一方式:

对象名.实例变量名

(2)两种成员变量都可以在声明的同时赋初值。

当没有赋初值时,系统将用缺省值对其初始化,见教材P.67。

成员变量的默认初值

类型

默认初值

boolean

false

char

'\u0000'

byte、short

(byte)0、(short)0

int、long

0、0L

float、double

+0.0f、+0.0

引用型变量

null

4.3.4最终域

最终域就是指用final声明的成员变量。

最终域初始化后不能被修改。

如:

publicclassCircle

{publicstaticfinaldoublePI=Math.PI;...

//该方法体内不能有setPI()

}

用final声明域时,要注意以下2点:

(1)同时需要指出tatic。

4.3.5域的作用域

域的作用域开始于声明处,结束于类的右花括号处。

域的作用域大于形参(是自动变量)的作用域,如:

classPoint

{privateintx,y;

//……

publicvoidsetPoint(intx,inty)

{this.x=x;this.y=y;}

}

4.3.6域的数据类型

域(成员变量)的数据类型可以是两种:

基本数据类型和引用类型(类、接口、数组等)。

4.4方法的定义

一般地说,方法的定义形式为:

[<访问控制修饰符>][<修饰符>]<返回类型>

<方法名>(<形参表>)

{<语句序列>

}

4.4.1方法的访问控制符及访问权限

同成员变量,有四种:

public、protected、缺省、private。

让我们来回忆一下这四种访问权限。

4.4.2构造方法和创建对象

(1)构造方法

用于初始化类对象的实例变量。

注意构造方法常被重载。

如:

为Point类定义构造方法。

classPoint

{privateintx,y;//坐标

publicPoint(){x=0;y=0;}

publicPoint(inta,intb){x=a;y=b;}

publicPoint(Pointr){x=r.a;y=r.b;}

//....

}

说明3点:

(a)当类中没有定义任何构造函数时,编译器自动产生一个函数体为空的缺省构造函数如下。

一般来说,应该为类定义构造函数。

publicX(){}

(b)当用已存在的对象初始化正在创建的对象时,将调用拷贝构造函数,其一般形式为:

publicX(Xp){每个实例变量间的拷贝操作}

(c)与C++不同,Java不产生缺省拷贝构造函数,若程序中要用时,必须自行定义拷贝构造函数。

(2)创建对象

对象创建的一般形式:

new<构造方法名>(<实参表>)

上述表达式创建的对象是匿名的,返回值为被创建对象的引用,要访问创建的对象,必须建立对象和对象引用变量(简称引用或句柄)的连接。

形式如下:

<类名><引用变量名>=new<构造方法名>(<实参表>);

<类名><引用变量名表>;

……

<引用名>=new<构造方法名>(<实参表>);

阅读下面的程序并写出程序输出。

public class Test

{ public static void main(String[] args)

{ String foo=newString("blue"); 

//String foo="blue";   

String bar=foo;    foo="green"; 

System.out.println(bar); 

 } 

   } 

说明3点:

(1)对象引用和其指向的对象是两个实体。

对象是匿名的,只能通过对象引用来访问。

(2)建立对象和其引用间的连接。

(3)对象和指向它的对象引用应属于同一种类类型,不同类型的对象引用和对象间一般无法直接建立连接的。

4.4.3静态方法(类方法)和非静态方法(实例方法)

用static声明的方法称类方法,是每个对象所共享的方法。

否则称实例方法,它是某个具体类对象(实例)的方法。

注意3点:

(1)调用类方法时,应用类名做前缀,最好不用对象名做前缀。

(2)在类方法内,不能直接访问实例成员,只能访问类成员。

classB

{intx=0;

staticpublicvoidfun()

{x=1;//非法,不能访问实例变量x

}...

}

(3)实例方法体内,既可以访问实例成员(实例变量和实例方法),也可以访问类成员。

4.4.4方法的重载

指重新定义已有的方法,得到的方法称重载方法。

对方法重载时必须遵循函数名相同,但参数表不同(个数不同或参数类型不同)。

如:

classPoint

{privateintx,y;//坐标

publicvoidsetPoint(inta,intb)重载方法1

{x=a;y=b;}

publicvoidsetPoint(Pointp)//重载方法2

{x=p.x;y=p.y;}

……

}

4.4.5this引用(变量)和实例方法

类的实例方法都有一个隐含的引用变量,称为this引用变量,简称this引用。

当1个对象调用某个实例方法时,它的this就指向那个对象。

在实例方法内访问的实例成员,都是this所指对象的实例成员;所以this引用往往省略。

如:

classPoint

{privateintx,y;//坐标

publicvoidsetPoint(Pointp)

{x=p.x;y=p.y;}//省略了this

publicvoidsetPoint(intx,inty)//重载

{this.x=x;this.y=y;}//此处的this不能省略

publicvoidmove(intdx,intdy)

{x+=dx;y+=dy;}//省略了this

publicdoublegetX(){returnx;}

publicdoublegetY(){returny;}

publicStringtoString()

{return“(“+x+”,”+y+”)”;}

}

在使用时注意3点:

(1)类方法没有this,所以在类方法体内不能访问实例变量及实例方法;

(2)当实例变量与实例方法的自动变量同名时,必须显式使用this,见上面的例子。

(3)对于重载的构造方法,可以在一个构造方法体内使用“this(参数表);”形式来调用本类另一个构造方法。

如:

classPoint

{privateintx,y;//坐标

publicPoint(){this(0,0);}

//this代表本类名,该语句必须是第一行语句

publicPoint(inta,intb){x=a;y=b;}

……

}

4.5类变量的初始化形式

有2种形式:

(1)在声明类变量的同时指定初始值,若未指定则用缺省值。

publicclassCircle

{publicfinalstaticdoublePI=3.1415926;

//省略其它成员

}

(2)在类中用static开头的语句块(静态初始化块)对类变量初始化,格式为:

static

{<语句序列>

}

如:

publicclassA

{publicstaticinta=1,b=0;

static

{a=0;b=1;

System.out.println("a="+a+"b="+b);

a=10;b=10;

}

publicstaticvoidmain(Stringargs[])

{System.out.println("a="+a+"b="+b);}

}

说明3点:

(1)静态初始化器在它所属的类加载到内存时由系统执行。

(2)一个类允许有多个静态初始化器,按它们出现的先后次序被执行。

(3)静态初始化器中的语句不能访问实例成员。

4.6类对象的初始化形式

对象的实例变量的初始化形式有3种:

(1)在声明实例变量的同时指定初始值,若未指定则用缺省值。

例如:

publicclassCircle

{publicfinalstaticdoublePI=Math.PI;

privateintradius=1;

privateintx=0,y;

publicintgetRadius(){returnradius;}

publicintsetRadius(intr){radius=r;}

...

}

指出newCircle()的执行过程。

(2)用初始化块

publicclassCircle

{publicfinalstaticdoublePI=3.1415926;

privateintradius=1;

privateintx=0,y;

{x=1;y=0;}//初始化块允许有其它的语句

...

}

指出newCircle()的执行过程。

(3)用构造方法初始化(必须定义)

publicclassCircle

{publicfinalstaticdoublePI=3.1415926;

privateintradius,x,y;

{x=1;y=1;}

publicCircle(){radius=1;x=0;y=0;}

publicCircle(intr,intx,inty)

{radius=r;this.x=x;this.y=y;}

...

}

试分析表达式:

newCircle(2,2,2)的执行过程。

4.7数组

4.7.1数组的创建形式

在Java中,数组被当成一种对象来处理,因此数组的创建也是用new操作符。

数组元素的类型可以是基本数据类型、类、接口等。

在Java中,创建数组有如下3种方式:

1.先声明数组的引用再创建数组

(1)声明数组引用

形式如下:

<元素类型>[]<数组引用>;//<数据类型><数组引用>[];

注意:

声明时不能指定数组的大小。

例如:

int[]oneDim;//intoneDim[];

oneDim[0]=0;//不能通过编译

(2)创建数组

形式:

<数组引用>=new<数组元素类型>[<元素个数>];

例如:

oneDim=newint[6];//每个元素取0值

注意:

数组创建后,系统用缺省值初始化每个数组元素。

2.声明引用的同时创建数组

<元素类型>[]<数组引用>=new<元素类型>[<元素个数>];

注意:

每个元素取缺省值。

例如:

intoneDim[]=newint[6];

StringcountryName[]=newString[3];

//创建对象数组

byte[]twoDim[]=newbyte[2][3];

3.声明、创建数组的同时初始化数组元素

如:

intoneDim[]={1,2,3,4,5,6};//省略了newint[]

String[]yellow={"blue","green","red"};//省newString[]

byte[]twoDim[]={{1,2,3},{4,5,6}};//省newbyte[][]

关于数组说明4点:

(1)所有的数组都有一个成员变量length,表示数组的长度,其值不能修改,在程序中用oneDim.length查询数组的大小。

(2)初始值可以是常量、变量或复杂表达式。

(3)对象数组的元素必须有一个确定值。

(4)若访问数组下标越界,JVM将抛出ArrayIndexOutOfBoundsException类型的异常,然后中止程序执行。

4.7.2(一组)数组的应用

一个数组经声明、创建或初始化后就可以存取它,下面介绍数组的2个重要的使用场合:

一是作为方法的形参,二是作为方法的返回值。

1.数组引用作为方法的参数

在方法调用发生时,把数组引用传递给被调用方法,在被调用的方法体内就可以读/写每个数组元素。

例如,编写一个程序,实现数组的转置。

publicclassInvertArray

{publicstaticvoidinvert(inta[])

{for(inti=0;i

{inttemp=a[i];a[i]=a[a.length-1-i];

a[a.length-1-i]=temp;

}

}

publicstaticvoidmain(Stringargs[])

{intb[]={1,3,5,7,9,11};

for(inti=0;i

System.out.print(b[i]+"\t");

System.out.println();

invert(b);

for(intelem:

b)

System.out.print(elem+"\t");

}

}

说明:

数组引用作为方法的形参,在使用时和C++基本上没有区别。

2.数组引用作为方法的返回值

方法的返回值是数组引用时,调用方法应该用与方法返回值类型相同的数组引用,接收被调方法的返回结果。

见下例的求斐波那契数列的Application程序。

publicclassCalFibonacci

{publicstaticlong[]reFibonacci(intm)//m≥2

{long[]fibonacci=newlong[m];

 fibonacci[0]=0L;

fibonacci[1]=1L;

for(intn=2;n

fibonacci[n]=fibonacci[n-1]+fibonacci[n-2];

returnfibonacci;

}

publicstaticvoidmain(String[]args)

{finalintn=25;intnum=1;

longfib[]=reFibonacci(n);//求前25个数列项

   System.out.println(“斐波那契数列前25个项:

”);

for(longe:

fib)

{System.out.print(e+"");

if(num%9==0)System.out.println();//一行9个

num++;

}

 }

}

//下面是一个完成等价功能的Applet程序

importjava.awt.Graphics;

publicclassReturnArrayextendsjava.applet.Applet

{publicvoidpaint(Graphicsg)

{intn=25;

longfib[]=reFibonacci(n);//求前25个数

paintArray(g,fib);

 }

long[]reFibonacci(intm)

{longfibonacci[]=newlong[m];

 fibonacci[0]=0L;

fibonacci[1]=1L;

for(intn=2;n

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 初中教育 > 语文

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1