初学者编写一个只包含main方法的单一类,是一个很小但是完整的程序。这样的程序通常使用Java类库中预定义的类来实例化对象,然后使用这些对象提供的服务。尝试编写新的程序,用到的类不完全是Java类库中预定义的,还需要自己编写新的类并定义类的对象完成的服务。面向对象软件设计的基本部分是确定程序中应该创建哪些类,这些类决定了系统中要管理的对象,要仔细考虑应如何表示组成系统的各个元素。在设计的初期就要为每个类分配职责,并考虑如何将这些任务转为具体的方法。
面向对象程序设计的核心是类的定义,它代表定义了状态和行为的对象。
public class SnakeEyes {
public static void main(String[] args) {
final int ROLLS = 500; //投掷次数,定义为常量
int num1,num2,count = 0;
Die die1 = new Die();
Die die2 = new Die(); //生成两个Die类的新对象
for(int roll = 1; roll <= ROLLS; roll++)
{
num1 = die1.roll();
num2 = die2.roll(); //使用Die类中定义的roll方法,即模拟随机投掷骰子
if(num1==1 && num2==1) //出现“蛇眼”即两个骰子均为1的情况
count++;
}
System.out.println("Number of rolls:" + ROLLS);
System.out.println("Number of snake eyes:" + count);
System.out.println("Ratio:" + (float)count/ROLLS);
}
}
示例中的Die类不是Java类库中预定义的,为了能让这个程序能编译并运行,我们就要自己编写Die类,并定义需要Die对象完成的服务。
public class Die {
private final int MAX = 6; //声明私有常量,最大投掷点数6
private int faceValue; //声明私有变量,骰子当前的面值
public Die() //定义Die类对象的构造方法,为对象生成一个新的faceValue值。
{
faceValue = 1; //faceValue就是Die对象的属性
}
public int roll() //有返回值faceValue,定义方法的返回值为int类型
{
faceValue = (int)(Math.random()*MAX) + 1;
// 生成0~1(不含)内的随机数,乘以6,为0~6(不含)内随机数,加1并向下取整,为1~6的整数。
return faceValue;
}
}
类可以包含数据声明和方法声明。数据声明代表类的每个对象中保存的数据,方法声明定义了对象提供的服务。类的数据和方法都称为类的成员(member)。
Die对象在任一时刻都显示一个具体的面值,这个值可以称为骰子的状态,而方法就定义了骰子的行为或动作。显然,在这个类中我们还可以定义一些别的方法来为投骰子的实例提供更多的服务,例如设置点数(将骰子的某一面朝上),返回当前的点数等。
在上一段代码的Die类中补充以下几个方法
public void setFaceValue(int Value) // 该方法输入整型Value,无输出(void)
{
if(Value > 0 && Value <= MAX)
faceValue = Value;
}
//设置骰子的点数为一个具体的整数
public int getFaceValue() //该方法没有输入,直接返回同属于Die类内的整型变量faceValue
{
return faceValue;
}
//返回骰子当前的点数
public String toString() //toString方法在Die类内的重写以实现具体的服务
{
String result = Integer.toString(faceValue);
return result;
}
//返回表示骰子当前点数的字符串
在将对象传递给print或者println方法,,以及将一个对象与一个字符串连接时,都会自动调用Object类中的toString方法。Object类是所有类的父类,每个类都直接或间接的继承自该类,所以任何类中都可以直接使用Object类中定义的方法。默认的方法通常得到的结果没有太大用处,所以最好自己定义所创建类的toString方法。
在Die类中,常量MAX和变量faceValue都是在类中声明的,而不是在某个方法中声明的。变量声明的位置定义了它的作用域(scope),作用域是指程序中能应用变量的区域。在类一级(而非在方法内)声明的变量和常量可以在类的任意方法内引用。
变量faceValue这样的成员称为实例数据(instance data)每次创建类的一个实例时都为这样的变量分配新的内存空间。所以Die类的每个对象都有自己的faceValue变量并有自己的数据空间,这也是每个对象可以保存自己状态的原因。
Java为类中声明的每个变量自动进行初始化。例如,所有的数据类型变量初始化为0,如int和double类型。不过,虽然语言能自动完成初始化工作,好的编程习惯还是要显式初始化变量(通常在构造方法中进行),以便阅读代码的人能明确了解代码意图。