对象导向设计中,对象并不是凭空产生的,您必须先定义您的对象,您要一个规格书,这个规格书称之为类别(Class)。
在Java中使用"class"关键词来书写类别(规格书),您使用类别来定义一个对象(object)时,您考虑这个对象可能拥有的「属性」(Property,在Java中则是用Field)与「方法」(Method)。属性是参与对象内部运算的数据成员,而方法则是对象与外界互动的动态操作。
您使用类别定义出对象的规格书,之后根据这个规格书来建构对象,然后透过对象所提供的操作接口来与程序互动。
举个例子来说,您可以定义一个对象:「球」。
考虑球有各种不同的颜色(或名称),以及球最基本的球半径信息,您想到这些信息应该可以取得,并可以进一步取得球的体积,当您在Java中要定义这些信息时,您可以如下进行定义:
public class Ball { private double radius; // 半径 private String name;?// 名称 // 无参数建构方法 public Ball() { this(0.0, "no name"); } // 有参数建构方法 public Ball(double radius, String name) {? this.radius = radius; this.name = name; } public double getRadius() { return radius; } public String getName() { return name; } public void setRadius(double radius) { this.radius = radius; } public void setName(String name) { this.name = name; } }?
一个定义良好的类别,即使在不看程序代码实作的情况下,也可以从定义中所提供的公开(public)方法看出这个类别的大致功能。
"class"是Java中用来定义类别的关键词,Ball是您所取的类别名称,记得一个类别的定义是这么作的:
public class Ball { // 实作内容 }
在类别中的运算参与数据(Field)及互动方法(Method),我们统称其为 类别成员(Class member)。
上例中的radius、name成员是field成员,getRadius()与getName()是method成员。注意到"public"这个关键 字,它表示所定义的成员可以使用宣告的对象名称加上 '.' 运算子直接呼叫,也称之为「公用成员」或「公开成员」。而private这个关键词用来定义一个「私用成员」,它不可以透过参考名称直接呼叫,又称之为 「私有成员」。
在定义类别时,有一个基本原则是:信息的最小化公开。也就是说尽量透过方法来操作对象,而不是直接存取其内部运算参与数据(也就是field成员)。
信息的最小化公开原则是基于安全性的考虑,避免程序设计人员随意操作field成员而造成程序的错误,您可以在日后的程序设计中慢慢来体会;在稍后的实作中,您将可以看到,我们将不会radius与name两个私用成员直接进行存取,而是透过公开的方法来进行设定。
一个类别中的field成员,若宣告为"private",则其可视范围(Scope)为整个类别,由于外界无法直接存取私用成员,所以您使用两个公开方法 getRadius()与getName()分别传回其这两个成员的值。
与类别名称同名的方法称之为 建构方法 Cconstructor),也有人称之为「建构子」,它没有传回值。顾名思义,建构方法的作用是让您建构对象可以设定一些必要的建构信息,它可 以被重载(Overload),以满足对象生成时不同的设定条件。
您在实作中重载了建构方法,在不指定参数的情况下,会将radius设定为0.0,而name设定为 "no name",另一个建构方法则可以指定参数,this()方法用于对象内部,表示呼叫对象的建构方法,另一个就是this,它表示对象本身,您可以在 关于 this 进一步了解其作用。
定义好类别之后,您就可根据这个类别(规格)来建构对象,建构对象时使用new关键词,顾名思义,就是根据所指定的类别(规格书)「新建」一个对象:
Ball ball1 = new Ball(); Ball ball2 = new Ball(3.5, "red ball");
在上例中配置了ball1与ball2两个对象,ball1对象在建立时并不指定任何参数,所以根据之前对Ball类别的定义,ball1的radius 将设定为0.0,name设定为"no name";ball2则给定两个参数,所以ball2的radius设定为3.5,而ball2的name设定为"red ball"。
您可以透过公开成员来操作对象或取得对象信息,方法是使用对象名称加上「.」运算子,例如:
ball1.getRadius(0.1); ball1.setName("GBall");
以下先看个简单的程序:
public class SimpleClass { public static void main(String[] args) { Ball b1 = new Ball(18.4, "red ball"); System.out.println("名称: " + b1.getName()); System.out.println("半径: " + b1.getRadius()); } }
执行结果:
名称: red ball 半径: 18.4
类别与对象这两个名词会经常混于书籍与文件之中,例如「您可以使用Scanner类别」、「您可以使用Scanner对象」,这两句在某些场合其语义是相 同的,不过要细究的话,两句的意思通常都是「您可以使用根据Scanner类别所建构出来的对象」,不过写这么长很烦,难免就省略了一些字眼。
Java会将参与内部运算的数据命名为field,其实是蛮有道理的,field在英文中有事件的参与者的意义,有限定范围的意思。基本上,在定义对象 时,field成员其作用范围要限定于对象之中,对对象内部数据的变更,都要透过公开方法来进行,避免field成员的作用范围离开了对象之外。