4.2 类
Java 与其他面向对象程序设计的语言一样,引入了类和对象的概念。类是用来创建对象的模板,它包含被创建对象的属性和方法的定义。因此,要学习Java 编程就必须学会怎样去编写类,即怎样用Java 的语法去描述一类事物共有的属性和方法。
4.2.1 定义类
在Java 中,类是基本的构成要素,是对象的模板。Java 程序中所有的对象都是由类创建的。
1.什么是类
类是同一种事物的统称,它是一个抽象的概念,如鸟类、人类、手机类、车类等。
由于Java 是面向对象程序设计的语言,而类是面向对象的核心机制,因此,我们可以在类中编写属性和方法,然后通过对象来实现类的行为。
2.类的声明
在类的声明中,需要定义类的名称、类的被访问权限、该类与其他类的关系等。类的声明格式如下:
●修饰符:可选参数,用于指定类的被访问权限,可选值为public、abstract 和final。
●类名:必选参数,用于指定类的名称。类名必须是合法的Java标识符,在一般情况下,要求首字母大写。
●extends 父类名:可选参数,用于指定要定义的类继承于哪个父类。当使用关键字extends 时,父类名为必选参数。
●implements 接口列表:可选参数,用于指定该类实现的接口。当使用关键字implements时,接口列表为必选参数。
如果一个类被声明为public,则表明该类可以被其他任何的类访问和引用,也就是说,程序的其他部分可以创建这个类的对象、访问这个类内部可见的成员变量和调用它的可见方法。
例如,定义一个Apple 类,对该类的访问权限为public,即该类可以被它所在包之外的其他类访问或引用。具体代码如下:
学习笔记
Java 的类文件的扩展名为 “.java”,类文件的名称前缀必须与类名相同,即类文件的名称为 “类名.java”。例如,有一个Java 类文件Apple.java,则其类名为Apple。
3.类体
在类的声明中,大括号中的内容为类体。类体主要由以下两部分组成:
(1)成员变量的定义。
(2)成员方法的定义。
下面会详细介绍成员变量和成员方法。
在程序设计过程中,编写一个能够完全描述客观事物的类是不现实的。例如,构建一个Apple 类,该类可以拥有很多的属性(即成员变量),但是在定义该类时,只选取程序需要的必要属性和方法就可以了。Apple 类的成员变量列表如下:
这个Apple 类只包含了苹果的部分属性和方法,但是它已经能够满足程序的需要。该类的实现代码如下:
4.2.2 成员变量和局部变量
在类体中,变量定义部分所声明的变量为类的成员变量,而在方法体中,声明的变量和方法的参数则为局部变量。成员变量又可细分为实例变量和类变量。在声明成员变量时,用关键字static修饰的被称为类变量(也可称为static变量或静态变量),否则被称为实例变量。
1.声明成员变量
Java 用成员变量来表示类的状态和属性。声明成员变量的基本语法格式如下:
●修饰符:可选参数,用于指定变量的被访问权限,可选值为public、protected 和private。
●static:可选参数,用于指定该成员变量为类变量,可以直接通过类名访问。如果省略该关键字,则表示该成员变量为实例变量。
●final:可选参数,用于指定该成员变量为取值不会改变的常量。
●变量类型:必选参数,用于指定变量的数据类型,其值可以为Java 中的任何一种数据类型。
●变量名:必选参数,用于指定成员变量的名称。变量名必须是合法的Java 标识符。
例如,在类中声明3 个成员变量,具体代码如下:
类变量与实例变量的区别:在运行时,Java 虚拟机只为类变量分配一次内存,并在加载类的过程中完成类变量的内存分配,可以直接通过类名访问类变量。而实例变量则是在每创建一个实例时,就为该实例的变量分配一次内存。
2.声明局部变量
声明局部变量的基本语法格式同声明成员变量类似,不同的是,不能使用关键字public、protected、private 和static 对局部变量进行修饰,但可以使用关键字final。声明局部变量的基本语法格式如下:
●final:可选参数,用于指定该局部变量为取值不会改变的常量。
●变量类型:必选参数,用于指定变量的数据类型,其值可以为Java 中的任何一种数据类型。
●变量名:必选参数,用于指定局部变量的名称。变量名必须是合法的Java 标识符。
例如,在成员方法grow() 中声明两个局部变量,具体代码如下:
3.变量的有效范围
变量的有效范围是指该变量在程序代码中的作用区域,在该区域外不能直接访问变量。有效范围决定了变量的生命周期。变量的生命周期是指从声明一个变量并分配内存空间、使用变量,然后释放该变量并清除所占用内存空间的一个过程。声明变量的位置决定了变量的有效范围,根据有效范围的不同,可以将变量分为以下两种。
(1)成员变量:在类中声明,在整个类中有效。
(2)局部变量:在方法内或方法内的复合代码块(即方法内部,“{” 与 “}” 之间的代码)中声明的变量。在复合代码块中声明的变量,只在当前复合代码块中有效;在复合代码块外、方法内声明的变量在整个方法内都有效。例如,一个实例的实现代码如下:
4.2.3 成员方法
在Java 中,类的行为由类的成员方法来实现。类的成员方法由以下两部分组成。
(1)方法的声明。
(2)方法体。
其一般格式如下:
●修饰符:可选参数,用于指定方法的被访问权限,可选值为public、protected 和private。
●方法返回值的类型:必选参数,用于指定方法返回值的类型。如果该方法没有返回值,则可以使用关键字void 进行标识。方法返回值的类型可以为任何Java 数据类型。
●方法名:必选参数,用于指定成员方法的名称。方法名必须是合法的Java 标识符。
●参数列表:可选参数,用于指定方法中所需的参数。当存在多个参数时,各参数之间应该使用逗号分隔。方法的参数类型可以为任何Java 数据类型。
●方法体:可选参数,是方法的实现部分。在方法体中可以完成指定的工作,可以只打印一句话,也可以省略方法体,使方法什么都不做。需要注意的是,当省略方法体时,其外面的大括号一定不能省略。
【例4.1】 创建成员方法实现两数相加,具体代码如下:
图4.4 创建成员方法实现两数相加的运行结果
程序运行结果如图4.4 所示。
在上面的代码中包含add() 方法和main() 方法。在add() 方法的定义中,首先定义整数类型的变量sum,该变量是add() 方法参数列表中的两个参数之和。然后使用关键字return 将变量sum 的值返回给调用该方法的语句。main() 方法是类的主方法,是程序执行的入口,该方法创建了类自身的对象count,然后调用count 对象的add() 方法计算苹果数量的总和,并输出到控制台中。
学习笔记
在同一个类中,不能定义参数和方法名都和已有方法相同的方法。
4.2.4 注意事项
上面说过,类体是由成员变量和成员方法组成的。对成员变量的操作只能放在方法中,方法会使用各种语句对成员变量和方法体中声明的局部变量进行操作,在声明成员变量时可以赋予其初始值。
例如:
但是不能这样:
4.2.5 类的UML 图
UML(Unified Modeling Language,统一建模语言)图是一个结构图,用来描述一个系统的静态结构。一个UML 图中通常包含类(Class)的UML 图、接口(Interface)的UML 图,以及泛化关系(Generalization)的UML 图、关联关系(Association)的UML 图、依赖关系(Dependency)的UML 图和实现关系(Realization)的UML 图。
在UML 图中,使用一个长方形描述一个类的主要构成,将长方形垂直地分为三层。Tiger 类的UML 图如图4.5 所示。
第一层是名字层,如果类的名字是常规字形,表明该类是具体类;如果类的名字是斜体字形,表明该类是抽象类(后续会讲到抽象类)。
第二层是变量层,也称属性层,用于列出类的成员变量及类型。格式是“变量名:类型”。
第三层是方法层,用于列出类中的方法。格式是 “方法名:类型”。