zoukankan      html  css  js  c++  java
  • java09 继承(覆盖重写、super、this)抽象类





    3.继承

          继承是多态的前提,面向对象的三大特征:封装、继承、多态

    image

    继承可以理解为抽取共性的关键点,如上图所示。

    定义:

    父类:  public class 父类名称{               子类:public class 子类名称 extends 父类名称{

            代码块                                                   代码块

    }                                                            }

    唯一一个标识  extends  。

    image

    从而实现了代码复用的作用。

    3.0.1.父类与子类的成员变量各自使用范围:

    父类可以使用父类的成员变量,而子类不光可以使用子类成员变量 还可以使用父类的成员变量。父类与子类成员变量可以重名。

    3.0.2.访问父类成员变量的方法:

    • 直接通过子类对象访问成员变量:

    规则:等号左边是谁,则优先用谁,否则没有则向上查找。

    • 间接通过成员方法访问成员变量:

    规则:子类对象点(调用)的方法是谁,则优先使用谁,没有则向上找。

    image

    至此,出现三种变量:局部变量、子类成员变量、父类成员变量,因此在子类的成员方法中进行以下三种方法区分:即

    • 局部变量直接用,子类成员变量用this.,

    • 而父类成员变量用super进行区分。

    • 调用成员方法的对象是子类,则优先用子类的成员方法,否则就向上找。

    image



    3.1.继承关系中成员方法名称一样就存在覆盖重写

    覆盖重写:override 发生在继承关系中,方法名称一样,参数列表也一样,

    方法重载:overload 方法名称一样,参数列表不同。

    3.1.1.方法的覆盖重写使用过程中有几点需要特别十分关注

    • 父类与子类的成员方法,必须同名和同参数,可使用@override起到安全检测作用。
    • 子类的返回值范围必须小于父类的返回值。
    • 子类的方法权限必须大于等于父类的方法权限 public>protected>(default)>private

    3.1.2.方法的覆盖重写的应用场景

          假如 现在有个需求,将老款手机中的来电提醒功能,增加手机姓名等,这时不方便写过去所有用户的老程序,此事扩展其新方法,就需要使用覆盖重写的子类方法。

    image

    3.1.3父类构造方法的访问特点:


        构造方法是定义在java类中的一个用来初始化对象的方法,体现在:所谓的创建一个对象就是开辟一个内存空间,初始化是指给对应属性赋初值。

      1 public class Student
      2 {
      3     public String name;
      4     public int age;
      5     public Student()
      6     {
      7         //默认的构造方法,其中name的初值是null,age的初值是0;
      8         //当然你也可以给定一个固定的值
      9         //name="name";
     10         //age=20;
     11     }
     12     //构造方法重载,完成对应属性的初始化
     13     public Student(String name,int age)
     14     {
     15         this.name=name;
     16         this.age=age;
     17         //其中name,age的初值是参数中传入的值
     18     }
     19 }

    特点:子类构造必须调用父类构造,默认赠送super();调用无参,否则手写super(传参)调用父类有参构造也就是父类重载的构造方法

    1.子类构造方法方法体内 必须调用父类构造方法,没有明确写super():,那么将默认赠送。

    2.子类构造方法可以用super关键字来调用父类重载构造

    3.子类构造方法用super调用父类构造方法时,必须排行第一句

    image

          构造方法是一种特殊的方法,它是一个与类同名的方法。对象的创建就是通过构造方法来完成,其功能主要是完成对象的初始化。当类实例化一个对象时会自动调用构造方法。

    构造方法和成员方法的区别

        A:格式区别
               构造方法和类名相同,并且没有返回类型,也没有返回值。
               普通成员方法可以任意起名,必须有返回类型,可以没有返回值。
         B:作用区别
                构造方法用于创建对象,并进行初始化值。
                普通成员方法是用于完成特定功能的。

         C:调用区别
                构造方法是在创建对象时被调用的,一个对象建立,只调用一次相应构造函数。
                普通成员方法是由创建好的对象调用,可以调用多次


    3.2.super关键字用法

    • A 子类的成员方法中,super调用父类的成员变量 super.父类成员变量名
    • B 子类的成员方法中,super调用父类的成员方法 super.父类成员方法名
    • C 子类的构造方法中,super调用父类的构造方法 super(可传参);

    super :代表父类的存储空间标识(可以理解为父亲的引用)。 也就是使用super关键字访问父类内容。它与this关键字的区别如下:

    this.成员变量 ‐‐ 本类的

    super.成员变量 ‐‐ 父类的

    this.成员方法名() ‐‐ 本类的

    super.成员方法名() ‐‐ 父类的

    3.3.this关键字

    3.3.1含义

    this :代表当前对象的引用(谁调用就代表谁)。 也就是使用this关键字访问本类中,或是子类中使用或是父类中使用。

    this.成员变量 ‐‐ 本类的

    super.成员变量 ‐‐ 父类的

    this.成员方法名() ‐‐ 本类的

    super.成员方法名() ‐‐ 父类的

    3.3.2this关键字的3个用法和4个关键点

    • 用法:

    在本类的成员方法中,访问本类的成员变量

    在本类的成员方法中,访问本类的另外一个成员方法

    在本类的构造方法中,访问本类的另外一个构造方法

    • 关键点:

    this调用也得是构造方法中的第一个语句。

    构造方法中,this调用不能没有尽头,至少有一个构造方法中没有调用this。

    成员方法中,this可以在全部成员方法循环调用。


    效果图如下:

    image


      1 package d.d.d;
      2 public class zi extends fu {
      3     int num =20;
      4     public void showNum(){
      5         int num = 10;
      6         System.out.println(num);//局部变量,访问本方法中局部变量 num = 10;
      7         System.out.println(this.num);//this关键字访问本类的成员变量num = 20
      8         System.out.println(super.num);//super关键字访问父类num = 30
      9     }
     10     public void methodA() {    // 成员方法A
     11         System.out.println("aaa");
     12         this.methodB();
     13     }
     14     public void methodB() {    // 成员方法B
     15         methodA();//在成员方法methoB中调用methodA,另外一种方法是this.methodA();是强调作用
     16         this.methodA();//与methodA();一样,只是起到强调作用
     17         System.out.println("bbb");
     18     }
     19      public zi(){   // 构造方法zi();
     20         //this.zi(); 这种是错误写法
     21         this(123);//本类的无参构造,调用本类的有参构造
     22     }
     23     public zi(int n){    // 构造方法zi(n);
     24         this(12,3);
     25     }
     26     public zi(int n,int b){    // 构造方法zi(n,m);
     27         //this(3); 不可以全部都有this,至少有一个构造方法
     28     }
     29 
     30 }
     31 
     32 
      1 package d.d.d;
      2 
      3 public class fu {//父类
      4     int num = 30;
      5 }
      6 

    3.3.3.内存图的变化

    image

      1 package d.d.d;
      2 
      3 public class demo {
      4     public static void main(String[] args) {
      5         zi zi = new zi();
      6         zi.show();
      7         zi.method();
      8     }
      9 }
      1 package d.d.d;
      2 
      3 public class fu {
      4     int num = 10;
      5     public void  method(){
      6         System.out.println("父类方法");
      7     }
      8 }
      9 
      1 package d.d.d;
      2 public class zi extends fu {
      3     int num =20;
      4     @Override
      5     public void method(){ //与父类成员方法一样,叫覆盖重写
      6         super.method();// 调用父类成员方法
      7         System.out.println("子类方法");
      8     }
      9     public void show(){
     10         int num = 30;
     11         System.out.println(num);// 输出局部变量,num = 30;
     12         System.out.println(this.num);// 输出本类成员变量,num = 20;
     13         System.out.println(super.num);// 输出父类成员变量,num = 10;
     14 
     15     }
     16 
     17 }
     18 

    3.3.4java的继承的特征

    • java语言是单继承,一个类的直接父类只能有唯一一个
    • java语言可以多级继承
    • java语言一个父类,可以有多个子类

    image


    4.抽象类

          了解下什么叫抽象,假设提问一个图形的面积计算,那么对于三角形、圆形、长方形等等,均有不同的计算方法。所以这个方法是一个抽象方法,具体到一种图形就行。如果父类方法不确定如何进行,也就是具体执行方式不确定,那么就是抽象方法

    05-抽象的概念

    4.1.抽象方法的定义

    抽象方法:就是在返回值前面加上 abstract 关键字,然后去掉大括号,直接小括号结束;

    抽象类:也就是抽象方法所在的类就是抽象类,定义抽象类就是在class前面加上abstract;

    语法:

    public abstract class 类名{   //抽象类就是在class前面加上abstract

          public abstract void eat(); //返回值前面加上 abstract 关键字,然后去掉大括号,直接小括号结束;

    }

    1585212939(1)

      1 package e.e.e;
      2 
      3 public abstract class E {//抽象方法
      4     public abstract void eat();//抽象方法
      5     //这是普通方法
      6     public void normamethod(){
      7 
      8     }
      9 }

    4.2.抽象方法的使用方法和注意事项

    • 不能直接创建new抽象类对象
    • 必须使用一个子类来继承抽象父类
    • 子类必须覆盖重写抽象父类当中的所有的抽象方法
    • 覆盖重写(实现):子类去掉抽象方法中的abstract关键字,然后补上方法体大括号。

    image

      1 package e.e.e;
      2 
      3 public abstract class animail {//抽象方法
      4     public abstract void eat();//抽象方法
      5     //这是普通方法
      6     public void normamethod(){
      7 
      8     }
      9 }
      1 package e.e.e;
      2 
      3 public class cat extends animail {
      4     @Override
      5     public  void eat(){
      6         System.out.println("猫吃鱼");
      7     }
      8 
      9 }
     10 
      1 package e.e.e;
      2 
      3 public class demo {
      4     public static void main(String[] args) {
      5         cat cat = new cat();
      6         cat.eat();
      7     }
      8 }
      9 


    4.3注意事项。

    • 抽象类不能创建对象,如果创建,编译无法通过而报错,只能创建其非抽象子类的对象,也就是说如果创建类抽象类的对象,调用抽象的方法,而抽象方法没有具体方法体,没有意义

    image

    • 抽象类中,可以有构造方法,是供子类创建对象时,初始化父类成员使用的,也就是说子类的构造方法中,有默认的super()会访问父类的构造方法,进行父类成员初始化。1.抽象父类构造方法先执行,然后子类的构造方法执行,这个父类的构造方法要执行,必须用super()调用。 2.子类即便没有构造方法,那么父类的无参构造方法也会默认执行。

    image

    • 抽象类中,不一定包含抽象方法,但有抽象方法的必须是抽象类。未包含抽象方法的抽象类,是不想让调用创建抽象方法的对象,通常用于某种特别结构设计,设计模式中的适配器模式就可以使用这样的。


    • 抽象类的子类,必须重写抽象父类所有的抽象方法,否则编译无法通过而报错,除非改子类也是抽象类。

    image

    5.案例:

    5.3.群主发普通红包

    群主发普通红包。某群有多名成员,群主给成员发普通红包。普通红包的规则:

    • 1. 群主的一笔金额,从群主余额中扣除,平均分成n等份,让成员领取。
    • 2. 成员领取红包后,保存到成员余额中。

    请根据描述,完成案例中所有类的定义以及指定类之间的继承关系,并完成发红包的操作

    分析:首先有个群,群主是发送红包,群主自己不抢红包,群主金额会减少,成员抢红包,抢到金额进入自己腰包约

    image

      1 public class User {
      2     private  String name;//姓名
      3     private int money;// 余额
      4 
      5     public User() {// 无参构造  alt+ insert  constructor 啥都不选快速生成
      6     }
      7 
      8     public User(String name, int money) {// 有参构造  alt+ insert  constructor 全选选快速生成
      9         this.name = name;
     10         this.money = money;
     11     }
     12     //展示一下当前用户多少钱
     13     public void show(){
     14         System.out.println("我叫:" + name + "我有多少钱" + money);
     15     }
     16 
     17     public String getName() {
     18         return name;
     19     }
     20 
     21     public void setName(String name) {
     22         this.name = name;
     23     }
     24 
     25     public int getMoney() {
     26         return money;
     27     }
     28 
     29     public void setMoney(int money) {
     30         this.money = money;
     31     }
     32 }
     33 
      1 import java.util.ArrayList;
      2 //群主的类
      3 public class Manager extends User{
      4     // 写默认构造和有参构造即可,默认有super();
      5     public Manager(){
      6 
      7     }
      8 
      9     public Manager(String name, int money) {//叫什么名字、多少钱
     10         super(name, money);//参数传递给父类
     11     }
     12     public ArrayList<Integer> send (int totalMoney,int count){        // 总共要发多少钱,要发几份
     13         //首先需要一个集合,存储若干个红包的金额
     14         ArrayList<Integer> redList = new ArrayList<>();
     15         // 首先看下群主有多少钱
     16         int leftMoney = super.getMoney();//群主当前余额。
     17         if(totalMoney > leftMoney){
     18             System.out.println("余额不足");
     19             return redList;// 返回空集合
     20         }
     21         // 扣钱 就是重新设置余额
     22         super.setMoney(leftMoney - totalMoney);// super是父类方法,将余额返回送进父类
     23         //发红包需要拆分count分
     24         int avg = totalMoney / count;
     25         int mod = totalMoney % count; // 余数 也就是取模
     26 
     27         // 除不开的零头放在最后一个红包中
     28         // 下面把红包一个一个放在集合中
     29         for (int i = 0; i < count - 1; i++) {//最后一个红包单独处理
     30             redList.add(avg);
     31         }
     32         // 最后一个红包
     33         int last = avg + mod;
     34         redList.add(last);
     35         return redList;
     36 
     37     }
     38 }
     39 
      1 import java.util.ArrayList;
      2 import java.util.Random;
      3 
      4 
      5 public class Member extends User{
      6     public Member() {
      7     }
      8 
      9     public Member(String name, int money) {
     10         super(name, money);
     11     }
     12     public void receive(ArrayList<Integer> list){//红包已经在集合中
     13         // 从多个红包当中随便抽泣一个红包,给自己,也就是随机获取集合当中的索引变化。
     14         int index = new Random().nextInt(list.size());// random是匿名对象,范围是不能超过集合长度,最高到size-1为止
     15         //根据索引,从集合中删除,并且得到被删除的红包,给自己
     16         int delta = list.remove(index);//remove返回的是被删除的值,也就是某个抢到的红包钱
     17         // 当前成员自己本来多少钱
     18         int money = super.getMoney();
     19         //最后成员多少钱,也就是加上后,重新设置回去。
     20         super.setMoney(money + delta);
     21 
     22 
     23     }
     24 }
     25 


      1 import java.util.ArrayList;
      2 
      3 public class MainRedPacket {
      4     public static void main(String[] args) {
      5         Manager manager = new Manager("群主",101);
      6         Member member1 = new Member("bingo1",2);
      7         Member member2 = new Member("bingo2",2);
      8         Member member3 = new Member("bingo3",2);
      9         Member member4 = new Member("bingo4",2);
     10         manager.show();
     11         member1.show();
     12         member2.show();
     13         member3.show();
     14         member4.show();
     15         // 装群主发红包的集合怎么来的呢
     16         ArrayList<Integer> redList = manager.send(20,4);
     17         // 四个人去收红包
     18         member1.receive(redList);
     19         member2.receive(redList);
     20         member3.receive(redList);
     21         member4.receive(redList);
     22 
     23         manager.show();
     24         member1.show();
     25         member2.show();
     26         member3.show();
     27         member4.show();
     28     }
     29 }
     30 
  • 相关阅读:
    java 寒假作业
    java 搭积木
    java 移动距离
    java 垒骰子
    java 饮料换购
    java 牌型种数
    ONOS基础教程(QuickStart with a VM)
    Java中 VO、 PO、DO、DTO、 BO、 QO、DAO、POJO的概念
    PM2使用基本介绍
    nodejs项目部署
  • 原文地址:https://www.cnblogs.com/rango0550/p/12573746.html
Copyright © 2011-2022 走看看