面向对象

1 抽象

抽象是将一类对象的共同特征总结出来构造类的过程,包括数据抽象和行为抽象两方面。抽象只关注对象有哪些属性和行为,并不关注这些行为的细节是什么。

2 封装

把数据和行为隐藏,只能通过暴露的接口访问数据。

3 继承

通过扩展一个类来建立另一个新的类。

3.1 慎用继承

  1. 将公共操作和域放在超类。
  2. 不要使用受保护的域。
  3. 使用继承实现”is-a”。
  4. 除非所有继承的方法都有意义,否则不要使用继承。
  5. 在覆盖方法时,不要改变预期的行为。
  6. 使用多态,而非类型信息。
  7. 不要过多地使用反射。

3.2 强制类型转换

只能在继承层次内进行类型转换。

在将超类转换成子类之前,应该使用 instanceof 进行检查。

  • 上溯造型(Upcasting):把衍生类型当作它的基本类型处理
  • 下溯造型(Downcasting):向下转型,超类可用子类置换。

3.3 重写(override)

存在于继承体系中,指子类实现了一个与父类在方法声明上完全相同的一个方法。

为了满足里式替换原则,重写有以下三个限制:

  • 子类方法的访问权限必须大于等于父类方法;
  • 子类方法的返回类型必须是父类方法返回类型或为其子类型。
  • 子类方法抛出的异常类型必须是父类抛出异常类型或为其子类型。

使用 @Override 注解,可以让编译器帮忙检查是否满足上面的三个限制条件。

在调用一个方法时,先从本类中查找看是否有对应的方法,如果没有再到父类中查看,看是否从父类继承来。否则就要对参数进行转型,转成父类之后看是否有对应的方法。总的来说,方法调用的优先级为:

  • this.func(this)
  • super.func(this)
  • this.func(super)
  • super.func(super)

3.4 重载(overload)

存在于同一个类中,指一个方法与已经存在的方法名称上相同,但是参数类型、个数、顺序至少有一个不同。

应该注意的是,返回值不同,其它都相同不算是重载。

4 多态

一个对象变量可以指示多种实际类型的现象被称为多态(polymorphism)。

Java 实现多态有三个必要条件:继承、重写、上溯造型。

虚拟机预先为每个类创建了一个方法表(method table),其中列出了所有方法的签名和实际调用的方法。

4.1 动态绑定

在运行时能够自动选择调用哪个方法的现象称为动态绑定。

  1. 编译器会列举类方法表中同名方法,和超类方法表中同名且为 public 的方法。
  2. 编译器重载匹配参数类型,若有完全匹配的就选择,没有就匹配允许类型转换的方法,如果这样还是不能找到匹配项,编译器就会报错;同时如果找到多于一个匹配项,编译器也会报错。

4.2 静态绑定

如果是 private,static,final 方法或者构造器,那么编译器可以明确地知道该调用哪个方法,这种调用方式成为静态绑定。

Author: iMine
Link: https://imine141.github.io/2020/08/19/Java%E5%9F%BA%E7%A1%80/%E5%AF%B9%E8%B1%A1%E4%B8%8E%E7%B1%BB/%E9%9D%A2%E5%90%91%E5%AF%B9%E8%B1%A1/
Copyright Notice: All articles in this blog are licensed under CC BY-NC-SA 4.0 unless stating additionally.