为什么要有继承

多个类中存在相同属性和行为时,将这些内容抽取到单独一个类中,那么多个类无需再定义这些属性和行为,只要继承那一个类即可。其中,多个类可以称为子类,单独那一个类称为父类超类或者基类

继承的概念

继承:就是子类继承父类的属性行为,使得子类对象具有与父类相同的属性、相同的行为。子类可以直接访问父类中的非私有的属性和行为。继承描述的是事物之间的所属关系,这种关系是: is-a 的关系。继承的关系中,“子类就是一个父类”,也就是说子类可以被当做父类看待。例如,兔子属于食草动物,食草动物属于动物。可见,父类更通用,子类更具体。我们通过继承,可以使多种事物之间形成一种关系体系。继承主要解决的问题是共性抽取。

好处

  • 提高代码的复用性
  • 类与类之间产生了关系,是多态的前提

继承关系当中的特点

  • 子类拥有父类中非私有的属性和行为
  • 子类还可以拥有自己独有的属性和行为

继承的格式

通过 extends 关键字,可以声明一个子类继承另外一个父类,定义格式如下:

注意:父类只是一个普通的类

代码举例

定义父类

package MyCode.demo01;

// 定义一个父类
public class MyFather {
    //父类中的成员变量
    public int age = 18;

    //父类中的成员方法
    public void method() {
        System.out.println("我是父类中的方法");
    }
}

定义子类

package MyCode.demo01;

// 定义子类MySon继承MyFather
public class MySon extends MyFather {
}

定义测试类

package MyCode.demo01;

public class MyTest {
    public static void main(String[] args) {
        //创建子类对象
        MySon son = new MySon();
        //子类里面什么代码都没有,但是继承了父类中非私有的方法和属性
        son.method();
        System.out.println(son.age);
    }
}

代码执行后的结果

继承中成员变量的访问特点

创建父类对象

  • 只能使用父类的成员变量,没有任何子类的成员变量

创建子类对象

  • 子类对象可以使用本类中的成员变量或者使用父类中非私有的成员变量
  • 如果子类父类中出现不重名的成员变量,这时子类对象可以根据不同的成员变量名来访问需要的成员变量。
  • 如果子类父类中出现重名的成员变量,这时子类对象有2种访问方式

             访问方式1:直接通过子类对象访问成员变量:等号左边是谁,就优先用谁,没有则向上(父类)找。
             访问方式2:间接通过成员方法访问成员变量:该方法属于谁,就优先用谁,没有则向上(父类)找

继承中成员方法的访问特点

创建父类对象

  • 只能使用父类的成员方法,没有任何子类的成员方法

创建子类对象

  • 子类对象可以使用本类中的成员方法或者使用父类中非私有的成员方法
  • 访问成员方法的规则:创建的对象是谁,就优先用谁,如果没有则向上(父类)找。

方法重写 (Override)

如果子类父类中出现重名的成员方法,这时的访问是一种特殊情况,叫做方法重写 (Override)。

  • 方法重写 :子类中出现与父类一模一样的方法时(返回值类型,方法名和参数列表都相同),会出现覆盖效 果,也称为重写或者复写。简单理解:声明不变,重新实现

方法重写的注意事项:

1. 必须保证父子类之间方法的名称相同,参数列表也相同。

  • tips:@Override:写在方法前面,用来检测是不是有效的正确覆盖重写。这个注解就算不写,只要满足要求,也是正确的方法覆盖重写。

2. 子类方法的返回值必须【小于等于】父类方法的返回值范围。

  • tips:java.lang.Object类是所有类的公共最高父类(祖宗类),java.lang.String就是Object的子类。

3. 子类方法的访问权限必须【大于等于】父类方法的权限修饰符。

  • tips:public > protected > (default) > private    备注:(default)不是关键字default,而是什么都不写,留空。

重写的应用

子类可以根据需要,定义特定于自己的行为。既沿袭了父类的功能名称,又根据子类的需要重新实现父类方法,从 而进行扩展增强。设计原则:对于已经投入使用的类,尽量不要修改,推荐一个新的类,来重复利用其中共性内容,添加新的内容。

代码举例

定义老款手机

package MyCode.demo02;

// 本来的老款手机
public class Phone {

    public void call() {

        System.out.println("打电话");
    }

    public void send() {
        System.out.println("发短信");
    }

    public void show() {
        System.out.println("显示号码");
    }

}

定义新款手机类,方法覆盖重写应用。

package MyCode.demo02;

// 定义一个新手机,使用老手机作为父类
public class NewPhone extends Phone {

    //重写父类的来电显示号码功能,并增加自己的显示姓名和图片功能
    @Override
    public void show() {
        //调用父类已经存在的功能使用super
        super.show();
        //增加自己特有显示姓名和图片功System.out.println("显示来电姓名");
        System.out.println("显示头像");
    }
}

定义测试类

package MyCode.demo02;

public class Demo01Phone {
    public static void main(String[] args) {

        // 创建子类对象
        NewPhone np = new NewPhone();

        //调用继承下来的方法
        np.call();
        np.send();
        // 调用子类重写的方法
        np.show();

    }
}

代码执行后的结果

Java关键字this和super用法总结

this关键字含义

  • this :代表当前对象的引用(谁调用就代表谁)。

super的含义

  • super :代表父类的存储空间标识(可以理解为父亲的引用)。

super关键字用来访问父类内容,用法有三种:

  1. 在子类的成员方法中,访问父类的成员变量。格式:super.成员变量名
  2. 在子类的成员方法中,访问父类的成员方法。格式:super.成员方法名
  3. 在子类的构造方法中,访问父类的构造方法。格式:super(参数列表)

this关键字用来访问本类内容,用法也有三种:

  1. 在本类的成员方法中,访问本类的成员变量。              格式:this.成员变量名
  2. 在本类的成员方法中,访问本类的另一个成员方法。   格式:this.成员方法名()
  3. 在本类的构造方法中,访问本类的另一个构造方法。   格式:this(参数列表)

第三种用法当中要注意:

  • this(...)调用也必须是构造方法的第一个语句,唯一一个。
  • super和this两种构造调用,不能同时使用。​​​​​​​

代码举例

package MyCode.demo03;

class Animal {
    public void eat() {
        System.out.println("animal : eat");
    }
}

创建子类Cat

package MyCode.demo03;

class Cat extends Animal {
    public void eat() {
        System.out.println("cat : eat");
    }

    public void eatTest() {
        // this 调用本类的方法
        this.eat();
        // super 调用父类的方法 }
        super.eat();
    }
}

创建测试类

package MyCode.demo03;

public class Test {
    public static void main(String[] args) {
        //创建父类对象Animal
            Animal a = new Animal();
            a.eat();
            //创建子类对象
            Cat c = new Cat();
            c.eatTest();
        }
    }

代码执行后的结果

继承关系中父子类构造方法的访问特点

  • 构造方法的名字是与类名一致的。所以子类是无法继承父类构造方法的。
  • 子类构造方法当中有一个默认隐含的“super()”调用,所以一定是先调用的父类构造,后执行的子类构造方法
  • 子类构造可以通过super关键字来调用父类重载构造。
  • super的父类构造调用,必须是子类构造方法的第一个语句。不能一个子类构造调用多次super构造。
  • 总结:子类构造方法必须调用父类构造方法,不写则赠送super();写了则用写的指定的super调用,super只能有一个,还必须是第一个。

父类空间优先于子类对象产生

在每次创建子类对象时,先初始化父类空间,再创建其子类对象本身。目的在于子类对象中包含了其对应的父类空间,便可以包含其父类的成员,如果父类成员非private修饰,则子类可以随意使用父类成员。代码体现在子类的构造方法调用时,一定先调用父类的构造方法。

继承的特点

Java只支持单继承,不支持多继承。

//一个类只能有一个父类,不可以有多个父类。
class C extends A{} //ok
class C extends A,B... //error

Java支持多层继承(继承体系)。

class A{}
class B extends A{}
class C extends B{}

子类和父类是一种相对的概念。tips:顶层父类是Object类。所有的类默认继承Object,作为父类。

综合案例:群主发普通红包

群主发普通红包。某群有多名成员,群主给成员发普通红包。普通红包的规则:
  • 群主的一笔金额,从群主余额中扣除,平均分成n等份,让成员领取。
  • 成员领取红包后,保存到成员余额中。请根据描述,完成案例中所有类的定义以及指定类之间的继承关系,并完成发红包的操作。

案例分析

  • 根据描述分析,得出如下继承体系:

代码实现

定义User类

package MyCode.demo05;

public class User {

    private String name; // 姓名
    private int money; // 余额,也就是当前用户拥有的钱数

    public User() {
    }

    public User(String name, int money) {
        this.name = name;
        this.money = money;
    }

    // 展示一下当前用户有多少钱
    public void show() {
        System.out.println("我叫:" + name + ",我有多少钱:" + money);
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getMoney() {
        return money;
    }

    public void setMoney(int money) {
        this.money = money;
    }
}

定义Manager类

package MyCode.demo05;

import java.util.ArrayList;

// 群主的类
public class Manager extends User {

    public Manager() {
    }

    public Manager(String name, int money) {
        super(name, money);
    }

    public ArrayList<Integer> send(int totalMoney, int count) {
        // 首先需要一个集合,用来存储若干个红包的金额
        ArrayList<Integer> redList = new ArrayList<>();

        // 首先看一下群主自己有多少钱
        int leftMoney = super.getMoney(); // 群主当前余额
        if (totalMoney > leftMoney) {
            System.out.println("余额不足");
            return redList; // 返回空集合
        }

        // 扣钱,其实就是重新设置余额
        super.setMoney(leftMoney - totalMoney);

        // 发红包需要平均拆分成为count份
        int avg = totalMoney / count;
        int mod = totalMoney % count; // 余数,也就是甩下的零头

        // 除不开的零头,包在最后一个红包当中
        // 下面把红包一个一个放到集合当中
        for (int i = 0; i < count - 1; i++) {
            redList.add(avg);
        }

        // 最后一个红包
        int last = avg + mod;
        redList.add(last);

        return redList;
    }
}

定义Member类

package MyCode.demo05;

import java.util.ArrayList;
import java.util.Random;

// 普通成员
public class Member extends User {

    public Member() {
    }

    public Member(String name, int money) {
        super(name, money);
    }

    public void receive(ArrayList<Integer> list) {
        // 从多个红包当中随便抽取一个,给我自己。
        // 随机获取一个集合当中的索引编号
        int index = new Random().nextInt(list.size());
        // 根据索引,从集合当中删除,并且得到被删除的红包,给我自己
        int delta = list.remove(index);
        // 当前成员自己本来有多少钱:
        int money = super.getMoney();
        // 加法,并且重新设置回去
        super.setMoney(money + delta);
    }
}

定义测试类

package MyCode.demo05;

import java.util.ArrayList;

public class MainRedPacket {

    public static void main(String[] args) {
        Manager manager = new Manager("群主", 100);

        Member one = new Member("成员A", 0);
        Member two = new Member("成员B", 0);
        Member three = new Member("成员C", 0);

        manager.show();
        one.show();
        two.show();
        three.show();
        System.out.println("===============");

        // 群主总共发20块钱,分成3个红包
        ArrayList<Integer> redList = manager.send(20, 3);
        // 三个普通成员收红包
        one.receive(redList);
        two.receive(redList);
        three.receive(redList);

        manager.show(); // 100-20=80
        // 6、6、8,随机分给三个人
        one.show();
        two.show();
        three.show();
    }

}

代码执行后的结果

Java之继承性的更多相关文章

  1. java的继承性

    在java继承中,子类也称为派生类,父类也称为基类或者超类,基本语法 :子类 extends 父类{} 实现一个简单的继承类: class Person{ private String name; p ...

  2. java 面向对象(十二):面向对象的特征二:继承性 (一) 前言

    1.为什么要有类的继承性?(继承性的好处) * ① 减少了代码的冗余,提高了代码的复用性 * ② 便于功能的扩展 * ③ 为之后多态性的使用,提供了前提图示: 2.继承性的格式:class A ext ...

  3. Java学习---基础知识学习

    2016-07-23  周六 利用键盘输入的时候需要抛出异常 ,直接快捷键 ctrl + 1 ;定义数组 int score[] = new int[4]  ;  只有4个数字BufferedRead ...

  4. 浅谈Java三大特性之继承

    前言 简单用伪代码去介绍一些 父类与子类的构造函数问题 others 前言 类的继承性是面向对象语言的基本特性,多态性前提是继承性.Java 支持继承性和多态性.——Java从小白到大牛 继承:三大特 ...

  5. JAVASE(九)面向对象特性之 : 继承性、方法重写、关键字super、

    个人博客网:https://wushaopei.github.io/    (你想要这里多有) 1.继承性 1.1 为什么要类的继承性?(继承性的好处) ①减少了代码的冗余,提高了代码的复用性:②更好 ...

  6. java 面向对象(二十四):interface:接口

    interface:接口1.使用说明: 1.接口使用interface来定义 * 2.Java中,接口和类是并列的两个结构 * 3.如何定义接口:定义接口中的成员 * * 3.1 JDK7及以前:只能 ...

  7. Java基础语法,常用知识复习

    1.开发环境搭建 1.1JDK.JRE.JVM.的关系 JDK = JRE + 开发工具集(例如javac编译工具集等) JRE = JVM + Java SE 标准类库 2.基本语法 2.1.jav ...

  8. 尚硅谷Java——宋红康笔记【day11-day18】

    day11 Eclipse中的快捷键: * 1.补全代码的声明:alt + / * 2.快速修复: ctrl + 1 * 3.批量导包:ctrl + shift + o * 4.使用单行注释:ctrl ...

  9. <Android Framework 之路>多线程

    多线程编程 JAVA多线程方式 1. 继承Thread线程,实现run方法 2. 实现Runnable接口 JAVA单继承性,当我们想将一个已经继承了其他类的子类放到Thread中时,单继承的局限就体 ...

随机推荐

  1. Task 的一些个人见解

    Task确实比较好用且优雅 我感觉.NET要成为艺术家... public class TheTask { /// <summary> /// 直接调用是同步方法 /// </sum ...

  2. Selenium之勾选框操作

    勾选框操作:       所谓勾选框,意思是可以勾选一个及以上或全部勾选.勾选框的图标一般都是方形的. 复选框勾选一般分为三种情况: ①勾选单个框,我们直接用元素定位的方式定位到点击即可. ②勾选多个 ...

  3. JS-变量、作用域、垃圾回收机制总结

    预解析时变量和函数同名的话,保留函数

  4. SpringBoot电商项目实战 — Zookeeper的分布式锁实现

    上一篇演示了基于Redis的Redisson分布式锁实现,那今天我要再来说说基于Zookeeper的分布式现实. Zookeeper分布式锁实现 要用Zookeeper实现分布式锁,我就不得不说说zo ...

  5. javaWeb实现验证码--代码超简单

    1.前端显示 HTML: <h3>验证码:</h3> <input type="text" name="validationCode&quo ...

  6. CentOS 磁盘在线扩容

    场景介绍: 操作系统Centos7.x 系统有一块vdisk,容量为20G,共分为3个区(swap和boot分区为标准分区xfs文件系统,根分区为LVM分区,xfs文件系统) 业务需求:在VM系统不关 ...

  7. IEEE754 32位浮点数表示范围

    6.1浮点数的数值范围 根据上面的探讨,浮点数可以表示-∞到+∞,这只是一种特殊情况,显然不是我们想要的数值范围. 以32位单精度浮点数为例,阶码E由8位表示,取值范围为0-255,去除0和255这两 ...

  8. python3数据分析,安装学习

    python3数据分析,安装学习 转载注明来源: 本文链接 来自osnosn的博客,写于 2019-09-26. 为了简单.安装 anaconda3 就好啦. 因为安装原版python3,用pip安装 ...

  9. deepin镜像 mxlinux镜像 ubuntu镜像桌面版

    百度网盘https://pan.baidu.com/s/18HX4XgXRMXFho036tuP-Hw

  10. Spring Boot 项目维护全局json数据

    1:概述 过去 我们在每一个方法中处理前端发过来的请求,需要自己构造请求数据,然后通过spring 提供的@ResponseBody 强制转为JSON数据吗,实际上出现了很多重复的代码,我么亦可以通过 ...