面向对象程序设计概述
OOP把设计的重心放在了数据结构上,其次才是算法
类
某一些有共同状态和行为的模板
对象
- 对象的行为 ——可以对对象施加那些行为?
- 对象的状态 ——施加这些方法时,对象如何响应?
- 对象标识 ——如何分辨有相同行为与状态的不同对象?
对象的状态应该需要根据方法的调用而改变,体现封装性.
识别类
书中提到用名词和动词,区分参数和方法。
类之间的关系
- 依赖 (uses-a) 一个类的方法操纵另外一个类
- 聚合(has-a) 类A的对象包含类B的对象
- 继承(is-a) 类A在类B的扩展之上
使用预定义类
介绍Date类,如何构造对象,如何调用类的方法
对象和对象变量
构造一个对象,需要使用构造器(构造方法)构造新实例,构造器的名字应该与类名相同
new Date()// new 构造器
String s = new Date().toString();
System.out.println(s);//Mon Mar 13 22:02:34 GMT+08:00 2017
// birthday引用了新构造的变量
Date birthday = new Date();
书中指出,对象和变量对象有一个重要区别:
对象变量并没有包含一个对象,仅仅是引用了一个变量
Date deadline;
// String s = deadline.toString();// 错误!
deadline = new Date();//指向一个存在的对象
Java类库中的GregorianCalendar类
介绍了另一种表示日历对象的GregorianCalendar类
更改器方法和访问器方法
- get方法仅仅查看并返回状态的对象.
- set和add方法对对象进行了修改,对实例域做出了修改.
import java.text.DateFormatSymbols;
import java.util.*;
/**
* @version 1.4 2007-04-07
* @author Cay Horstmann
*/
public class Demo {
public static void main(String[] args) {
// construct d as current date
GregorianCalendar d = new GregorianCalendar();
int today = d.get(Calendar.DAY_OF_MONTH);
int month = d.get(Calendar.MONTH);
// set d to start date of the month
d.set(Calendar.DAY_OF_MONTH, 1);
int weekday = d.get(Calendar.DAY_OF_WEEK);
// get first day of week (Sunday in the U.S.)
int firstDayOfWeek = d.getFirstDayOfWeek();
// determine the required indentation for the first line
int indent = 0;
while (weekday != firstDayOfWeek) {
indent++;
d.add(Calendar.DAY_OF_MONTH, -1);
weekday = d.get(Calendar.DAY_OF_WEEK);
}
// print weekday names
String[] weekdayNames = new DateFormatSymbols().getShortWeekdays();
do {
System.out.printf("%4s", weekdayNames[weekday]);
d.add(Calendar.DAY_OF_MONTH, 1);
weekday = d.get(Calendar.DAY_OF_WEEK);
} while (weekday != firstDayOfWeek);
System.out.println();
for (int i = 1; i <= indent; i++)
System.out.print(" ");
d.set(Calendar.DAY_OF_MONTH, 1);
do {
// print day
int day = d.get(Calendar.DAY_OF_MONTH);
System.out.printf("%3d", day);
// mark current day with *
if (day == today)
System.out.print("*");
else
System.out.print(" ");
// advance d to the next day
d.add(Calendar.DAY_OF_MONTH, 1);
weekday = d.get(Calendar.DAY_OF_WEEK);
// start a new line at the start of the week
if (weekday == firstDayOfWeek)
System.out.println();
} while (d.get(Calendar.MONTH) == month);
// the loop exits when d is day 1 of the next month
// print final end of line if necessary
if (weekday != firstDayOfWeek)
System.out.println();
}
}
用户自定义类
多数情况下,一个程序将若干个类组合在一起,其中只有一个main方法
Employee类
书中创建了一个employee类
import java.util.*;
/**
* This program tests the Employee class.
* @version 1.11 2004-02-19
* @author Cay Horstmann
*/
public class Demo{
public static void main(String[] args)
{
// fill the staff array with three Employee objects
Employee[] staff = new Employee[3];
staff[0] = new Employee("Carl Cracker", 75000, 1987, 12, 15);
staff[1] = new Employee("Harry Hacker", 50000, 1989, 10, 1);
staff[2] = new Employee("Tony Tester", 40000, 1990, 3, 15);
// raise everyone's salary by 5%
for (Employee e : staff)
e.raiseSalary(5);
// print out information about all Employee objects
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 Date hireDay;
public Employee(String n, double s, int year, int month, int day)
{
name = n;
salary = s;
GregorianCalendar calendar = new GregorianCalendar(year, month - 1, day);
// GregorianCalendar uses 0 for January
hireDay = calendar.getTime();
}
public String getName()
{
return name;
}
public double getSalary()
{
return salary;
}
public Date getHireDay()
{
return hireDay;
}
public void raiseSalary(double byPercent)
{
double raise = salary * byPercent / 100;
salary += raise;
}
}
多个源文件使用
当自解码器开始解析EmployeeTest时发现需要用到Employee类,就会自动寻找Employee.class,没有再去寻找Employee.java
剖析Employee类
- 一个构造器和4个方法
- 所有方法都使用public修饰
- 所有实例域都使用private修饰