作用

  1. 区分、管理同名类
  2. 控制访问范围

    包名规则

    通常为域名反转,如com.google.···

    基本语法

    1. // 打包
    2. package 包名;
    3. // 导包
    4. import 包名;

    本质

    创建不同的文件夹/目录管理类文件。

    Java 提供的常用包

    1. java.lang.*; // 基本包,默认引入
    2. java.util.*; // 工具包,包含各种工具类,如 Scanner
    3. java.net.*; // 网络包,网络开发
    4. java.awt.*; // GUI 开发

    建议 使用到哪个类就导哪个包,不建议
    *细节

  3. 一个类只能有一个 package且只能放在类文件最上方。

  4. import不限数量,在 package下方。

    访问修饰符

    用于控制类、方法和属性的访问权限。
    image.png
    注意 只有默认(default)和 public才能修饰类。

    面向对象三大特征

  • 继承
  • 封装
  • 多态

    继承

    必须满足 is-a 关系:我是一个人
    解决代码复用性问题:多个类存在相同属性、方法时,将其抽取并封装为一个类——父类(基类/超类),通过extends关键字继承了父类的类——子类(派生类),可拥有父类中的内容。

    基本语法

    1. class A{...} // 父类
    2. class B extends A{...} // 子类继承父类

    优点

  • 提高代码复用性。

  • 提高代码扩展性和可维护性。

    注意

  • 子类不能直接操作父类私有属性和方法,需要父类提供公共方法完成。

  • 子类必须调用父类构造器,完成父类初始化
  • 创建子类对象,默认总会去调用父类无参构造(可显示调用),若父类未提供,则使用 super 指定使用父类的构造器,完成父类初始化。
  • super() 和 this() 只能放在构造器第一行,因此二者不能共存同一构造器中。
  • Java 所有类都是 Object 子类,Object 是所有类的基类。
  • 父类构造器可以一直向上追溯,不限于上一层。
  • Java 是单继承。(可通过间接继承实现多继承)

    super

    代表父类引用,用于访问父类的(非私有)属性、方法、构造器。
    若父类没有,则往上再找,直到找到顶级父类。(this同理,只不过先找本类)
    image.png

    封装

    将属性和方法封装在一起,隐藏细节,只用通过被授权的操作(方法)才能对数据操作,保护数据。

    优点

  1. 隐藏实现细节。
  2. 保护数据安全。

    步骤

  3. 属性私有化。

  4. 提供公共修改器/访问器(set/get)方法用于数据的操作。

    构造器与修改器/访问器的结合

    1. public Person(String name, int age, double salary) {
    2. // 替代 this.name = name;
    3. setName(name);
    4. setAge(age);
    5. setSalary(salary);
    6. }

    多态

    方法或对象具有多种形态(使用者不同,含义不同),建立在继承和封装基础之上。重写和重载体现了多态,如
    1. void eat(){}
    2. person.eat(); // 人吃饭
    3. cat.eat(); // 🐱吃猫粮
  • 对象的编译类型和运行类型可以不一致
  • 编译类型再定义对象时确定,无法更改
  • 运行类型可变

    1. // 编译类型👇 运行类型👇
    2. Animal animal = new Dog();

    重点

  • 多态前提:二者存在继承关系。

  • 多态向上转型:父类引用指向子类对象,不能调用子类特有成员,运行效果看子类具体实现。
  • 多态向下转型:父类引用强转子类(不能强转父类对象),可调用子类中所有成员。、

    instanceOf

    比较,判断对象运行类型是否为指定类型或其子类型

    1. dog instanceOf Animal;

    方法重写/覆盖(override)

    子类拥有同父类相同签名的方法、返回类型(返回值是父类返回值的子类也可以),但方法权限大于等于父类。

    动态绑定

    调用对象方法时,该方法会和该对象的内存地址/运行类型绑定。

  • 即方法都是子类对象(运行类型)中的。

调用对象属性时,没有动态绑定,哪里声明,那里使用。

  • 即方法在哪个类中使用属性,该属性就是当前存在的类中的属性。

注意编译类型和运行类型的概念

  • 编译看左边,执行看右边。

    1. class A{
    2. int i = 1;
    3. public int getI(){
    4. return i;
    5. }
    6. int sum(){
    7. return i + 1;
    8. }
    9. }
    10. class B extends A{
    11. int i = 10;
    12. public int getI(){
    13. return i;
    14. }
    15. int sum(){
    16. return i + 1;
    17. }
    18. }
    19. class test{
    20. A a = new B();
    21. sout(a.sum);// 2
    22. // 思考B中 sum 被注释,此时 a 调用的 sum 是父类的
    23. // 而父类中的 sum 需要 getI
    24. // 此时 getI 是父类 A 中的 getI ,还是子类 B 中的 getI?
    25. // 答案:B,原因:Java 动态绑定机制
    26. }

    Object 类

    equals 和 ==

  • == 可判断基本类型和引用类型,但只是比较值(引用的值就是地址)是否相等。

  • equals 只能判断引用类型内容是否相等。

    对象类型的比较——重写 equals 方法

    判断两个对象的内容是否相等,如果二者属性值一致返回 true 反之 false。

  • 判断二者是否为同一对象

  • 判断二者类型,同类型则比较各属性值。

    hashCode 方法

    返回该对象的哈希码值,为了提高哈希表的性能。
    image.png

  • 该方法提高具有哈希结构的容器效率。

  • 两个引用指向同一对象,哈希值相同,反之不同。
  • 哈希值主要根据地址号来,不能完全将哈希值等价于地址。
  • 重写 hashCode 方法会在集合中讲解。

    toString 方法

  • 默认返回:全类名 + @ + 十六进制哈希值,子类往往重写,用于返回对象属性信息。

  • 打印或拼接对象时,会自动调用对象的 toString 形式。

    finalize 方法

  • 对象被回收时,系统自动调用该方法。子类可以重写该方法用于一些释放资源的操作。

  • 何时被回收:对象没有任何引用时,jvm 判定为垃圾对象,垃圾回收机制生效销毁该对象,销毁前会调用该方法。
  • 垃圾回收机制调用由系统决定,也可通过System.gc()触发。