一、基本概念

1、

类(class)构造(construct)对象(object)的过程称为创建类的实例(instance)

对象中的数据称为实例字段(instance field),操作数据的过程称为方法(method)

封装(encapsulation)是将数据和方法组合在一个包(package)中,并对对象的使用者隐藏具体的实现方法。

实现封装的关键是绝对不能让类中的方法直接访问其他类的实例字段,程序只能通过对象的方法与对象数据进行交互。

继承(inheritance)是通过扩展一个类来建立另一个类的过程。

2、

对象的三个主要特征:即对象的行为(behavior)、状态(state)、标识(identity)

类之间常见关系有:依赖、聚合、继承

3、对象与对象变量

java语言中要使用构造器(constructor)构造新的实例

Date brithday = new Date();
//等号的右边用构造器Date()创建了对象,用new操作符创建了一个对象的引用
//然后将Date的引用给了对象变量brithday
Date deadline;         
//该语句定义了一个对象变量deadline,他可以引用Date类型的对象,但他不是一个对象,且实际上也没有引用任何对象,此时还不能在该变量上使用任何方法Date的方法
S = deadline.toString();//该语句将产生编译错误
 对象变量的初始化:
        1、使用new操作符构造一个新的对象:Date brithday = new Date();
        2、引用一个已有变量: Date deadline = brithday;

对象变量没有实际包含一个对象,它只是引用了一个对象。在java任何对象变量的值都是对存储在另外一个地方的某个对象的引用。new操作符返回值也是一个引用。 

二、用户自定义类

例1:hello_world.java

public class hello_world{
    public static void main(String[] args){
        //法开始执行。所有的 Java 程序由 public static void main(String[] args) 方
        System.out.print("hello world");//此种打印方法不换行,下一个字符串紧跟"o"之后
        System.out.println("hello world");
        System.out.println("\u0041");
        System.out.println("\u1F37A");
    }
}

 以上定义了一个简单的类(hello_world),它只包含了一个main方法

例2:Employee.java

import java.lang.String;
import java.time.*;
public class EmployeeTest {
    public static void main(String[] args) {
        Employee[] staff = new Employee[3];
        staff[0] = new Employee("zhang",5000,2000,1,1);
        staff[1] = new Employee("wang",6000,1999,1,1);
        staff[2] = new Employee("li",7000,2002,1,1);
        for(Employee e:staff)
            e.raiseSalary(5);
        for(Employee e:staff)
            System.out.println("姓名:"+e.getName()+",工资为:"+e.getSalary()+",参加工作时间为:"+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){
        salary+= salary*byPercent/100;
    }
}

1、剖析EmployeeTest类:

 该实例中包含两个类:Employee类和带有public访问修饰符的EmployeeTest类。

 源文件名为EmployeeTest.java,文件名必须与public类的名字一致,在一个源文件中只能有一个公共类,但可以有多个非公共类。

当编译这段源代码时,编译器将在当前目录创建两个类文件:Employee.class和EmployeeTest.class

然后启动程序:java EmployeeTest

字节码解释器开始运行EmployeeTest类的main方法的代码。这段代码先后构造了三个Employee对象,并显示出他们的状态

2、剖析Employee类:

这个类定义了3个实例字段用于存放数据,关键字private确保只有Employee类自身的方法才能访问这些实例字段,而其他类的方法不能够访问。

private String name;
    private double salary;
    private LocalDate hireDay;

这个类包含了一个构造器与四个方法,所有方法都被标记为public。关键字public意味任何类的任何方法都可以调用这些方法(共有4种访问方法)

public Employee(String N,double S,int Year,int month,int day)
    public String getName()
    public double getSalary()    
    public LocalDate getHireDay()
    public void raiseSalary(double byPercent)

Employee类的构造器:

public Employee(String n,double s,int Year,int month,int day){
        name = n;
        salary = s;
        hireDay = LocalDate.of(Year,month,day);
    }

 构造器与类同名,在创建Employee类的对象时,构造器会运行从而初始化实例字段。

 构造器与其他方法有一个重要的不同是:构造器总是结合new运算符来调用。

注意:

1、构造器与类同名

2、每个类可以有一个以上的构造器

3、构造器可以无参数或多个参数

4、构造器无返回值

5、构造器总是伴随new操作符一起调用

6、不要在构造器中定义与实例字段同名的局部变量

三、变量及对象变量

1、用var声明局部变量

在java10中如果可以从变量的初始值推断出它的类型,那么可以用var关键字声明局部变量,而无需指定类型。

Employee harry = new Employee("zhang",5000,1999,10,1);

//也可用var进行声明

var harry = new Employee("zhang",5000,1999,10,1);

var关键字只能用于方法中的局部变量,参数与字段的类型必须声明。

 2、对象变量

对象变量有可能为null,如果对null值应用一个方法,会产生一个NullPointerException的异常,程序就会终止。

因此定义一个类时应该注意哪些字段可能为空,对此有两种解决办法:

“宽容型”方法把null转换为一个适当的非null值

if(n==null) name = "unknow";esle name = n;
在java9中,Objects类提供了一个检测的方法
name = Objects.requireNonNullElse(n,"unknow");

 “严格型”方法干脆拒绝null参数

Objects.requireNonNull(n,"this is name cannot be null");
name = n;

3、隐式参数与显式参数

对于raiseSalary方法

public void raiseSalary(double byPercent){
        salary+= salary*byPercent/100;
    }

 当调用这个对象的raiseSalary方法时:

staff[0].raiseSalary(10);

它的目的是将 staff[0]的salary字段增加10%,其实执行的是下列指令:

staff[0].salary+= staff[0].salary*byPercent/100;

 raiseSalary方法有两个参数,第一个参数为隐式参数,是出现在方法名前的Employee类型的对象。第二个参数是显式参数,位于方法名后的括号中的数值。

显式参数显式的列在方法的声明中,隐式参数没有出现方法的声明中。

4、封装的优点

public String getName(){
        return name;
    }
    public double getSalary(){
        return salary;
    }
    public LocalDate getHireDay(){
        return hireDay;
    }

这是典型的访问器的方法,由于它们只返回实例字段值,因此又被称为字段访问器。

其中name只是一个只读字段,一旦在构造器中设置,就无任何办法将其修改,这样可以确保name字段不会受到外界破坏

salary不是只读字段,但它只能用raiseSalary方法修改,若salary是公共字段,则难以调试。

若要获得或者设置实例字段的值,将需要提供下列三种内容

1、一个私有的数据字段

2、一个公共的字段访问器方法

3、一个公共的字段更改器方法

 这样可以改变相应字段的值且不会影响其他代码。

5、基于类的访问权限

一个方法可以访问所属类的所有对象的私有数据 

6、final实例字段

将实例字段定义为final,这些字段必须在构造对象时初始化,即在每一个构造器执行后,这个字段的值已设置,并且以后不能再修改这个字段

class Employe{
private final String name;
...
}

final修饰符用于类型为基本类型或不可变类的字段(类中的所有方法都不会改变其对象,这样的类为不可变的类,如String类)。