一、对象
要想使用对象,必须先构造对象,并指定其初始状态
在 Java 中,使用构造器来构造并初始化对象
- 构造器是一种特殊的方法
- 构造器的名字与类名相同
- 用 new 操作符构造对象
new Date() //对象,并被初始化为当前的日期和时间
System.out.println(new Date()); //将这个对象传递给println方法
String s = new Date().toString(); ////Date类中有一个toString方法:返回日期的字符串描述
希望构造的对象可以多次使用,需要将对象存放在一个变量中
Date birthday = new Date();//birthday 为对象变量
一个对像变量并没有实际包含一个对象,而仅仅引用一个对象
//这里仅仅只是定义了一个Date类型的对象变量,不能调用方法
Date deadline;
//现在,这两个变量引用同一个对象
Date deadline = new Date();
Date birthday = new Date();
deadline = birthday;
二、类
1、预定义类:这里主要使用Java类库中的LocalDate类举例
Date 类:表示时间点
LocalDate 类:表示日历
注意:不要使用构造器来构造LocalDate 类的对象,使用静态工厂方法代表你调用构造器
LocalDate.now(); //构造一个新对象
LocalDate.of(1999,12,31); //提供年、月、日构造特定日期的对象
LocalDate date= LocalDate.of(1999,12,31) //将构造的对象保存在对象变量中
int year = date.getYear(); //1999
int month = date.getMonthValue(); //12
int today = date.getDayOfMonth(); //31
plusDays和minusDays方法
LocalDate dateLater = date.plusDays(1000);//生成当前日期之后1000天的日期
LocalDate dateLater = date.minusDays(1000);//生成当前日期之前1000天的日期
更改器方法与访问器方法:简单理解就是 set 方法和 get 方法,一个改变对象,一个只是访问对象。
注意:不要编写返回引用可变对象的访问器方法。
2、用户自定义类:
package employeetest;
import java.time.*;
public class EmployeeTest {
public static void main(String[] args) {
//构造一个Employee数组并填入三个雇员对象
Employee[] staff = new Employee[3];
staff[0] = new Employee("A",75000,1987,12,15);
staff[1] = new Employee("B",50000,1989,10,1);
staff[2] = new Employee("C",40000,1990,3,15);
//调用raiseSalary方法将每个人的薪水提高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) {
//this表示隐式参数,形参表示显式参数,即为了区分显式参数和隐式参数
double raise =this.salary * byPercent / 100;
this.salary +=raise;
}
}
- 构造器总是伴随着new 操作符的执行被调用,以便将实例域初始化所希望的状态
- 每个类可以有一个以上的构造器
- 构造器可以有0个、1个或多个参数
- 构造器没有返回值
3、隐式参数与显示参数:关键字 this 表示隐式参数,将实例域与局部变量明显的区分开来
比如上面的构造器可以这样写:
public Employee(String n,double s,int year,int month,int day) {
this.name = n;
this.salary = s;
this.hireDay = LocalDate.of(year,month,day);
}
4、final 实例域:
private final String name;//说明name域不会再被修改,即没有setName方法
三、静态域与静态方法
- 静态域(又称类域):将域定义为 static ,每个类中只有一个这样的域,
private static int nextId = 1;
它属于类,不属于任何一个独立的对象,是大家所共有的。
- 静态常量
public static final double PI = 3.14159265358979323846;
可以采用Math.PI的形式获得这个常量
如果关键字 static 被省略,PI就变成了Math类的一个实例域,需要通过Math类对象访问PI
- 静态方法
- 不能操作对象,也不需要使用是对象调用静态方法,即没有 this 参数
- 只能访问自身类中的静态域
//静态方法
public static int getNextId(){
return nextId;
}
//通过类名调用这个方法
int n = Employee.getNextId();
如果省略关键字 static ,则需要通过类对象的引用来调用这个方法,但是不建议。
- main 方法:
- main 方法也是一个静态方法,不对任何对象进行操作
- 静态的 main 方法将执行并创建程序所需要的对象
四、方法参数
在Java中总是采用按值调用,而不是引用调用
- 一个方法不能修改一个基本数据类型的参数(即数值型或布尔型)
public static void tripValue(double x){
x = x * 3;
}
//调用这个方法
double percent = 10;
tripleValue(percent);
//percent的值并没有改变,还是10
- 一个方法可以改变一个对象参数的状态
public static void tripleSalary(Employee x){
x.raiseSalary(200);
}
//调用方法
harry = new Employee(...);
tripleSalary(harry);
//通过对象引用作为参数,对象的状态就改变了
- 一个方法不能让对象参数引用一个新的对象
Employee a = new Employee("A", . . .);
Employee b = new Employee("B", . . .);
swap(a, b);//无变化
Employee temp = x;
x = y;
y = temp;
//无变化
五、对象构造
1. 重载:Java允许重载任何方法
- 同一个类
- 方法名相同
- 参数列表不同
方法签名:方法名及参数的类型,返回类型不是方法签名的一部分
2. 默认域初始化
- 构造器中没有显示地给域赋初值,默认的数值为0,布尔值为false,对象引用为null
3. 无参数的构造器
如果在编写类是没有写构造器,那么系统会自动提供一个无参数构造器,其中
所有的实例域设置为默认值。
public Employee(){
}
//所有域都被赋予默认值
如果类中至少提供了一个构造器,但没有提供无参的,则在构造对象时没有提供参数不合法
public Employee(String n,double s) {
name = n;
salary = s;
}
Employee e = new Employee();//false
Employee e = new Employee(“A”,10000);//true
4、显示域初始化
//直接赋值
private String name = "A";
//调用方法对域初始化
private static int nextId;
private int id = assignId();
...
private static int assignId(){
int r = nextId;
nextId++;
return r;
}
5、参数名 :通常在参数前加 “ a ”,或者不加,直接用 this 区分
public Employee(String aName, double aSalary){
name = aName;
salary = aSalary;
}
//或者
public Employee(String Name, double Salary){
this.name = Name;
this.salary = Salary;
}
6、调用另一个构造器
形如 this():调用同一个类的另一个构造器,且永远作为构造器的第一条语句,没有的话默认是super。
this 本身表示对当前对象的引用
public Employee(String n, double s) {
name = n;
salary = s;
}
public Employee(double s) {
this("" + nextId, s);//调用了上面的Employee构造器,即String name
}
7、初始化块
首先运行初始化块,再运行构造器的主体部分
- 对象初始化块
- 静态域初始化块
- 实例域初始化块
class Employee{
private static int nextId;
private int id;
private String name = "";//实例域初始化块
private double salary;
//使用静态的初始化块来对静态域进行初始化
static {
Random generator = new Random();
nextId = generator.nextInt(10000);
}
//对象初始化块
{
id = nextId;
nextId++;
}