Java学习–类与对象

基础

首先要区分对象和对象变量:

Date deadline;//这是一个对象变量
new Date()//这是一个对象

对象变量在没有引用对象的时候是无法使用任何Date方法,如果对它进行初始化或者设置这个变量:

deadline = new Date();
deadline = birthday;

那么这个对象变量就引用了一个对象,注意这里是引用而不是包含。在Java中,任何对象变量的值都是对存储在另外一个地方的某个对象的引用。new操作符的返回值也是一个引用。(所有的Java对象都存储在堆中,当一个对象包含另一个对象变量时,它只是包含着另一个对、堆对象的指针)

静态工厂方法

不通过 new,而是用一个静态方法来对外提供自身实例的方法,即为我们所说的静态工厂方法(Static factory method)。
先留个坑,等学会了再来补。

更改器方法

调用后改变对象状态的方法。

访问器方法

只访问对象而不修改对象的方法有时称为访问器方法。

实现一个类

源文件名为EmployeeTest.java,这是因为文件名必须与public类的名字相匹配,在一个源文件中,只能有一个公共类,可以有任意多个非公共类。
实例字段强烈建议使用private,访问这些字段可以通过提供的方法去访问。

import java.time.*;

/**
 * This program tests the Employee class.
 * @version 1.13 2018-04-10
 * @author Cay Horstmann
 */
public class EmployeeTest
{
   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 LocalDate hireDay;
   public Employee()
   {
      this("Default", 1000.3, 2014, 12, 13);
      //调用其他构造方法
   }
   public Employee(String n, double s, int year, int month, int day)
   {
   	  /*
   	  static{
   	  静态初始化块,类加载时隐式调用
   	  }
   	  {
   	  普通初始化块,创建对象时隐式调用
   	  }
   	  */
      //name = Objects.requireNonNullElse(n, "unknown");
      //Objects.requireNonNull(n, "The name cannot be null!");
      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;
   }
}
多个源文件

一般习惯将一个类放到单独的一个文件中,如果这样组织文件,可以有两种编译源程序的方法:
使用通配符调用Java编译器:

javac Employee*.java

这样一来,所有与通配符匹配的源文件都将被编译成类文件。
或者:

javac EmployeeTest.java

java编译器发现EmployeeTest.java使用了Employee类时,会查找名为Employee.class文件,没有找到就会找对应的java文件,然后进行编译。同时如果Employee.java版本较class文件版本更新的话,就会自动进行重新编译。

final实例字段

就像声明一个变量一样,加上final修饰符就会使得这个字段变成一个常量。但有一点需要注意,如果final修饰的是一个可变的类对象,由于实际上Java中的对象实际是对象的引用,那么final只是保证这个引用不会更改为引用其他的对象,但它本身引用的对象的具体内容还是可以变化的。