大可制作:QQ群:31564239(asp|jsp|php|mysql)

Java Gossip: 使用类(Class)定义对象

对象导向设计中,对象并不是凭空产生的,您必须先定义您的对象,您要一个规格书,这个规格书称之为类(Class)

在Java中使用"class"关键字来书写类(规格书),您使用类来定义一个对象(object)时,您考虑这个对象可能拥有的“属性”(Property,在Java中则是用Field)“方法”(Method)。属性是参与对象内部运算的数据成员,而方法则是对象与外界互动的动态操作。

您使用类定义出对象的规格书,之后根据这个规格书来建构对象,然后透过对象所提供的操作接口来与程序互动。

举个例子来说,您可以定义一个对象:“球”。

考虑球有各种不同的颜色(或名称),以及球最基本的球半径信息,您想到这些信息应该可以取得,并可以进一步取得球的体积,当您在Java中要定义这些信息时,您可以如下进行定义:

  • Ball.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();
ball1.setName("GBall");

以下先看个简单的程序:

  • SimpleClass.java
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成员的作用范围离开了对象之外。