Java语言进阶 #继承&多态 #Day9 #继承 #重写 #抽象 #发红包案例

文章目录

  • 一、继承
    • 1. 共性抽取
    • 2. 继承的格式
    • 3. 示例
    • 4. 成员变量/方法的4种访问特点
    • 5. 方法重写override
    • 6. 方法的重写实例
    • 7. 构造方法的4种访问特点
    • 8. super & this
      • 8.1 super关键字的3种用法:
      • 8.2 this关键字的3种用法:
      • 8.3 Demo
      • 8.4 内存图
    • 9. Java继承的特点
  • 二、抽象类
    • 1. 什么是抽象
    • 2. 抽象的格式
    • 3. 抽象方法的使用
    • Test:发红包
      • 需求分析
      • 代码实现

一、继承

面向对象三大特征:封装继承多态

继承是多态的前提

继承: 师傅会的徒弟都会,主要解决的是共性抽取

1. 共性抽取

  1. 有这样两个类,我们发现,他们有共性
    Java语言进阶 #继承&多态 #Day9 #继承 #重写 #抽象 #发红包案例_第1张图片
  2. 如果存在一个父类 ,正好有这些共性,就可以省下存储空间。
    Java语言进阶 #继承&多态 #Day9 #继承 #重写 #抽象 #发红包案例_第2张图片

注意: 一个先有父类,再有子类,上面的只是用于理解的推导。

  • 父类 也叫基类 ,也叫超类 (super())。
  • 子类 也叫派生类

2. 继承的格式

体会一下这句话:在继承的关系中,子类就是一个父类 (父类是官员,子类是文官。文官就是一个官员。是一个is a的关系。也就是说,子类可以当做父类对待

  • 父类格式 :
public class 父类名 {}
  • 子类格式:
public class 子类名 extends 父类名称 {}

3. 示例

  1. 创建一个父类
    Java语言进阶 #继承&多态 #Day9 #继承 #重写 #抽象 #发红包案例_第3张图片
  2. 创建一个空的子类
    在这里插入图片描述
  3. 在另一个文件创建子类对象。调用父类方法成功。
    Java语言进阶 #继承&多态 #Day9 #继承 #重写 #抽象 #发红包案例_第4张图片

4. 成员变量/方法的4种访问特点

  1. 子类创建的对象,调用成员方法或使用成员变量,会优先在子类 中找,找不到就向上一级找,实在找不到就报错。 即以子类为起点,向上查找。
  2. 子类调用的方法,如果使用了某个变量,则以该方法的所属者向上查找。
  3. 所属的概念,不仅是类的范畴。局部变量所属者是其方法区块,向上是本类变量,再向上是父类变量。所以当各种重名时,是会先从局部开始找起。
  4. 如果使用某特定部位的变量,则可用使用:局部变量this.成员变量super.成员变量名,来指定调用局部、本类还是父类的变量。
  • 总结一下逻辑,太好理解了: 为啥吃饱了撑的,要定义重名变量(方法)?就是因为直接使用上一级的变量(方法)不满足需求,才会重新定义。而有时确实有用到上一级的需求,只要使用有this关键字和super关键字即可。

5. 方法重写override

重写: 在继承关系中,方法名与父类方法名相同,参数列表也一样。也叫覆盖、覆写
重载: 方法名相同,参数列表不同的一组方法。


  1. 名称必须相同,参数列表也必须相同
@Override  // 检测是否是重写,如果不是会报错。
public void method() {}  // 方法名和父类相同

@的意思是注解。@Override可以不写(不写时,只要格式正确,也是正确的重写),但最好写上,起到一个安全检测的功能。


  1. 子类方法的返回值必须【小于等于】父类方法的返回值范围
  • java.lang.Object类是所有类的祖宗类
  • 比如父类方法返回值是Object类,子类方法是String类,这就行。反之不行。 (当初定义这个父类方法,是拿来返回无所不包的Object的。子类重写方法,只能得到String之类的,Object范围的子集。也就是说,重写时,父类的方法是一种限制。前面的1. 讲的是怎么重写。)

  1. 子类方法的权限 必须【大于等于】父类方法的权限修饰符
  • 权限修饰符:public > protected > (default) > private
  • 备注: (default)不是关键字default,而是什么都不写,留空

在绝大多数情况下,父类和子类的返回值和权限是一致的。

6. 方法的重写实例

为什么要进行方法重写:

  • 设计模式: 对于已经投入使用的类,尽量不要进行修改 。最好定义一个 的类,来重复利用其中共性内容,并且添加改动新内容。
  • 这就是继承 ,宏观上叫更新迭代

  1. 父类:
    Java语言进阶 #继承&多态 #Day9 #继承 #重写 #抽象 #发红包案例_第5张图片
  2. 子类: 输入要重写的方法名,出现提示,按回车,自动完成重写方法
    Java语言进阶 #继承&多态 #Day9 #继承 #重写 #抽象 #发红包案例_第6张图片
  3. 子类: 利用super.方法名()来调用父类方法(上一步中已经被IDEA写好了),再添加新代码
    Java语言进阶 #继承&多态 #Day9 #继承 #重写 #抽象 #发红包案例_第7张图片

7. 构造方法的4种访问特点

  1. 构造方法,会先执行父类 ,再执行子类 。(因为先有父,才有子)
    1.1 先写一个父类
    Java语言进阶 #继承&多态 #Day9 #继承 #重写 #抽象 #发红包案例_第8张图片
    1.2 再写一个子类
    Java语言进阶 #继承&多态 #Day9 #继承 #重写 #抽象 #发红包案例_第9张图片
    1.3 运行,发现父类构造方法先执行了
    Java语言进阶 #继承&多态 #Day9 #继承 #重写 #抽象 #发红包案例_第10张图片

  1. 子类构造方法中,会默认隐含super();调用。(这是一个无参构造的调用,如果要调用有参的重载形式,需要手动使用super(参数);
    2.1 父类不变
    2.2 子类全参构造方法,手动加上super(参数);(当然,可以使用Alt + Insert让IDE帮你加)
    Java语言进阶 #继承&多态 #Day9 #继承 #重写 #抽象 #发红包案例_第11张图片
    2.3 创建全参子类对象
    Java语言进阶 #继承&多态 #Day9 #继承 #重写 #抽象 #发红包案例_第12张图片

  1. 只有子类的构造方法,可以利用super();调用父类的构造方法,且这个构造方法,必须是子类构造方法的第一个语句

  1. 子类必须调用父类构造方法,不写就赠送,写了就用新写的

8. super & this

8.1 super关键字的3种用法:

  1. super.成员变量名 访问父类成员变量
  2. super.成员方法名() 访问父类成员方法
  3. super(); 访问父类构造方法

8.2 this关键字的3种用法:

  1. 在本类的成员方法中,访问本类的成员变量
  2. 在本类的成员方法中,访问本类的另一个成员变量
  3. 在本类的构造方法中,访问另一个构造方法()
    (比如无参构造,调用有参构造。this();也必须为第一个语句。)
    super();this();都必须是第一个,不能同时使用,如果使用了this();那么super();不再赠送。
    - 如果构造方法循环调用 (比如:无参调1参,1参调全参,全参调无参),会报错

8.3 Demo

Java语言进阶 #继承&多态 #Day9 #继承 #重写 #抽象 #发红包案例_第13张图片
Java语言进阶 #继承&多态 #Day9 #继承 #重写 #抽象 #发红包案例_第14张图片
Java语言进阶 #继承&多态 #Day9 #继承 #重写 #抽象 #发红包案例_第15张图片

8.4 内存图

Java语言进阶 #继承&多态 #Day9 #继承 #重写 #抽象 #发红包案例_第16张图片

  1. 最开始,方法区载入三个类(特别注意,子类有一个指向父类的[[super_class]],这是程序自动编写的)。然后检测到main()方法,使其进栈。
    Java语言进阶 #继承&多态 #Day9 #继承 #重写 #抽象 #发红包案例_第17张图片

  2. 创建一个子类对象时,会new进堆。此时在堆中为子类开辟的内存空间分为两部分,外部是子类自己,内部是一个完整的父类结构。
    Java语言进阶 #继承&多态 #Day9 #继承 #重写 #抽象 #发红包案例_第18张图片

  3. 调用子类method();方法。子类通过super.去子类内部找到父类的method();方法。结束之后弹栈
    Java语言进阶 #继承&多态 #Day9 #继承 #重写 #抽象 #发红包案例_第19张图片

  4. 调用子类打印变量方法
    Java语言进阶 #继承&多态 #Day9 #继承 #重写 #抽象 #发红包案例_第20张图片

9. Java继承的特点

  1. Java语言是单继承 的。一个类的直接父类只能有唯一一个。(Python中,可以多继承是由于__mor__继承顺序)
  2. Java语言可以多级继承,一个类的父类的父类还是它的父类,只不过不是直接父类。
  3. java.lang.Object是一切类的祖宗类

二、抽象类

1. 什么是抽象

你能知道图形类的计算面积方法嘛?
Java语言进阶 #继承&多态 #Day9 #继承 #重写 #抽象 #发红包案例_第21张图片
如果父类中的方法不确定如何进行具体实现,那么这就是一个抽象方法

2. 抽象的格式

创建一个图形类:
Java语言进阶 #继承&多态 #Day9 #继承 #重写 #抽象 #发红包案例_第22张图片

  1. 抽象方法必须在抽象类内部
  2. 抽象类和抽象方法都用abstract修饰

3. 抽象方法的使用

  1. 不能直接创建抽象类对象(无意义),需用子类来继承创建
  2. 子类需要重写(也叫实现)父类的所有抽象方法(没有abstract关键字,有方法体)

Java语言进阶 #继承&多态 #Day9 #继承 #重写 #抽象 #发红包案例_第23张图片

注: Math.pow(a, b)表示a的b次方

Java语言进阶 #继承&多态 #Day9 #继承 #重写 #抽象 #发红包案例_第24张图片


注意:

  1. 抽象方法也可以有构造方法,是供子类super();调用时使用的。
  2. 抽象类可以没有抽象方法。此时是为了,不让调用这直接创建该类对象。
  3. 抽象类的子类,必须重写父类所有抽象方法,除非这个子类也是抽象类。

Test:发红包

需求分析

Java语言进阶 #继承&多态 #Day9 #继承 #重写 #抽象 #发红包案例_第25张图片

  • 需求分析: 群主和群成员都有各自姓名和余额。
  • 群主: 群主发红包,成员收红包。 群主需要知道当前有多少群成员,以便把红包分成多少份。返回的红包钱数用ArrayList返回(因为不确定长度,所以用可以变化长度的集合来做)。群主只能发比自己余额少的钱数。
  • 群成员: 需要接收红包,加入自己余额

代码实现

以下仅展示主要方法
父类
Java语言进阶 #继承&多态 #Day9 #继承 #重写 #抽象 #发红包案例_第26张图片
群主类
Java语言进阶 #继承&多态 #Day9 #继承 #重写 #抽象 #发红包案例_第27张图片
成员类
Java语言进阶 #继承&多态 #Day9 #继承 #重写 #抽象 #发红包案例_第28张图片


运行调用:
Java语言进阶 #继承&多态 #Day9 #继承 #重写 #抽象 #发红包案例_第29张图片
结果
Java语言进阶 #继承&多态 #Day9 #继承 #重写 #抽象 #发红包案例_第30张图片

你可能感兴趣的:(java)