Chapter 4 Objects and Classes
1. Introduction to Object-Oriented Programming(面向对象编程)
2. using Predefined Classes
3. Defined Your Own Classes
4. Static Fileds and Methods
5. Method Parameters
6. Objects Construction
7. Packages
8. The Class Path
9. Documentation Comments
10. Class Design Hints
1. Introduction to Object-Oriented Programming
Object-oriented programming, or OOP for short, is the dominant(占主导位置的) programming paradigm these days.
An object-oriented program is made of objects. Each object has a specific functionality, exposed to its users, and a hidden implementation. Many
objects in your programs will be taken “off-the-shelf”(下架) from a library; others will be custom-designed. Whether you build an object or buy it might
depend on your budget or on time. But, basically, as long as an object satisfies your specifications, you don’t care how the functionality is
implemented.
1.1 Classes
A class is the template(模板) or blueprint(蓝图,设计图) from which objects are made.
When you construct(构造) an object from a class, you are said to have created an instance(实例) of the class.
Encapsulation(封装) is a key concept in working with objects. Encapsulation is simply combining data and behavior in one package and hiding
the implementation details(实现的细节) from the users of the object.
The bits of data in an object are called its instance fields, and the procedures that operate on the data are called its methods.
When you start writing your own classes in Java, another tenet(教义) of OOP will make this easier: Classes can be built by extending other
classes. When you extend an existing class, the new class has all the properties and methods of the class that you extend. You then supply new methods
and data fields that apply to your new class only. The concept of extending a class to obtain another class is called inheritance.
1.2 Objects
To work with OOP, you should be able to identify three key characteristics of objects:
1. The object’s behavior—What can you do with this object, or what methods can you appley to it?
2. The object's state—How does the object react when you invoke those methods?
3. The object’s identity—How is the object distinguished from others that may have the same behavior and state?
1.3 Identifying Classes
1.4 Relationships between Classes
The most common relationship between classes are
1>Dependence("uses-a")
2>Aggregation("has-a")
3>Inheritance("is-a")
2. Using Predefined Classes
Take, for example, the Math class. You have seen that you can use methods of the Math class, such as Math.random, without needing to
know how they are implemented—all you need to know is the name and parameters (if any). That’s the point of encapsulation, and it will
certainly be true of all classes. But the Math class only encapsulates functionality; it neither needs nor hides data. Since there is no data, you do not
need to worry about making objects and initializing their instance fields—there aren’t any!
2.1 Objects and Object Variables
To work with objects, you first construct them and specify their initial state. Then you apply methods to the objects.
To construct a Date object, you combine the constructor with the new operator, as follows:
new Date()
This expression constructs a new object. The object is initialized to the current date and time.
Here is how you would apply the toString method to a newly constructed Date object:
String s = new Date().toString();
The constructed object is used only once. Usually, you will want to hang on to the objects that you construct so that you can keep using them.
Simply store the object in a variable:
Date birthday = new Date();
This statement has two parts. new Date() makes an object of type Date , and its value is a reference to that newly created object. The
reference is then stored in the deadline variable.
3. Defined Your Own Classes
3.1 An Employee Class
The Simplest form for a class definition in Java is
class ClassName{ field1 filed2 ... constructor1 constructor2 ... method1 method2 ... }
For example,version of an Employee class that might be used by a business in writing a payroll(薪水账册) system
1 class Employee{ 2 //instance fileds 3 private String name; 4 private double salary; 5 private Date hireDay; 6 7 //constructor 8 public Employee(String n, double s, int year, int month, int day){ 9 name = n; 10 salary = s; 11 GregorianCalendar calendar = new GregorianCalendar(year,month-1,day); 12 hireDay = calendar.getTime(); 13 } 14 15 //a method 16 public String getName(){ 17 return name; 18 } 19 }
Following program shows the Employee class in action
1 import java.util.*; 2 3 public class EmployeeTest{ 4 public static void main(String[] args) { 5 Employee[] staff = new Employee[3]; 6 staff[0] = new Employee("zhangsan",75000,1987,12,15); 7 staff[1] = new Employee("lisi",50000,1989,10,1); 8 staff[2] = new Employee("wangwu",40000,1990,3,12); 9 10 // raise everyone's salary by 5% 11 for (Employee e : staff) 12 e.raiseSalary(5); 13 // print out information about all Employee objects 14 for (Employee e : staff) 15 System.out.println("name=" + e.getName() + 16 ",salary=" + e.getSalary() + 17 ",hireDay=" + e.getHireDay()); 18 } 19 20 static class Employee{ 21 //instance fileds 22 private String name; 23 private double salary; 24 private Date hireDay; 25 26 //constructor 27 public Employee(String n, double s, int year, int month, int day){ 28 name = n; 29 salary = s; 30 GregorianCalendar calendar = new GregorianCalendar(year,month-1,day); 31 hireDay = calendar.getTime(); 32 } 33 34 //a method 35 public String getName(){ 36 return name; 37 } 38 39 public double getSalary(){ 40 return salary; 41 } 42 43 public Date getHireDay() 44 { 45 return hireDay; 46 } 47 48 public void raiseSalary(double byPercent){ 49 double raise = salary * byPercent / 100; 50 salary += raise; 51 } 52 } 53 }
In the program,we construct an Employee array and fill it with three employee objects
1 Employee[] staff = new Employee[3]; 2 staff[0] = new Employee("zhangsan",75000,1987,12,15); 3 staff[1] = new Employee("lisi",50000,1989,10,1); 4 staff[2] = new Employee("wangwu",40000,1990,3,12);
Next, we use the raiseSalary method of the Employee class to raise each employee’s salary by 5%:
Finally, we print out information about each employee, by calling the getName, getSalary, and getHireDay methods:
3.2 Use of Multiple Source Files
Many programmers prefer to put each class into its own source file. For example, you can place the Employee class into a file Employee.java
and the EmployeeTest class into EmployeeTest.java.
There is a small difference, in Employee.java, we don not have to write a static before class Employee
3.3 Dissecting(解剖) the Employee Class
this class has one constructor and four methods
public Employee(String n, double s, int year, int month, int day) public String getName() public double getSalary() public Date getHireDay() public void raiseSalary(double byPercent)
All methods of this class are tagged as public. The keyword public means that any method in any class can call the method.
You could use the public keyword with your instance fields, but it would be a very bad idea. Having public data fields would allow any part
of the program to read and modify the instance fields, completely ruining encapsulation. Any method of any class can modify public
fields—and, in our experience, some code will take advantage of that access privilege when you least expect it. We strongly recommend to make all
your instance fields private.
3.4 First Steps with Constructors(构造函数)
//constructor public Employee(String n, double s, int year, int month, int day){ name = n; salary = s; GregorianCalendar calendar = new GregorianCalendar(year,month-1,day); hireDay = calendar.getTime(); }
As you can see, the name of the constructor is the same as the name of the class. This constructor runs when you construct objects of
the Employee class giving the instance fields the initial state you want them to have.
For example, when you create an instance of the Employee class with code like this:
new Employee("James Bond", 100000, 1950, 1, 1)
you have set the instance fields as follows:
name = "James Bond"; salary = 100000; hireDay = January 1, 1950;
There is an important difference between constructors and other methods. A constructor can only be called in conjunction with the new
operator. You can’t apply a constructor to an existing object to reset the instance fields. For example,
james.Employee("James Bond", 250000, 1950, 1, 1) // ERROR
We will have more to say about constructors later in this chapter. For now, keep the following in mind:
• A constructor has the same name as the class. • A class can have more than one constructor. • A constructor can take zero, one, or more parameters. • A constructor has no return value. • A constructor is always called with the new operator.
3.5 Implicit(隐式) and Explicit(显式) Parameters
Methods operate on objects and access their instance fields
public void raiseSalary(double byPercent) { double raise = salary * byPercent / 100; salary += raise; }
the method sets a new value for the salary instance field in the object on which this method is invoked(请求)
the explicit parameters are explicitly listed in the method declaration, for example, double byPercent.
the implicit parameter does not appear in the method declaration. for example, salary
In every method, the keyword this refers to the implicit parameter. If you like, you can write the raiseSalary method as follows:
1 public void raiseSalary(double byPercent) 2 { 3 double raise = this.salary * byPercent / 100; 4 this.salary += raise; 5 }
3.6 Benefits of Encapsulation
3.7 Class-Based Access Privileges
3.8 Private Methods
When implementing a class, we make all data fields private because public data are dangerous.
3.9 Final Instance Fields
You can define an instance field as final. Such a field must be initialized when the object is constructed. the field may not be modified again. For
example, the name field of the Employee class may be declared as final because it never changes after the object is constructed—there is no
setName method.
4. Static Fields and Methods
4.1 Static Fileds
If you define a field as static, then there is only one such field per class.We add an instance field id and a static field nextId to the Employee
class:
class Employee { private static int nextId; pirvate int id; }
Every employee object now has its own id field, but there is only one nextId field that is shared among all instances of the class.
Let’s implement a simple method
public void setId() { id = nextId; nextId++; }
Suppose you set the employee identification number for harry:
harry.setId();
Then, the id field of harry is set to the current value of the static field nextId, and the value of the static field is incremented.
4.2 Static Constants
As we mentioned several times, it is never a good idea to have public fields, because everyone can modify them. However, public constants
(that is, final fields) are fine.
4.3 Static Methods
Static methods are methods that do not operate on objects
You can think of static methods as methods that don’t have a this parameter.
Since static methods don’t operate on objects, you cannot access instance fields from a static method. However, static methods can access the
static fields in their class. Here is an example of such a static method:
public static int getNextId() { return nextId; }
To call this method,you supply the name of the class
int n = Employee.getNextId();
It is legal to use an object to call a static method. For example, if harry is an Employee object, then you can call harry.getNextId() instead of
Employee.getnextId().
4.4 The main Method
Note that you can call static methods without having any objects. For the same reason, the main method is a static method.
1 public class Application 2 { 3 public static void main(String[] args) 4 { 5 // construct objects here 6 . . . 7 } 8 }
The main method does not operate on any objects. In fact, when a program starts, there aren’t any objects yet. The static main method
executes, and constructs the objects that the program needs.
5. Method Parameters