Lazy loaded image
编程
📕Day09-面向对象3(继承)
字数 3889阅读时长 10 分钟
2019-1-21
2025-8-13
type
status
date
slug
summary
tags
category
icon
password

继承

继承: 把多个类共有的属性和行为再进一步抽象,放到一个父类里
继承的特点: 子类继承自父类以后,可以访问父类里的部分属性,调用父类里的部分方法(和权限修饰符以及类的位置有关)
  1. 父类被private修饰的属性和方法,子类不能直接访问。
  1. 父类被默认权限修饰符修饰的属性和方法,子类如果和父类不在同一个包里,子类无法访问
修饰符
类内部
同一个包
不同包的子类
同一个工程
private
yes
(默认)
yes
yes
protected
yes
yes
yes
public
yes
yes
yes
yes
一旦子类A继承父类B以后,子类A中就获取了父类B中声明的结构:属性、方法。 特别是父类中声明为private的属性或方法,子类继承父类以后,仍然认为获取了父类中私有的结构,只是因为封装性的影响,使得子类不能直接调用父类的结构而已 子类继承父类以后,还可以声明自己特有的属性或方法。实现功能的扩展。子类和父类的关系不同于集合和自己的关系,子类的功能更加强大

继承性的好处

  1. 减少了代码的冗余,提升了代码的复用性
  1. 方便功能的扩展
  1. 为后面的多态性使用提供了前提

继承的格式

class A extends B{}
A子类、派生类、subclass B父类、超类、基类、superclass

继承的规定

  1. 一个子类只能有一个父类(java类的单继承性。C++支持多重继承,java不支持,后面会讲到接口,一个类是可以实现多个接口的)
  1. 一个父类可以有多个子类
  1. 子父类是一个相对的概念。
  1. 子类直接继承的类成为直接父类,间接继承的父类称为间接父类。
  1. 子类继承父类以后,就获取了直接父类以及所间接父类中声明的属性和方法。
  1. Java里 最终的父类是 java.lang.Object,在 Object里定义的 protected以上的方法,所有的类都能调用。

Object

  1. 如果我们没显式的声明一个类的父类的话,则此类继承于java.lang.Object类
  1. 所的java类(除java.lang.Object类之外都直接或间接的继承于java.lang.Object类
  1. 意味着,所的java类具有java.lang.Object类声明的功能。

Object类常见方法介绍

  • toString(): 当直接打印一个对象时,默认就是调用 toString()方法
  • equals(): 比较两个对象的内容是否相等,不能使用 ==,而要使用 equals方法,如果一个类没有重写equals方法,会调用 Object 的 equals()方法,默认实现方式就是直接使用 == 比较对象的地址值
  • hashCode():返回改对象的哈希吗值,是为了提供HashTable或HashMap的性能
  • getClass():获取运行时类型,返回值为Class对象
  • clone():主要是JAVA里除了8种基本类型传参数是值传递,其他的类对象传参数都是引用传递,我们有时候不希望在方法里将参数改变,这时就需要在类中重写clone方法,如果在clone方法中调用super.clone()方法需要实现Cloneable接口,否则会抛出CloneNotSupportedException。此方法只实现了一个浅层拷贝,对于基本类型字段成功拷贝,但是如果是嵌套对象,只做了赋值,也就是只把地址拷贝了,所以没有成功拷贝,需要自己重写clone方法进行深度拷贝。
  • wait():多线程时用到的方法,作用是让当前线程进入等待状态,同时也会让当前线程释放它所持有的锁。直到其他线程调用此对象的 notify() 方法或 notifyAll() 方法,当前线程被唤醒
  • notify():多线程时用到的方法,唤醒该对象等待的某个线程
  • notifyAll():多线程时用到的方法,唤醒该对象等待的所有线程
  • finalize():对象在被GC释放之前一定会调用finalize方法,对象被释放前最后的挣扎,因为无法确定该方法什么时候被调用,很少使用。

方法的重写

重写:子类继承父类以后,可以对父类中同名同参数的方法,进行覆盖操作 应用:重写以后,当创建子类对象以后,通过子类对象调用子父类中的同名同参数的方法时,实际执行的是子类重写父类的方法;子类如果想要访问父类里的同名方法,可以使用 super.方法名()调用
静态方法不允许重写,子类可以定义一个和父类相同的静态方法,但是这个不是重写

重写的相关规定

  1. 子类重写的方法的方法名和形参列表与父类被重写的方法的方法名和形参列表相同
  1. 子类重写的方法的权限修饰符要大于等于父类被重写的方法的权限修饰符 特殊情况:子类不能重写父类中声明为private权限的方法。private < 缺省 < protected < public
  1. 返回值类型: 父类被重写的方法的返回值类型是void,则子类重写的方法的返回值类型只能是void 父类被重写的方法的返回值类型是A类型,则子类重写的方法的返回值类型可以是A类或A类的子类 父类被重写的方法的返回值类型是基本数据类型(比如:double),则子类重写的方法的返回值类型必须是相同的类型(double)
  1. 子类重写的方法抛出的异常类型不大于父类被重写的方法抛出的异常类型

区分方法的重载和重写

重载概念及具体规则:“两同一不同”,在同一个类中,允许存在方法名相同,形参不同的多个方法。形参不同主要表现在形参的个数、形参的顺序或者形参的类型。 重载方法的返回值类型可以不同,无法通过返回值类型判断一个方法是否构成重载,重载方法的权限可以为任意权限。重载也可以发生在子父类之间
重写概念:重写方案的方法名和参数必须完全一样。jdk1.5版本之后,java放宽了对返回值类型的要求,重载方法的返回值需要小于等于原方法的返回值。重写方法抛出的异常不能大于原方法抛出的异常,重写方法的权限不能小于原方法的权限。重写方法只能发生在父类和子类之间。
简言之,重写方法的规则是两同,两小,一大
重写需要注意的问题:
  1. 声明为final类型的方法不能被重写
  1. static的方法不能被重写,但可以被继承
  1. 构造方法不能被重写
  1. 继承是重写的前提。被private修饰的方法不能被继承和重写;缺省的方法只有当子类在同一个包下的时候才能继承和重写;被protected和public修饰的方法,子类全都可以继承和重写
区别:
  1. 重写方法的权限必须大于等于原方法的权限,重载方法的权限可以是任意的
  1. 重写方法的方法名和方法参数必须完全一致,重载方法的方法名要相同,而方法参数要不同
  1. 静态方法不可以重写,但是静态方法可以被重载
  1. 构造器不可以重写,但是可以被重载
  1. 重写实现的是运行时行为(动态/晚绑定),而重载实现的是编译时行为(静态\早绑定)。重写是多态,重载不是多态

子父类属性方法题目

  1. 子类没有定义同名变量
notion image
  1. 子类只重写了get方法
notion image
  1. 子类只重写了set方法
notion image
  1. 子类重写了get和set方法
notion image

super关键字

super 关键字可以理解为:父类的。super可以调用的结构是属性、方法、构造器
super调用属性、方法:
  1. 我们可以在子类的方法或构造器中,通过使用"super.属性"或"super.方法"的方式,显式的调用父类中声明的属性或方法。但是,通常情况下,我们习惯省略"super.”
  1. 当子类和父类中定义了同名的属性时,我们要想在子类中调用父类中声明的属性,则必须显式的使用"super.属性"的方式,表明调用的是父类中声明的属性
  1. 当子类重写了父类中的方法以后,我们想在子类的方法中调用父类中被重写的方法时,则必须显式的使用"super.方法"的方式,表明调用的是父类中被重写的方法
super调用构造器:
  1. 我们可以在子类的构造器中显式的使用"super(形参列表)"的方式,调用父类中声明的指定的构造器
  1. "super(形参列表)"的使用,必须声明在子类构造器的首行
  1. 我们在类的构造器中,针对于"this(形参列表)"或"super(形参列表)"只能二一,不能同时出现
  1. 在构造器的首行,没显式的声明"this(形参列表)"或"super(形参列表)",则默认调用的是父类中空参的构造器:super()
  1. 在类的多个构造器中,至少一个类的构造器中使用了"super(形参列表)",调用父类中的构造器

Objects工具类

上一篇
Day08-面向对象2(封装习题)
下一篇
Day10-面向对象4(接口、抽象类、多态)