用户定义类是大部分复杂程序所需要的主力类(workhorse class)。通常,这些类没有mian方法,却有自己的实例字段和实例方法。要想构建一个完整的程序,会结合使用多个类,其中只有一个类有main方法。
一、Employee类
在Java中,最简单的类定义形式为:
class ClassName
{
field1
field2
...
constructor1
constructor2
...
method1
method2
...
}
下面看一个非常简单的Employee类。在编写工资管理系统可能会用到。
class Employee
{
//实例字段
private String name;
private double salary;
private LocalDate hireDay;//定义了私有方法
//构造函数
public Employee(String n,double s,int year,int month,int day){
name = n;
salary = s;
hireDay = LocalDate.of(year,month,day);
}
//定义一个方法
public String getName()
{
return name;
}
//其他方法
}
这里创建了一个实例,接下来的部分都将由这一个程序实现。(可以大致看一看,后面会有详细的分解)
import java.time.*;
public class EmployeeTest {
public static void main(String[] args) {
//三个员工填充职员数组
Employee[] staff = new Employee[3];
staff[0] = new Employee("Carl Cracker", 75000, 1994, 12, 15);
staff[1] = new Employee("Harry Hacker", 50000, 1990, 10, 1);
staff[2] = new Employee("Tony Tester", 40000, 1997, 3, 15);
//每人工资提高5%
for (Employee e : staff)
e.raiseSalary(5);
//打印出职员信息
for (Employee e : staff)
System.out.println("name:" + e.getName() + ",salary:" + e.getSalary() + ",hireDay:" + e.getHireDay());
}
}
class Employee {
private String name;
private double salary;
private LocalDate hireDay;
public Employee(String n,double s,int year,int month,int day){
name = n;
salary = s;
hireDay = LocalDate.of(year,month,day);
}
public String getName()
{
return name;
}
public double getSalary()
{
return salary;
}
public LocalDate getHireDay()
{
return hireDay;
}
public void raiseSalary(double byPercent){
double raise =salary*byPercent/100;
salary+= raise;
}
}
在这个程序中我们构造了一个Employee数组,并填入了3个Employee对象:
staff[0] = new Employee("Carl Cracker", 75000, 1994, 12, 15);
staff[1] = new Employee("Harry Hacker", 50000, 1990, 10, 1);
staff[2] = new Employee("Tony Tester", 40000, 1997, 3, 15);
接下来,使用Employee类的raiseSalary方法将每个员工的薪水提高5%:
for (Employee e : staff)
e.raiseSalary(5);
最后调用getName方法、getSalary方法和getHireDay方法打印各个员工的信息:
for (Employee e : staff)
System.out.println("name:" + e.getName() +
",salary:" + e.getSalary() +
",hireDay:" + e.getHireDay());
(注意:这个程序设计包含了两个类,其中一个是包含mian方法的EmployeeTest,另一个是自定义Employee类)
源文件名是EmployeeTest.java,这是因为文件名必须与public类名字相同,一个源文件只能有一个公共类但是可以有任意数目的非公共类。
接下来当编译这段代码时,编译器将会在目录下创建两个类文件:EmployeeTest.class和Employee.class。
将程序中包含main方法的类名提供给字节码解释器,以启动这个程序:
java EmployeeTest
字节码解释器开始运行EmployeeTest类的main方法中的代码。在这段代码中,先后构造了3个新Employee对象,并显示它们的状态。
二、多个源文件的使用
在上述程序中,一个源文件包含了两个类。我们也可以将每一类存放在一个单独的源文件中。例如将EmployeeTest类放入EmployeeTest.java,将Employee类放入Employee.java中。
如果喜欢这样组织文件,可以有两种编译源程序的方法。一种是使用通配符调用Java编译器:
javac Employee*.java
这样一来,所有与通配符匹配的原文件都将编译成类文件。或者键入以下命令:
javac EmployeeTest.java
当Java编译器发现EmployeeTest.java使用了Emplyee类,会查找Employee.class,如果查不到就会自动寻找Java文件,然后对它进行编译。
三、剖析Employee类
下面各节将对Employee类进行剖析。首先从类方法开始。通过查看源代码会发现,这个类包含一个构造器和4个方法:
public Employee(String s,double s,int year,int month,int day)
public String getName()
public double getSalary()
public LocalDate getHireDay()
public void raiseSalary(double byPercent
这个类的所有方法都被标记为public。关键字public表示为任何类的任何方法都可以调用。然而我们要注意Employee类自身的方法中private只能被自身类访问,其他类不能访问。
private String name;
private double salary;
private LocalDate hireDay;
最后注意。有两个实例本身就是对象:name字段是String类对象,hireDay字段是LocalDate类对象。这种情况十分常见:类包含的实例字段通常属于某个类类型。
从构造器开始
下面先看Employee类的构造器:
public Employee(String n,double s,int year,int month,int day){
name = n;
salary = s;
hireDay = LocalDate.of(year,month,day);
}
可以看到构造体与类同名。在构造Employee类的对象时,构造器会运行,从而将实例字段初始化为所希望的初始状态。
例如,当使用下面这个代码创建Employee类实例时:
new Employee("James Bond",10000,1950,1,1)
将会把实例字段设置为:
name = "James Bond"
salary = 100000
hireDay = LocalDate.of(1950.1.1);//January 1,1950
构造器与其他方法有一个重要的不同。构造器总是结合new运算符来调用。不能对一个已经存在的对象调用构造器来达到重新设置实例字段的目的。例如,
James。Employee("James Bond",10000,1950,1,1)//ERROR
将产生编译错误。
构造器需记住的内容
- 构造器与类同名。
- 构造器可以有0个、1个或多个参数。
- 每个类可以有多个以上的构造器。
- 构造器没有返回值。
- 构造器总是伴随着new操作符一起调用。