七、面向对象设计——类和对象
1. 面向对象的基本概念
类
将具有相同属性及相同行为的一组对象称为类(class)。广义地讲,具有共同性质的事物的集合就称为类。在面向对象程序设计中,类是一个独立的单位,它有一个类名,其内部包括成员变量,用于描述对象的属性;还包括类的成员方法,用于描述对象的行为,这大大地扩充了数据类型的概念。
类是一个抽象的概念,要利用类的方式来解决问题,必须用类创建一个实例化的对象,然后通过对象去访问类的成员变量,去调用类的成员方法来实现程序的功能。就如同“汽车”本身是一个抽象的概念,只有使用了一辆具体的汽车,才能感受到汽车的功能。
一个类可创建多个类对象,它们具有相同的属性模式,但可以具有不同的属性值。JAVA程序为每一个对象都开辟了内存空间,以便保存各自的属性值。
对象
对象(object)是类的实例化后的产物。对象的特征分为静态特征和动态特征两种。静态特征指对象的外观、性质、属性等。动态特征指对象的功能、行为等。客观事物是错综复杂的,但人们总是从某一目的出发,运用抽象分析的能力,从众多的特征中抽取最具代表性、最能反映对象本质的若干特征加以详细研究。
人们将对象的静态特征抽象为属性,用数据来描述,在JAVA语言中称之为变量,将对象的动态特征抽象为行为,用一组代码表示,完成对数据的操作,在JAVA语言中称之为方法(method)。一个对象由一组属性和一系列对属性进行操作的方法构成。
在现实世界中,所有事物都可视为对象,对象是客观世界里的实体。而在JAVA里,“一切皆为对象”,它是一门面向对象的编程语言,面向对象(Object-Oriented)的核心就是对象。要学好JAVA就必须学会使用面向对象的思想来思考问题和解决问题。
类和对象的关系
面向对象的编程思想力图使在计算机语言中对事物的描述与现实世界中该事物的本来面目尽可能地一致,类和对象就是面向对象方法的核心概念。类是对某一类事物的描述,是抽象的、概念上的定义;对象是实际存在的该类事物的个体,因而也称作实例(instance)。
2. 类的声明与定义
类的声明
在使用类之前,必须先声明它,然后才可以声明变量,并创建对象。声明语法如下:
[标识符] class 类名称
{
//类的成员变量
//类的方法
}
标识符可以是public、private、protected或者完全省略这个修饰符,类名称只要是一个合法的标识符即可。类的标识符可以是访问控制符。JAVA提供了一系列的访问控制符来设置基于类(class)、变量(variable)、方法(method)及构造方法(constructor)等不同等级的访问权限。JAVA的访问权限主要有4类。
(1)默认模式(default):在默认模式下,不需为某个类、方法等不加任何访问修饰符。这类方式声明的方法和类,只允许在同一个包(package)内是可访问的。
(2)私有(private):这是JAVA语言中对访问权限控制最严格的修饰符。如果一个方法、变量和构造方法被声明为“私有”访问,那么它仅能在当前声明它的类内部访问。类和接口(interface)的访问方式是不能被声明为私有的。
(3)公有(public):这是JAVA语言中访问权限控制最宽松的修饰符。如果一个类、方法、构造方法和接口被声明为“公有”访问,那么它不仅可以被跨类访问,而且允许跨包访问。如果需要访问其他包里的公有成员,则需要事先导入(import)那个包含所需公有类、变量和方法等的那个包。
(4)保护(protected):介于public和private之间的一种访问修饰符。如果一个变量、方法和构造方法在父类中被声明为“保护”访问类型,只能被类本身的方法及子类访问,即使子类在不同的包中也可以访问。类和接口(interface)的访问方式是不能声明为保护类型的。
光是叙述也不是很好理解,下面举一例子以便更清楚地认识类的组成:
程序首先用class声明了一个名为person的类,在这里person是类的名称。第5、6行先声明了两个属性(即描述数据的变量)name和age,name为String型,age为int型。第7至10行声明了一个talk()方法——操作数据的方法。
类的定义
在声明一个类后,还需要对类进行定义,定义语法如下:
class 类名称
{
数据类型 属性; //零到多个属性
类名称(参数,......) //零个到多个构造方法
{
}
返回值的数据类型 方法名称(参数1,参数2......) //零到多个方法
{
程序语句;
return表达式;
}
}
类中各个成员之间,定义的先后顺序没有任何影响。各成员可相互调用,但需要注意static修饰的成员不能访问没有static修饰的成员。
定义一个类后,就可以创建类的实例了,创建类实例通过new关键字完成。举个例子更好理解:
运行结果:
在ColorDefine这个类中,在第5行定义一个String类型的属性color,并赋初值“黑色”。在第6至9行定义了一个普通的方法getMes(),其完成的功能是向屏幕输出字符串“定义类”。第10到15行定义了一个公有访问的静态方法——main方法。在main方法中,代码第12行定义了ColorDefine的对象b,第13行输出了对象b的数据成员color,第14行调用了对象的方法getMes()。
3. 类的属性
类的属性是变量,定义语法如下:
[修饰符] 属性类型 属性名=[默认值]
通过实例来理解类的属性:
public class lianxi6
{
static Stringa="string-a";
static Stringb;
Stringc="string-c";
Stringd;
//static 语句块用于初始化static成员变量,是最先运行的语句块
static
{
printStatic("before static");
b="string-b";
printStatic("after static");
}
//输出静态成员变量
public static void printStatic(String title)
{
System.out.println("------"+title+"------");
System.out.println("a=\""+a+"\"");
System.out.println("b=\""+b+"\"");
}
public lianxi6()
{
print("before constructor");
d="string-d";
print("after conctructor");
}
//打印所有属性,包括静态成员
public void print(String title)
{
System.out.println("------"+title+"------");
System.out.println("a=\""+a+"\"");
System.out.println("b=\""+b+"\"");
System.out.println("c=\""+c+"\"");
System.out.println("d=\""+d+"\"");
}
public static void main(String[] args)
{
System.out.println();
System.out.println("------创建lianxi6对象");
System.out.println();
new lianxi6();
}
}
运行结果:
4. 对象的声明与使用
对象的声明
由类产生对象的基本形式:
类名 对象名=new 类名();
下面为例句:
person p1; //先声明一个person类对象p1
p1=new person(); //用new关键字实例化person的对象p1
person p1=new person(); //声明person对象p1并直接实例化此对象
对象的使用
如果要访问对象里的某个成员或方法,可以通过以下语法:
对象名称. 属性名 //访问属性
对象方法. 方法名 //访问方法
例如,想访问person类中的name和age属性,可以用以下方法访问:
p1.name; //访问person类中的name属性
p1.age; //访问person类中的age属性
若想将对象的属性赋值,则可以用以下例句:
p1.name="张三";
p1.age="24";
如果想调用person中的talk()方法,可以用以下写法:
p1.talk(); //调用person类中的talk()方法
切勿“纸上谈兵”,所以还是得敲代码,下面是使用person类的对象调用类中的属性与方法的过程的例子:
运行结果:
小知识点
“==”是比较对象内存地址值(即所谓的引用值)的,而“equals”是比较对象内容的。
对象数组的使用
用new 产生新的对象,并分配内存给它。
例如,要创建3个person类型的数组元素,语法如下:
person p[ ]; //声明person类类型的数组变量
p=new person[3]; //用new分配内存空间
创建好数组元素之后,便可把数组元素指向由person类所定义的对象。
p[0]=new person();
p[1]=new person();
p[2]=new person();
或者用静态方式来初始化对象数组:
person p[ ]={new person(),new person(),new person()}
下面是用静态方式初始化对象数组的例子: