【面向对象三大特性之继承】

news2024/12/24 9:16:37

目录

  • 1.什么是继承
  • 2.父类成员访问
    • 2.1 子类访问父类的成员变量
      • 2.1.1 子类和父类不存在同名成员变量
      • 2.1.2 子类和父类存在同名成员变量
    • 2.2子类中访问父类的成员方法
      • 2.2.1. 成员方法名字不同
      • 2.2.22. 成员方法名字相同
  • 3.super关键字
  • 4.子类构造方法
  • 5.super和this的异同点
  • 6.代码块的顺序
  • 6.继承方式
  • 7.final关键字

1.什么是继承

继承是一种机制,是对代码复用的重要手段。
主要解决的问题是:共性的抽取,实现代码的复用。

我们使用继承的时候,使用extends关键字

A extends B 这个就是继承
A:称为子类/派生类
B:称为父类/超类/基类

class 子类 extends 父类 {
// …
}

因为姓名和年纪是公用的,所以我们将姓名和年纪放到父类中,我们的子类只需要继承就可以了
这个样子就避免了代码的冗余。

继承之后,子类可以复用父类中成员,子类在实现时只需关心自己新增加的成员即可。

class Animal{
    public String name;
    public  int age;
}

class Dog extends Animal
{

}
class Cat extends Animal
{

}
public class Test {
    public static void main(String[] args) {
        Dog dog=new Dog();
        Cat cat=new Cat();
    }
}

2.父类成员访问

2.1 子类访问父类的成员变量

2.1.1 子类和父类不存在同名成员变量

当我们的子类和父类不存在同名的变量的时候,我们直接使用就可以了。

其中a,b是从父类继承下来的,c是子类自己的

class Base
{
    public int a;
    public int b;
}
class Derivce extends  Base
{
    public int c=9;

    public void func()
    {
        System.out.println(a);
        System.out.println(b);
        System.out.println(c);//优先子类
    }
}
public class Test2 {
    public static void main(String[] args) {
        Derivce derivce=new Derivce();
        derivce.func();
    }
}

在这里插入图片描述

2.1.2 子类和父类存在同名成员变量

当我们的子类和父类存在同名的变量的时候,如果子类中有这个变量,我们会优先值子类的,如果之类没有那就会向父类中查询,取到父类的。

其中a,b是从父类继承下来的,在子类中没有,所以取到的是父类的,c是优先子类自己的。

在子类方法中 或者 通过子类对象访问成员时:
如果访问的成员变量子类中有,优先访问自己的成员变量。
如果访问的成员变量子类中无,则访问父类继承下来的,如果父类也没有定义,则编译报错。
如果访问的成员变量与父类中成员变量同名,则优先访问自己的

class Base
{
    public int a;
    public int b;

     public int c=199;

}
class Derivce extends  Base
{
    public int c=9;

    public void func()
    {
        System.out.println(a);
        System.out.println(b);
        System.out.println(c);//优先子类
    }
}
public class Test2 {
    public static void main(String[] args) {
        Derivce derivce=new Derivce();
        derivce.func();
    }
}

在这里插入图片描述

2.2子类中访问父类的成员方法

2.2.1. 成员方法名字不同

class A
{
    public void MethodA()
    {
        System.out.println("MethodA");
    }
}
class B extends  A
{
    public void MethodB()
    {
        System.out.println("Method B");
    }

    public void show()
    {
        MethodB();
        MethodA();
    }
}
public class Test3 {
    public static void main(String[] args) {
        B b=new B();
        b.show();
    }
}

在这里插入图片描述

这时我们可以看出来,当我们访问方法的时候,如果子类有就优先子类的,子类没有就去父类里面找,如果父类也没有的话,就会报错。

2.2.22. 成员方法名字相同

class A
{
    public void MethodA()
    {
        System.out.println("MethodA");
    }
}
class B extends  A
{
    public void MethodB()
    {
        System.out.println("Method B");
    }

    public void MethodA()
    {
        System.out.println("Method and B");
    }
    public void show()
    {
        MethodB();
        MethodA();
    }
}
public class Test3 {
    public static void main(String[] args) {
        B b=new B();
        b.show();
    }
}

在这里插入图片描述

通过子类对象访问父类与子类中不同名方法时,优先在子类中找,找到则访问,否则在父类中找,找到
则访问,否则编译报错。
通过派生类对象访问父类与子类同名方法时,如果父类和子类同名方法的参数列表不同(重载),根据调用
方法适传递的参数选择合适的方法访问,如果没有则报错;

3.super关键字

当我们子类和父类都有变量或者方法的时候,我们都知道会优先访问子类自己的变量或者方法,那么如果我们想要访问父类的变量或者方法,怎么办呢?

这个时候我们就要借助super’这个关键字。

Java提供了super关键字,该关键字主要作用:在子类方法中访问父类的成员

class Base
{
    public int a;
    public int b;

     public int c=199;

}
class Derivce extends  Base
{
    public int c=9;

    public void func()
    {
        System.out.println(a);
        System.out.println(b);
        System.out.println(c);//优先子类
        System.out.println(super.c);//拿的是父类的
        System.out.println(this.c);//自己的
    }
}
public class Test2 {
    public static void main(String[] args) {
        Derivce derivce=new Derivce();
        derivce.func();
    }
}

在这里插入图片描述

【注意事项】
super只是一个关键字,最大作用就是在写代码的时候体现出更好的可读性
1. 只能在非静态方法中使用
2. 在子类方法中,访问父类的成员变量和方法。

super 只能代指直接的父类
super.属性 在子类中,访问父类的成员变量
super.方法() 在子类中,访问父类的成员方法

4.子类构造方法

在继承关系上,当我们在构造之类的时候,一定要先帮父类进行构造。

父子父子,先有父再有子,即:

子类对象构造时,需要先调用基类构造方法,然后执行子类的构造方法

当我们在子类构造一个方法的时候,我们就一定要先帮父类也构造一个方法。,当我们构造一个子类方法的时候,系统会默认帮我们在里面构造一个无参数的super。

class Animal{
    public String name;
    public  int age;

    public void eat(){
        System.out.println(name + "正在吃饭");
    }

    public Animal() {

    }

    public Animal(String name, int age) {
        this.name = name;
        this.age = age;
    }

    public void sleep(){
        System.out.println(name + "正在睡觉");
    }

}

class Dog extends Animal
{
    public Dog() {

    }

    //在构造子类的时候,一定要先构造父类
    public Dog(String name, int age) {
        //super一定要在第一行
        super(name,age);//显示的调用父类的构造方法,帮助父类的成员实现初始化
    }

    public void speak(){
        System.out.println(name + "在汪汪汪");
    }
}
class Cat extends Animal
{

    public Cat() {
        super();
    }
    public Cat(String name, int age) {
        super(name, age);
    }

    public void speak(){
        System.out.println(name + "在喵喵喵");
    }
}
public class Test {
    public static void main(String[] args) {
        //Animal animal=new Animal();
//        Dog dog=new Dog("小狗",10);
        Dog dog=new Dog();
        dog.name="小狗";
        dog.age=10;
        dog.speak();
        dog.eat();
        System.out.println("===========");
        Cat cat=new Cat("小猫",11);
//        cat.name="小猫";
//        cat.age=11;
        cat.speak();
        cat.eat();
    }
}

在这里插入图片描述

在子类构造方法中,并没有写任何关于基类构造的代码,但是在构造子类对象时,先执行基类的构造方法,然后执
行子类的构造方法,因为:子类对象中成员是有两部分组成的,基类继承下来的以及子类新增加的部分 。父子父子
肯定是先有父再有子,所以在构造子类对象时候 ,先要调用基类的构造方法,将从基类继承下来的成员构造完整
,然后再调用子类自己的构造方法,将子类自己新增加的成员初始化完整 。

注意:

  1. 若父类显式定义无参或者默认的构造方法,在子类构造方法第一行默认有隐含的super()调用,即调用基类构
    造方法
  2. 如果父类构造方法是带有参数的,此时需要用户为子类显式定义构造方法,并在子类构造方法中选择合适的父类构造方法调用,否则编译失败。
  3. 在子类构造方法中,super(…)调用父类构造时,必须是子类构造函数中第一条语句。4. 4. super(…)只能在子类构造方法中出现一次,并且不能和this同时出现

5.super和this的异同点

【相同点】

  1. 都是Java中的关键字
  2. 只能在类的非静态方法中使用,用来访问非静态成员方法和字段
  3. 在构造方法中调用时,必须是构造方法中的第一条语句,并且不能同时存在【不同点】
    【不同点】
  4. this是当前对象的引用,当前对象即调用实例方法的对象,super相当于是子类对象中从父类继承下来部分成
    员的引用
  5. 在非静态成员方法中,this用来访问本类的方法和属性,super用来访问父类继承下来的方法和属性
  6. 在构造方法中:this(…)用于调用本类构造方法,super(…)用于调用父类构造方法,两种调用不能同时在构造
    方法中出现
  7. 构造方法中一定会存在super(…)的调用,用户没有写编译器也会增加,但是this(…)用户不写则没有

6.代码块的顺序

我们可以看出来,显著性静态代码块,然后执行父类的代码块,最后执行之类的代码块,
这里需要注意:静态代码块只在第一次初始化的时候会执行一次,后面再创建对象的时候,不会执静态代码块。

class Animal{
    public String name;
    public  int age;

    static {
        System.out.println("Animal Static");
    }
    {
        System.out.println("Aninmal{}");
    }

    public void eat(){
        System.out.println(name + "正在吃饭");
    }

    public Animal() {
        System.out.println("Animal()");

    }


}

class Dog extends Animal
{
    static {
        System.out.println("Dog Static");
    }
    {
        System.out.println("Dog{}");
    }
    public Dog() {
        System.out.println("Dog()");

    }




}
class Cat extends Animal
{

    public Cat() {
        super();
    }


    public void speak(){
        System.out.println(name + "在喵喵喵");
    }
}
public class Test {
    public static void main(String[] args) {

        Dog dog=new Dog();
        System.out.println("===========");
        Dog dog1=new Dog();
    }
}

在这里插入图片描述

通过分析执行结果,得出以下结论:
1、父类静态代码块优先于子类静态代码块执行,且是最早执行
2、父类实例代码块和父类构造方法紧接着执行
3、子类的实例代码块和子类构造方法紧接着再执行
4、第二次实例化子类对象时,父类和子类的静态代码块都将不会再执行

6.继承方式

在我们的Java中有以下这几个继承方式
1.单继承
class A
{

}
class B extends A
{

}
在这里插入图片描述
2.多继承

class A
{

}
class B extends A
{

}
class  C extends B{
    
}

在这里插入图片描述
3.不同类继承同一个类

class A
{

}
class B extends A
{

}
class  C extends A{

}

在这里插入图片描述

7.final关键字

final关键字可以用来修饰变量,成员方法,以及类等等。

  1. 当final修饰变量的时候,表示常量,不能被改变
    一旦被概念就会报错

在这里插入图片描述
2.修饰类的时候
当final修饰类的时候,不能被继承,否则会报错
在这里插入图片描述
3.修饰方法:表示该方法不能被重写
当final修饰方法的时候,方法不能被重写,会编译错误
在这里插入图片描述

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

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

相关文章

可视化探索开源项目的 contributor 关系

引语:作为国内外最大的代码托管平台,根据最新的 GitHub 数据,它拥有超 372,000,000 个仓库,其中有 28,000,000 是公开仓。分布式图数据库 NebulaGraph 便是其中之一,同其他开源项目一样,NebulaGrpah 也有自…

用arcgis for javascript 开发一个三维地图(入门案例)

效果如图: 详细的步骤就不啰嗦介绍了,大家可以参考上一篇文章二维地图入门案例,这里只是改了一点引用和属性而已。 核心代码: SceneView 用于创建三维地图 require([“esri/Map”, “esri/views/SceneView”] 这里提一句有两种…

vue项目中的环境变量的应用

vue项目中的环境变量的应用 在Vue项目中使用环境变量可以方便地在开发、测试、生产等不同环境中进行配置,而无需修改代码。 项目根目录下创建一个.env文件或者.env.[mode]文件,其中mode表示开发、测试、生产等不同的环境,文件名的后缀部分指…

Python的分布式网络爬虫

分布式爬虫其实就是指利用多台计算机分布式地从互联网上采集数据的一种爬虫。它可以把大规模的任务分解成若干小规模的,由多台计算机并行进行处理,大大提高了效率和速度。 分布式爬虫有很多优势:解决单机爬虫效率低的问题,分布式…

【UR3系统升级到CB3.12附带URcap1.05】

【UR3系统升级到CB3.12附带URcap1.05】 1. 前言1.1 Polyscope 3.12更新须知1.2 更新步骤 2. 对 PSU 电压进行控制的步骤2.1 启动机器人电源2.2 启动机器人程序2.3 查看PSU 电压 3. Polyscope 3.12 软件下载3.1 CB 系列机器人3.2 下载软件包URUP 4. CB3 软件安装的指导4.1 连接示…

Kohl‘s百货的EDI需求详解

Kohls是一家美国的连锁百货公司,成立于1962年,总部位于美国威斯康星州的门多西。该公司经营各种商品,包括服装、鞋子、家居用品、电子产品、化妆品等,并拥有超过1,100家门店,分布在美国各地。本文将为大家介绍Kohls的E…

SDK接口远程调试【内网穿透】

文章目录 1.测试环境2.本地配置3. 内网穿透3.1 下载安装cpolar内网穿透3.2 创建隧道 4. 测试公网访问5. 配置固定二级子域名5.1 保留一个二级子域名5.2 配置二级子域名 6. 使用固定二级子域名进行访问 转发自cpolar内网穿透的文章:Java支付宝沙箱环境支付&#xff0…

stable diffusion使用入门

目录 1、stable diffusion简要说明 2、安装stable-diffusion-webui (1)下载地址 (2)执行启动命令 3、Lora模型介绍 4、模型下载 (1)Lora模型使用 (2)底座模型使用 1、stable…

初识开源接口测试工具——Postcat

Postcat 是一个强大的开源、跨平台(Windows、Mac、Linux、Browsers...)的 API 开发测试工具,支持 REST、Websocket 等协议(即将支持 GraphQL、gRPC、TCP、UDP),帮助你加速完成 API 开发和测试工作。 它适合…

OLAP和OLTP

1:OLAP和OLTP对比 数据库系统可以在广义上分为联机事务处理(Online Transaction Process,OLTP)和联机分析处理(Online Analyze Process,OLAP)两种面向不同领域的数据库,OLAP数据库也…

vue-cli的使用

什么是单页面应用程序? ​ 单页面应用程序(Single Page Application)简称SPA。指的是一个web网站中只有唯一的一个html页面,所有的功能与交互都在这个唯一的页面内完成。 什么是vue-cli? ​ vue-cli是Vue.js开发的标准工具。它简化了基于webpack创建工程化的vue项目过程。…

刷题常用算法模板(持续更新)

目录 1、二分查找2、线段树3、树状数组4、差分数组5、前缀树6、并查集7、AC自动机8、Morris遍历9、二叉树非递归遍历10、KMP11、Manacher12、快速选择 bfprt13、滑动窗口14、加强堆15、有序表16、单调栈 1、二分查找 需求:在一个有序数组中,快速查询某一…

chatgpt赋能python:Python中画笔放下:掌握Python图形编程

Python 中画笔放下:掌握 Python 图形编程 Python 是一种高级编程语言,广泛应用于数据处理、人工智能、Web 应用程序等领域。除了这些应用外,Python 还可以用于图形编程,包括绘制 2D 和 3D 图形、创建游戏和交互式应用程序等。在 …

Vue的基本使用

文章目录 Vue简介Vue的使用1.Vue指令2.过滤器3.侦听器4.计算属性 Vue简介 ​ Vue是一套用于构建用户界面的前端框架。 vue的两个特性 (1)数据驱动视图 在使用vue的页面中,vue会监听数据的变化,从而自动重新渲染页面的结构。当页面数据发生变化的时候,会自动重新渲染(数据的…

GUI JFrame实战:六一节,爱她就给她画个哆啦A梦吧

文章目录 前言技术积累容器分类主要APIGraphics图像 绘画方法实战演示1、创建哆啦A梦渲染类2、创建测试方法3、查看渲染结果 写在最后 前言 相信很多使用JAVA高级语言的同学都知道GUI图形用户界面,开发人员可以使用java.awt、javax.swing两个API绘画想要的图形并通…

蓝牙规范系列--基础篇(第一篇)

一、前言 玩过物联网的小伙伴肯定知道ESP32(一款WiFi/BT SoC),那肯定也知道蓝牙这个东西,蓝牙技术最近几年由于蓝牙耳机很火,那蓝牙技术到底是怎样的呢? 蓝牙无线技术是一种短距离的通信系统旨在替换便携式…

c++学习——友元、全局友元函数、友元类

友元 类的主要特点之一是数据隐藏,即类的私有成员无法在类的外部(作用域之外)访问。但是,有时候需要在类的外部访问类的私有成员,怎么办? 解决方法是使用友元函数,友元函数是一种特权函数,c允许这个特权函数访问私有…

python 自动编译VS项目

目录 一、python自动编译项目 1、环境变量 1) CMAKE 2)VS 2、CMAKE 生成VS项目 1) cmake 命令介绍 2)python 调用cmake 命令 3、devenv编译VS项目 1) devenv介绍 2)devenv命令行开关 3) 自动编译VS项目 一、python自动编译项目 …

04 布隆过滤器BloomFilter

是什么 布隆过滤器(英语:Bloom Filter)是 1970 年由布隆提出的。它实际上是一个很长的二进制数组一系列随机hash算法映射函数,主要用于判断一个元素是否在集合中。通常我们会遇到很多要判断一个元素是否在某个集合中的业务场景&a…

C++ 和机器学习:使用 C++ 执行 ML 任务的简介

C 和机器学习:使用 C 执行 ML 任务的简介 介绍 C 是一种高性能编程语言,非常适合机器学习( ML ) 任务。尽管它在 ML 中可能不像 Python 或 R 那样流行,但它在速度和内存效率方面具有优势。 在本文中,我们将概述使用 C 执行 ML 任务…