day15_面向对象的三大特征之一(继承)

news2024/11/25 12:27:53

继承的概述

Java是对现实社会的模拟,现实中有儿子可以继承父亲的财产,因此有了富二代的。 java中多个类中存在相同属性和行为时,将这些内容抽取到单独一个类中,那么多个类中无需再定义这些属性和行为,只需要和抽取出来的类构成某种关系。如图所示:

其中,多个类可以称为子类,也叫派生类;多个类抽取出来的这个类称为父类超类(superclass)或者基类继承描述的是事物之间的所属关系,这种关系是is-a 的关系。例如,图中猫属于动物,狗也属于动物。可见,父类更通用,子类更具体。我们通过继承,可以使多种事物之间形成一种关系体系。

继承的好处

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

继承的格式

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

继承演示,代码如下:  

现实中通用的属性和功能定义在父类中

/*
 * 定义人类Person,做为父类
 */
public class Person {
    //成员变量 对应 现实中的属性
    private String name;
    private int age;

    public String getName() {
        return name;
    }

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

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }
    // 成员方法 对应现实中的功能
    public void showInfo(){
        System.out.println("姓名:" +name +"年龄:" + age);
    }
}

定义Student子类

/*
 * 定义Student类继承 人类Person
 */
public class Student extends Person {
    //独有的方法
    public void study() {
        System.out.println("学习..");
    }
}

定义Teacher子类

/*
 * 定义Teacher类继承 人类Person
 */
public class Teacher extends Person{
    //独有的方法
    public void teaching() {
        System.out.println("教书..");
    }
}

定义测试类

public class Test {
    public static void main(String[] args) {
        //创建子类Student对象
        Student student = new Student();
        //调用从父类继承的方法 和变量
        student.setName("张三");
        student.setAge(18);
        student.showInfo(); //姓名:张三  年龄:18
        //调用本类独有的方法
        student.study(); //学习..


        //创建子类Teacher对象
        Teacher teacher = new Teacher();
        //调用从父类继承的方法 和变量
        teacher.setName("李四");
        teacher.setAge(28);
        teacher.showInfo(); //姓名:李四  年龄:28
        //调用本类独有的方法
        teacher.teaching(); //教书..
    }
}

继承的特点

  • Java只支持单继承,不支持多继承
//一个类只能有一个父类,不可以有多个父类。
class C extends A{} 	//ok
class C extends A,B...	//error
  •  Java支持多层继承(继承体系)。顶层父类是Object类。所有的类默认继承Object,作为父类。
class A{}
class B extends A{}
class C extends B{}
  • 子类和父类是一种相对的概念。例如:B类对于A来说是子类,但是对于C类来说是父类
  •  一个父类可以同时拥有多个子类

继承的中成员变量的访问

  • 父类中的成员,无论是公有(public)还是私有(private),均会被子类继承。
  • 子类虽会继承父类私有(private)的成员,但子类不能对继承的私有成员直接进行访问,可通过继承的get/set方法进行访问。如图所示:

代码示例

/*
 * 定义动物类Animal,做为父类
 */
class Animal {
    // 定义name属性
    private String name;
    // 定义age属性
    public int age;
    // 定义动物的吃东西方法
    public void eat() {
        System.out.println(age + "岁的" + name + "在吃东西");
    }
}

/*
 * 定义猫类Cat 继承 动物类Animal
 */
class Cat extends Animal {
    // 定义一个猫抓老鼠的方法catchMouse
    public void catchMouse() {
        System.out.println("抓老鼠");
    }
}

/*
 * 定义测试类
 */
public class Test {
    public static void main(String[] args) {
        // 创建一个猫类对象
        Cat cat = new Cat();

        // 为该猫类对象的name属性进行赋值
        //cat.name = "Tom";// 编译报错,不能直接访问父类中私有的成员

        // 为该猫类对象的age属性进行赋值
        cat.age = 2;

        // 调用该猫的catchMouse()方法
        cat.catchMouse(); //抓老鼠

        // 调用该猫继承来的eat()方法
        cat.eat(); //2岁的null在吃东西
    }
}

如果子父类中有重名的成员变量,子类中如何访问父类中的成员变量

  • 当父类的成员变量私有化时,在子类中是无法直接访问的,如果想要访问父类的私有成员变量,只能通过父类的get/set方法访问。所以是否重名不影响
  • 当父类的成员变量非私有时,在子类中可以直接访问,所以如果有重名时,就需要加“super."进行区别。

代码示例

class Animal {
    private String name = "动物";
    public int age = 118;

    public String getName() {
        return name;
    }

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

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }
}

class Cat extends Animal {
    // private String name = "猫";
    public int age = 18;

    public void show() {
        // System.out.println("种类:"+ super.name);  编译报错,父类私有的成员变量子类不能直接访问

        //通过GetXxx方法访问
        System.out.println("种类:" + getName()); //种类:动物

        //直接访问变量名称使用的是本类中的
        System.out.println("我的年龄:" + age); //我的年龄:18

        // 使用super来访问父类中的非私有成员
        System.out.println("我父亲的年龄是:" + super.age); //我父亲的年龄是:118
    }
}


public class Test {
    public static void main(String[] args) {
        Cat cat = new Cat();
        cat.show();

    }
}

继承的中成员方法的访问

我们说父类的所有方法子类都会继承,我们不能直接访问父类中私有的成员方法,但是可以间接访问。

class Animal {
    private void introduce() {
        System.out.println("我是动物老大");
    }
    public void info(){
        introduce();
    }

}

class Cat extends Animal {

}

public class Test {
    public static void main(String[] args) {
        Cat cat = new Cat();
       // cat.introduce(); 子类不能直接访问父类中私有的成员方法
        //间接访问
        cat.info(); //我是动物老大

    }
}

我们也可以直接调用父类中,非私有的成员方法

class Animal {
    public void eat() {
        System.out.println("我是动物,要吃东西");
    }

}

class Cat extends Animal {

}

public class Test {
    public static void main(String[] args) {
        Cat cat = new Cat();
        cat.eat(); //我是动物,要吃东西

    }
}

方法重写

当子类中出现了与父类一模一样的方法时,我们称之为方法重写 (Override) 。应用场景:子类觉得父类原来的实现方法不适合于子类。比如新的手机增加来电显示头像的功能,代码如下

class Phone {
    public void sendMessage() {
        System.out.println("发短信");
    }

    public void call() {
        System.out.println("打电话");
    }

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

//智能手机类
class NewPhone extends Phone {

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

public class Test {
    public static void main(String[] args) {
        // 创建子类对象
        NewPhone np = new NewPhone();


        // 调用父类继承而来的方法
        np.call();
        np.sendMessage();

        // 调用子类重写的方法
        np.showNum();

    }
}

注意事项:

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

必须保证父子类之间方法的名称相同,参数列表也相同。大部分情况下,我们只要保证要重写的方法一模一样就好,除非有特殊要求。任何情况下也不能违背下面几点原则

返回值类型:

  • 引用类型:子类方法的返回值类型必须【小于等于】父类方法的返回值类型(小于其实就是是它的子类,例如:Student < Person)。
  • 基本类型:如果返回值类型是基本数据类型和void,那么必须是相同

子类方法的访问权限必须【大于等于】父类方法的访问权限修饰符 小扩展提示:public > protected > 缺省 > private

几种特殊的方法不能被重写

  • 静态方法不能被重写
  • 私有等在子类中不可见的方法不能被重写
  • final方法不能被重写

继承的中构造方法的访问

当类之间产生了关系,其中各类中的构造方法,又产生了哪些影响呢?

首先我们要回忆两个事情,构造方法的定义格式和作用。

  1. 构造方法的名字是与类名一致的。所以子类是无法继承父类构造方法的。

  2. 构造方法的作用是初始化实例变量的,而子类又会从父类继承所有成员变量。所以子类的初始化过程中,必须先执行父类的初始化动作。子类的构造方法中默认有一个super() ,表示调用父类的实例初始化方法,父类成员变量初始化后,才可以给子类使用。

代码示例

class Fu{
    public Fu() {
        System.out.println("我是父类中的无参数构造器");
    }
}
class Zi extends Fu{
    public Zi() {
        System.out.println("我是Zi类中的无参数构造器");
    }
}

public class Test {
    public static void main(String[] args) {
        Zi zi = new Zi();
        /*
        输出结果:
            我是父类中的无参数构造器
            我是Zi类中的无参数构造器
        
         */
    }

}

如果父类没有无参构造怎么办?

class Fu{
    public int number;
    public Fu(int number) {
        System.out.println("我是父类中的有参数构造器");
    }
}
class Zi extends Fu{
    public Zi() { //此时子类代码报错。
        System.out.println("我是Zi类中的无参数构造器");
    }
}

解决办法:在子类构造器中,用super(实参列表),显示调用父类的有参构造解决。

class Fu {
    public int number;

    public Fu(int number) {
        System.out.println("我是父类中的有参数构造器: " + number);
    }
}

class Zi extends Fu {
    public Zi() {
        super(1); //用super(实参列表),显示调用父类的有参构造解决
        System.out.println("我是Zi类中的无参数构造器");
    }
}

public class Test {
    public static void main(String[] args) {
        Zi zi = new Zi();
        /*
        输出结果:
           我是父类中的有参数构造器: 1
           我是Zi类中的无参数构造器
         */
    }

}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/53015.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

CSDNtop1全栈接口测试教程 jmeter接口测试,接口自动化测试

测试时优先对其进行结构化拆分&#xff0c;将测试整体拆分为各个场景 创建线程组&#xff0c;简单控制器&#xff0c;HTTP请求默认值&#xff0c;HTTP信息头管理器 将测试目标结构化&#xff0c;可以更好地管理测试框架和整合其他组件&#xff0c;有利于反馈工作 添加HTTP请求…

如何做好自动化测试?揭开测试项目团队的自动化实践过程……

稍具测试规模的项目团队皆想引进自动化测试&#xff0c;然而动手实现自动化测试的团队却不多&#xff0c;未能真正实施的原因多种多样&#xff0c;有扼杀在摇篮里的&#xff0c;有写了后弃之不用。那么是不是所有的业务都适合自动化测试呢&#xff1f;下面就介绍下自己在项目中…

超级好用的笔记工具------Typora 如何修改Typora 中图片保存的位置

用了这么多的笔记、最后还是选择了Typora。真的是很不错呐。一些私密的笔记、比如公司内部资料。放到网页多多少少是不安全的。还是放到本地安全的多。 1、使用Typora 做的小笔记 1.1 目录情况 这个可以按照自己的进度或者时间节点自行分级 1.2 某一个页面的具体设计 2、基本…

react18 通过redux 做一个简单的状态管理基站

我们打开react项目 在终端输入 npm install redux --saveredux就进来了 这里 我们引入了 redux 但其实 有一个 redux 和一个 react-redux 两者区别在于 redux 是一个js的状态管理容器 而react-redux 则提供了 更多便于react开发的状态管理方法 然后我们在项目的src目录下创…

4-FreeRTOS队列、互斥、信号量

1-队列 队列&#xff08;我对队列的理解就是上体育课&#xff0c;排队这种&#xff09;是任务之间通信的一种方式。队列可以用于任务和任务之间或者中断和任务之间消息的接收与发送。在多数情况下&#xff0c;他们消息缓冲是按照FIFO&#xff08;先进先出&#xff09;原则。也…

文本处理方式方法

概述 从今天开始&#xff0c;我们将开启一段自然语言处理的流程&#xff0c;自然语言可以让来处理、理解以及运用人类的语言&#xff0c;实现机器语言和人类语言之间的沟通桥梁。 文本处理 我们正在进行文本处理的时候&#xff0c;经常会用到文本长度不一致的情况&#xff0c…

Microsoft SQL Server 图书管理数据库的建立

文章目录题目描述创建数据库使用数据库创建三个表外码的表示形式结果展示题目描述 – 新建 “图书管理数据库" – 其中包含三个关系 – 图书&#xff08;编号&#xff0c;图书名&#xff0c;作者&#xff0c;出版社&#xff0c;类型&#xff0c;单价&#xff09; – 借阅…

ASP.NET Core 3.1系列(16)——Entity Framework Core之Code First

1、前言 前一篇博客介绍了EFCore中的DB First开发模式&#xff0c;该模式可以根据数据库生成实体类和数据库上下文&#xff0c;因此适用于数据库已经存在的场景。而与之相对应的&#xff0c;Code First主要是根据自定义的实体类和数据库上下文反向构建数据库&#xff0c;因此也…

操作系统02_进程管理_同步互斥信号量_PV操作_死锁---软考高级系统架构师007

存储管理可以分为固定存储管理和分页存储管理。 现在固定存储管理已经不用也不考,但要知道因为固定存储管理指的是整存整取 也就是把一整个程序,比如说10G的游戏全部都存到内存里 这样的话是非常占用内存的,这个固定存储管理现在已经不用了。 然后这里我们主要看分页存储管: …

网页去色变黑白+网页黑白恢复为彩色

前言 特定节日&#xff0c;你会发现网页和app首页都会变成灰色&#xff0c;以此来表达我们的哀思之情。 好奇宝宝想知道各个网站都是使用哪些小技巧来做出这种效果的&#xff08;由彩变灰&#xff0c;由灰变彩&#xff09;&#xff0c;于是稍微学习了一下… 由灰变彩 稍微想…

USDP集群服务器宕机后集群及组件重启

USDP集群的其中2服务器意外宕机&#xff0c;其中包括一台USDP管理服务节点主机和工作节点主机&#xff0c;服务器重新启动后&#xff0c;USDP智能大数据平台无法登录&#xff0c;启动UDSP服务&#xff08;/opt/usdp-srv/usdp/bin/start-udp-server.sh&#xff09;后可以登录&am…

Go1.9.3跑GinDemo

Gin 1. 简介 1.1. 介绍 Gin是一个golang的微框架&#xff0c;封装比较优雅&#xff0c;API友好&#xff0c;源码注释比较明确&#xff0c;具有快速灵活&#xff0c;容错方便等特点 对于golang而言&#xff0c;web框架的依赖要远比Python&#xff0c;Java之类的要小。自身的n…

Linux部署WordPress(宝塔版)

宝塔手册宝塔安装 yum install -y wget && wget -O install.sh http://download.bt.cn/install/install_6.0.sh && sh install.sh 宝塔配置 1.帮助命令&#xff1a;bt2.修改用户名(童心同萌)&#xff1a;bt 63.修改密码(123456)&#xff1a;bt 54.修改端口(888…

JWT详细介绍

文章目录1 jwt介绍1.1 什么是jwt1.2 使用场景1.2.1 授权1.2.2 信息交换1.3 JWT结构1.3.1 header1.3.2 payload1.3.3 signature 签名2 Python 实现2.1 手动编码2.2 jwt包3 校验 jwt5 js解析jwt1 jwt介绍 官网&#xff1a;https://jwt.io/ 本文以python来进行实战演示 1.1 什么…

KG-开源项目:CMeKG【利用自然语言处理与文本挖掘技术,基于大规模医学文本数据,以人机结合的方式研发的中文医学知识图谱】

CMeKG&#xff08;Chinese Medical Knowledge Graph&#xff09;是利用自然语言处理与文本挖掘技术&#xff0c;基于大规模医学文本数据&#xff0c;以人机结合的方式研发的中文医学知识图谱。 项目来源&#xff1a; 中文医学知识图谱CMeKG2.0版发布-自然语言处理实验室北京大…

iOS开发之打包上传到App Store——(一)各种证书的理解

OK&#xff0c;有日子没写iOS开发的相关文章啦&#xff0c;主要是最近的精力都没在这上面&#xff0c;不过既然产品已经快要出来了&#xff0c;就有必要了解一下各种证书啥的&#xff08;众所周知iOS的一堆证书可是很让人头大呀&#xff09;&#xff0c;最近确实被这个搞得头大…

外汇天眼:随着美元贬值所有世界货币,每个国家都在为自己着想

没有迹象表明各国政府愿意合作&#xff0c;各国被迫靠自己的力量建立防御措施&#xff0c;抵御万能的美元的无情力量。 在美联储的鹰派政策、美国经济强劲以及寻求市场波动避险的投资者的支持下&#xff0c;美元兑所有其他货币正在稳步走强&#xff0c;创下数十年来的最大涨幅。…

信号发生器不会用?一篇文章教会你

信号发生器是一种能提供各种频率、波形和输出电平电信号的设备。在测量各种电信系统或电信设备的振幅特性、频率特性、传输特性及其它电参数时&#xff0c;以及测量元器件的特性与参数时&#xff0c;用作测试的信号源或激励源。 1、信号发生器如何使用 选用与验电器相同电压等…

Gateway--服务网关

目录一、网关简介二、Gateway简介三、Gateway快速入门基础版增强版简写版四、Gateway核心架构基本概念执行流程五、断言内置路由断言工厂内置路由断言工厂的使用自定义路由断言工厂六、 过滤器局部过滤器内置局部过滤器内置局部过滤器的使用自定义局部过滤器全局过滤器内置全局…

ROS MoveIT2(humble)安装总结

版本 系统版本&#xff1a;ubuntu22.04 ROS2版本&#xff1a;humble Moveit版本&#xff1a;moveit2-humble 安装 ROS 2 和 Colcon 如果您在接下来的几个步骤中遇到错误&#xff0c;一个好的开始是返回并确保您已正确安装 ROS 2。用户通常忘记的一个是获取 ROS 2 安装本身。…