面向对象三大特征——继承

news2024/11/27 6:17:31

目录

1. 概述

2. 继承的限制

2.1 单继承

2.2 访问修饰符

2.3 . final

3. 重写

4. super

4.1super的作用

4.2访问父类的成员和被重写方法

4.3调用父类的构造器


1. 概述

多个类中存在相同属性和行为时,将这些内容抽取到单独一个类中,那么就无需在多个类中定义这些相同属性和行为,只要继承那个类即可。

 

继承

继承

Teacher

Person

Student

在 Java 中通过extends关键字可以实现类与类的继承。

public class Person {
    String name;
    int age;
​
    void eat() {
        System.out.println("能吃饭");
    }
​
    void sleep() {
        System.out.println("能睡觉");
    }
}
​
​
public class Teacher extends Person {
    String job;
​
    void educate() {
        System.out.println("会讲课");
    }
}
​
public class Student extends Person {
    String major;
​
    void study() {
        System.out.println("会学习");
    }
}  
​
/***************************************/
public class PersonTest {
    public static void main(String[] args) {
        Teacher teacher = new Teacher();
        Student student = new Student();
        teacher.name = "马老师";
        teacher.eat();
        student.sleep();
    }
}
/**********************************************/
​
public class Person {
    /*
     *  父类中私有的成员是不能继承给子类的
     */
    private String name;
    int age;
​
    public String getName() {
        return name;
    }
​
    public void setName(String name) {
        this.name = name;
    }
        ......
}
​
public class PersonTest {
    public static void main(String[] args) {
        Teacher teacher = new Teacher();
        Student student = new Student();
        // 报错,父类中私有的成员是不能继承给子类的
        teacher.name = "马老师";
        // 父类中公有方法是可以继承给子类的
        teacher.setName("马老师");
        System.out.println(teacher.getName());
    }
}

image-20230205170030860

  • 继承的格式:class A extends B { }

    • A:子类、派生类、subclass

    • B:父类、超类、基类、superclass

      • 体现:一旦子类A继承父类B以后,子类A中就获取到了B类中所有的公开的属性和方法。特别的,父类中声明为private的属性和方法,子类无法继承。

      • 子类继承父类以后,还可以声明自己特有的属性或者方法:实现功能的扩展。

      • 子类和父类的关系,不同于子集和集合的关系。

  • 优缺点

    • 优点:

      • 提高了代码的复用性,减少代码冗余

      • 提高了代码的可维护性即可扩展性

      • 是多态的前提

    • 缺点:

      • 提高了代码的耦合性

耦合性:事物与事物之间的依赖关系,互相影响的程度

开发原则:

  • 高内聚:一个对象自身可以完成所有的东西

  • 低耦合:对其他代码的依赖性非常

2. 继承的限制

2.1 单继承

image-20230205162209565

Java支持单继承,支持多层继承,不支持多重继承。

  • 单继承:一个子类只能继承一个父类(一个孩子只能有一个亲爹)

  • 多层继承:A类可以继承B类,B类可以继承C类,A类中拥有B、C类中的所有属性和方法。

  • 如果我们没有显式的声明一个类的父类的话,则此类继承于java.lang.Object类,意味着,所有java类都具有java.lang.Object类声明的功能

2.2 访问修饰符

修饰符同类中同一个包中(子类和无关类)不同包(子类)不同包(无关类)
public✔️✔️✔️✔️
protected✔️✔️✔️
default✔️✔️
private✔️
  • 含义:

    • public(公共的)接口访问权限:使用public关键字,就意味着被声明的成员或方法对所有类都是可以访问的。

    • protected(受保护的)继承访问权限:使用protected关键字,就意味着被声明的成员或方法,在子类以及相同包内的其他类都是可以访问的。

    • default(默认的)包访问权限:即不写任何关键字,就意味着相同包内的其他类(包括子类)可以访问,包外都不可以访问。

    • private(私有的)无法访问:使用private关键字,就意味着被声明的成员或方法,除了本类,其他任何类都无法访问。

    • 作用:访问权限范围越小,安全性越高

    • 对于类的修饰,我们只能使用public 和 缺省。

2.3 . final

  • final关键字:可以修饰类、方法、变量。

  • 修饰类:表示一个最终类,表示不能有子类【不能被其他类继承】

  • 修饰方法:表示一个最终方法,【该方法不能被重写】

  • 修饰变量:表示一个最终变量,该【变量变成了常量】,就只能赋值一次,不能二次赋值了,变量名大写

  • String类是否可以被继承?

3. 重写

  • 为什么需要重写?父类的方法对于子类来说并不适用。

  • 子类中定义了与父类中一模一样的方法声明,但是实现方式不同,称为方法的重写。

  • override / overwrite覆写、覆盖

  • 重写:子类继承父类以后,可以对父类中同名同参数的方法,进行覆盖操作

  • 应用:重写以后,当创建子类对象以后,通过子类对象调用父类中的同名同参方法时,实际执行的是子类重写父类的方法

  • 约定俗称:子类中的叫重写的方法,父类中的叫被重写的方法

public class Teacher extends Person {
    String job;
​
    void educate() {
        System.out.println("会讲课");
    }
​
    @Override
    void eat() {
        System.out.println("讲课费体力,所以要多吃饭!");
    }
​
    @Override
    void sleep() {
        System.out.println("讲课费体力,所以要多休息!");
    }
}
/*********************************************************/
public class PersonTest {
    public static void main(String[] args) {
        Teacher teacher = new Teacher();
        teacher.eat();
        teacher.sleep();
    }
}
  • 注意事项:

    • 子类重写方法的方法名和形参列表与父类被重写方法的方法名和形参列表形同

    • 子类重写方法的权限修饰符不小于父类重写的方法的权限修饰符

      • 特殊情况:子类不能重写父类中声明为private权限的方法

    • 返回值类型

      • 父类被重写方法的返回值类型是void,则子类重写的方法的返回值类型只能是void

      • 父类被重写方法的返回值是基本数据类型,则子类重写的方法的返回值必须是相同的基本数据类型

      • 父类被重写方法的返回值是A类型,则子类重写的方法的返回值可以是A类或者A类的子类,比入Object与String

重写 & 重载 区别:(高频面试题)

  • 重写:在子父类中,方法名相同,参数列表相同,与返回值类型有关(相同)。

  • 重载:在同一个类中,方法名相同,参数列表不同,与返回值类型无关。

方法重写的检查:

  • 关键字:@Override

  • 让编译器帮助我们检查,当前的这个方法,究竟是否是对父类方法的重写。

说明:方法本身还是属于父类,只是在子类中重新实现了这个方法的内容。

  • 注意:子类与父类中同名同参数的方法必须同时声明为非static的(即为重写),或者同时声明为 static的(不是重写)。因为static方法是属于类的,子类无法覆盖父类的方法。

4. super

4.1super的作用

  • 在Java类中使用super来调用父类中的指定操作:

    • super可用于访问父类中定义的属性

    • super可用于调用父类中定义的成员方法

    • super可用于在子类构造器中调用父类的构造器

    • 示例:

public class Person {
    String name;
    int age;
    int id = 1001;//身份证号
​
    public void eat() {
        System.out.println("人:吃饭");
    }
}
​
public class Student extends Person {
​
    String major;
     int id = 1002;//学号
​
​
     @Override
     public void eat() {
         System.out.println("学生:多吃有营养的食物");
     }
​
     void info() {
         System.out.println("学生的id是:"+id);
     }
}
​
public class StudentTest {
    public static void main(String[] args) {
         Student student = new Student();
         student.info();
    }
}

4.2访问父类的成员和被重写方法

  • 在子类中,既可以访问子类的成员变量,也可以访问父类的成员变量。

  • 在子父类中定义了同名的成员变量,在子类中,根据就近原则来访问,因此父类的同名属性会被隐藏,但可以通过super关键字来显示访问父类成员。

  • 当子类重写了父类中的方法以后,我们想要在子类中方法中调用父类中被重写的方法时,则必须显式的使用super.方法的方式,表明调用的是父类中被重写的方法

void info() {
         System.out.println("学生的id是:"+this.id);
         System.out.println("父类的id是:"+super.id);
         // 调用重写之后的方法
         eat();
         // 调用父类未重写方法
         super.eat();
     }

4.3调用父类的构造器

  • 父类的构造方法不能被继承

    • 父类的构造方法需要和父类的类名一致、子类的构造方法需要和子类类名一致,父类和子类的类名不一样。因此无法继承,名称有冲突。

    • 子类的构造方法必须调用父类的构造方法

    • 当生成子类对象时,Java 默认首先调用父类的不带参数的构造方法。

        // 父类无参构造
          public Person() {
              System.out.println("父类无参构造");
          }
      ​
        // 子类无参构造
          public Student() {
              super();
              System.out.println("子类无参构造");
          }
      ​
          public class StudentTest {
          public static void main(String[] args) {
              Student student = new Student();
          }
      }

  • 如果父类没有无参构造,子类构造方法中必须显示调用父类构造方法,通过super();,该语句必须作为构造方法中的第一条执行语句。

       // 父类无参构造
        //  public Person() {
        //   System.out.println("父类无参构造");
        //  }
    ​
        // 父类有参构造
        public Person(String name, int age) {
            this.name = name;
            this.age = age;
        }
    ​
      // 子类有参构造
        public Student(String name, int age, String major) {
            super(name, age);
            this.major = major;
        }
     @Override
        public String toString() {
            return "Student{" +
                    "name='" + name + '\'' +
                    ", age=" + age +
                    ", pid=" + super.id +
                    ", major='" + major + '\'' +
                    ", id=" + id +
                    '}';
        }
    ​
    public class StudentTest {
        public static void main(String[] args) {
            Student student = new Student("小明", 18, "Computer");
            System.out.println(student);
        }
    }
     总结:
      /*
       * super关键字的使用
       *  1.super理解为:父类的
       *  2.super可以用来调用:属性、方法、构造器
       *  3.super的使用 调用属性和方法
       *    3.1 我们可以在子类的方法或构造器中,通过super.属性或者super.方法的方式,显示的调用
       *    父类中声明的属性或方法。但是,通常情况下,我们习惯省略super.
       *    3.2 特殊情况:当子类和父类中定义了同名的属性时,我们要想在子类中调用父类的属性,则必须显式
       *    的使用super.属性的方式,表明调用的是父类中的属性
       *    3.3 特殊情况,当子类重写了父类中的方法以后,我们想要在子类中方法中调用父类中被重写的方法时,
       *   则必须显式的使用super.方法的方式,表明调用的是父类中被重写的方法
       *  4.super调用构造器
       *    4.1 我们可以在子类的构造器中显式的使用"super(形参列表)"的方式,调用父类中声明的指定构造器
       *    4.2 super(形参列表)的使用,必须声明在子类构造器的首行!
       *    4.3 在类的多个构造器中,至少有一个类的构造器中使用了super(形参列表)调用父类中的构造器
       *        4.4 super的追溯不仅限于直接父类
       *        4.5 super和this的用法相像,this代表本类对象的引用,super代表父类的内存空间的标识
       */

    image-20230205175313681

    • 子类对象实例化的全过程

      • 1.从结果上看(继承性)

      • 子类继承父类以后,就获取了父类中声明的属性和方法 ,创建子类的对象,在堆空间中,就会加载父类中声明的属性

      • 2.从过程上看

      • 当我们通过子类的构造器创建子类对象时,我们一定会直接或者间接的调用父类的构造器,进而调用父类的父类构造器,

      • 直到调用了java.lang.Object类中空参的构造器位置,正是因为加载过所有的父类的结构,所以才可以看到内存中有

      • 了父类中的结构,子类对象才可以进行调用。

      • 明确:虽然创建了子类对象时调用了父类的构造器,但是自始至终就只创建过一个对象,即为new的子类对象

    练习:

    • 程序员类:

      • 属性:姓名、工号、工资

      • 方法:敲代码

    • 项目经理类:

      • 属性:姓名、工号、工资、奖金

    • 方法:控制项目进度

    定义程序员类和项目经理类

    public class Programmer {
        String name;
        int id;
        double salary;
    ​
        public Programmer(String name, int id, double salary) {
            this.name = name;
            this.id = id;
            this.salary = salary;
        }
    ​
        void work() {
            System.out.println("会敲代码!");
        }
    }
    ​
    ​
    public class ProjectManager extends Programmer {
        double bonus;
    ​
        public ProjectManager(String name, int id, double salary, double bonus) {
            super(name, id, salary);
            this.bonus = bonus;
        }
    ​
        @Override
        void work() {
            System.out.println("控制项目进度");
        }
    ​
        @Override
        public String toString() {
            return "ProjectManager{" +
                    "name='" + name + '\'' +
                    ", id=" + id +
                    ", salary=" + salary +
                    ", bonus=" + bonus +
                    '}';
        }
    }
    ​
    public class ProgrammerTest {
        public static void main(String[] args) {
            ProjectManager xiaoming = new ProjectManager("小明", 3, 24000, 3500);
            System.out.println(xiaoming);
            xiaoming.work();
        }
    }

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

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

相关文章

DeciLM-7B:突破极限,高效率、高精准度的70亿参数AI模型

引言 在人工智能领域,语言模型的发展速度令人瞩目。Deci团队最近推出了一款具有革命性意义的语言模型——DeciLM-7B。这款模型在速度和精确度上都实现了显著的突破,以其70亿参数的规模,在语言模型的竞争中脱颖而出。 Huggingface模型下载&am…

C# 基本桌面编程(二)

一、前言 本章为C# 基本桌面编程技术的第二节也是最后一节。前一节在下面这个链接 C# 基本桌面编程(一)https://blog.csdn.net/qq_71897293/article/details/135024535?spm1001.2014.3001.5502 二、控件布局 1 叠放顺序 在WPF当中布局,通…

我与Datawhale的故事之长篇

Datawhale成员 作者:Datawhale团队成员 前 言 上周五周年文章发出后大家反响比较热烈: 我们与Datawhale背后的故事! 本期给大家带来三篇长篇回忆 胡锐峰 我与Datawhale的故事 题记:我和你的相遇就像春风拂面,就像夏雨…

[原创][R语言]股票分析实战[2]:周级别涨幅趋势的相关性

[简介] 常用网名: 猪头三 出生日期: 1981.XX.XX QQ联系: 643439947 个人网站: 80x86汇编小站 https://www.x86asm.org 编程生涯: 2001年~至今[共22年] 职业生涯: 20年 开发语言: C/C、80x86ASM、PHP、Perl、Objective-C、Object Pascal、C#、Python 开发工具: Visual Studio、D…

UE5 C++(三)— 基本用法(生命周期、日志、基础变量)

文章目录 生命周期日志打印Outlog打印屏幕打印 基础变量类型FString、FName 和 FText,三者之间的区别 基础数据类型打印 忘记说了每次在Vscode修改后C脚本后,需要编译一下脚本,为了方便我是点击这里编译脚本 生命周期 Actor 生命周期官方文档…

20--Set集合

1、Set集合 1.1 Set集合概述 java.util.Set接口和java.util.List接口一样,同样继承自Collection接口,它与Collection接口中的方法基本一致,并没有对Collection接口进行功能上的扩充,只是比Collection接口更加严格了。与List接口…

wordpress安装之正式开始安装wordpress

1、拉取wordpress镜像 docker pull wordpress 2、启动容器 启动容器,设置容器名为wordpress2并把80端口映射到宿主机的9988端口 docker run -it --name wordpress2 -p 9988:80 -d wordpress 3、查看容器状态 docker ps 4、安装wordpress博客程序 因为我们前面启…

SLAM算法与工程实践——相机篇:传统相机使用(3)

SLAM算法与工程实践系列文章 下面是SLAM算法与工程实践系列文章的总链接,本人发表这个系列的文章链接均收录于此 SLAM算法与工程实践系列文章链接 下面是专栏地址: SLAM算法与工程实践系列专栏 文章目录 SLAM算法与工程实践系列文章SLAM算法与工程实践…

关于找不到XINPUT1_3.dll,无法继续执行代码问题的5种不同解决方法

一、xinput1_3.dll的作用 xinput1_3.dll是Windows操作系统中的一款动态链接库文件,主要用于支持游戏手柄和游戏输入设备。这款文件属于Microsoft Xbox 360兼容性库,它包含了与游戏手柄和其他输入设备相关的功能。在游戏中,xinput1_3.dll负责…

计算机操作系统-第十八天

目录 进程调度时机 补充知识 进程调度的方式 非剥夺调度方式 剥夺调度方式 进程的切换与过程 本节思维导图 进程调度时机 进程调度(低级调度),即按照某种算法从就绪队列中选择一个进程为其分配处理机。 共有两种需要进行进程调度与…

CCNP课程实验-OSPF-CFG

目录 实验条件网络拓朴需求 配置实现基础配置1. 配置所有设备的IP地址 实现目标1. 要求按照下列标准配置一个OSPF网络。 路由协议采用OSPF,进程ID为89 ,RID为loopback0地址。3. R4/R5/R6相连的三个站点链路OSPF网络类型配置成广播型,其中R5路…

PMP项目管理 - 资源管理

系列文章目录 PMP项目管理 - 质量管理 PMP项目管理 - 采购管理 PMP项目管理 - 资源管理 PMP项目管理 - 风险管理 现在的一切都是为将来的梦想编织翅膀,让梦想在现实中展翅高飞。 Now everything is for the future of dream weaving wings, let the dream fly in…

DISC-MedLLM—中文医疗健康助手

文章目录 DISC-MedLLM 项目介绍数据集构建重构AI医患对话知识图谱生成问答对医学图谱构建图谱生成QA对 人类偏好引导的对话样例其他数据MedMCQA通用数据 模型微调评估评估方式评估结果 总结 DISC-MedLLM 项目介绍 DISC-MedLLM 是一个专门针对医疗健康对话式场景而设计的医疗领…

「斗破年番」小医仙黑皇城遭调戏,五品丹换药材,获取菩提涎消息

Hello,小伙伴们,我是拾荒君。 《斗破苍穹年番》的第75集已经更新了,喜欢这部国漫的小伙伴应该都去观看了吧,拾荒君也是看了看这一集。在这一集中,萧炎成功地帮助吴昊等人摆脱了鹰爪老人的围困,然后便前往了黑皇城。 黑…

openGauss学习笔记-163 openGauss 数据库运维-备份与恢复-导入数据-使用COPY FROM STDIN导入数据-简介

文章目录 openGauss学习笔记-163 openGauss 数据库运维-备份与恢复-导入数据-使用COPY FROM STDIN导入数据-简介163.1 关于COPY FROM STDIN导入数据163.2 CopyManager类简介163.2.1 CopyManager的继承关系163.2.2 构造方法163.2.3 常用方法 openGauss学习笔记-163 openGauss 数…

torch中张量与数据类型的介绍

PyTorch张量的定义介绍 PyTorch最基本的操作对象是张量,它表示一个多维数组,类似NumPy的数组,但是前者可以在GPU上加速计算 初始化张量 ttorch.tensor([1,2]) # 创建一个张量 print(t) t.dtype #打印t的数据类型为torch.int…

Vue 指定class区域增加水印显示(人员姓名+时间)

效果 代码,存放位置 /utils/waterMark.js //waterMark.js文件let waterMark {}let setWaterMark (str,str1) > {let id 1.23452384164.123412416;if (document.getElementById(id) ! null) {//ui-table是table上的一个样式,一般水印显示在这个tab…

visual stdio code运行js没有输出

visual code运行js没有输出 先Debug file 然后右键直接run code就会输出了 插件的安装 visual stdio code插件安装 c qt wordle游戏实现

RK3568平台(网络篇)添加网络交换芯片RTL8306M

一.硬件原理图 分析: 该交换芯片支持I2C、SPI、mdio通信,但是看ast1520的uboot代码采用的是mdio去通信phy芯片的,所以暂时也先采用mdio的方式,需要配置相应的引脚才可以配置成mdio通信模式,具体的配置硬件工程师解决。…

代码随想录算法训练营Day4 | 24.两两交换链表中的节点、19.删除链表的倒数第 N 个节点、面试题. 链表相交、142.环形链表II

LeetCode 24 两两交换链表中的节点 本题要注意的条件: 遍历终止条件改变引用指向的时候,需要保存一些节点记录 为了更好的操作链表,我定义了一个虚拟的头节点 dummyHead 指向链表。如下图所示 既然要交换链表中的节点,那么肯定…