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

目录

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("会讲课");}
​@Overridevoid eat() {System.out.println("讲课费体力,所以要多吃饭!");}
​@Overridevoid 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;//学号
​
​@Overridepublic 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;}@Overridepublic 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;}
    ​@Overridevoid work() {System.out.println("控制项目进度");}
    ​@Overridepublic 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.mzph.cn/news/229039.shtml

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

相关文章

C++类与对象 (上)

目录 前言: 类和对象的理解 类的引入 类的定义与使用方式 访问限定符 类的两种定义方式 成员变量的命名规则 类的作用域 类的实例化 类对象模型 计算类对象的大小 类对象的存储方式 this指针 前言: C语言是面向过程的,关注的是过…

基于Java SSM框架实现智能停车场系统项目【项目源码+论文说明】

基于java的SSM框架实现智能停车场系统演示 摘要 本论文主要论述了如何使用JAVA语言开发一个智能停车场管理系统,本系统将严格按照软件开发流程进行各个阶段的工作,采用B/S架构,面向对象编程思想进行项目开发。在引言中,作者将论述…

图扑物联助力打造现代化绿色智慧港口

“智慧港口”是以现代化基础设施设备为基础,以云计算、大数据、物联网、移动互联网、智能控制等新一代信息技术与港口运输业务深度融合为核心,以港口运输组织服务创新为动力,以完善的机制、法律法规、标准规范、发展政策为保障。能够在更高层…

Element 介绍

Element 介绍 Vue 快速入门 Vue 常见组件 表格 分页组件 其他自己去看吧 链接: 其他组件

设计模式——装饰模式(结构型)

引言 装饰模式是一种结构型设计模式, 允许你通过将对象放入包含行为的特殊封装对象中来为原对象绑定新的行为。 假设你正在开发一个提供通知功能的库, 其他程序可使用它向用户发送关于重要事件的通知。 库的最初版本基于 通知器Notifier类,…

Oracle RAC环境下redo log 文件的扩容

环境: 有一个2节点RAC每一个节点2个logfile group每一个group含2个member每一个member的大小为200M 目标:将每一个member的大小有200M扩充到1G。 先来看下redo log的配置: SQL> select * from v$log;GROUP# THREAD# SEQUENCE# …

JUC并发编程 06——Synchronized与锁升级

一.Java对象内存布局和对象头 在HotSpot虚拟机里,对象在堆内存中的存储布局可以划分为三个部分:对象头(Header) 、实例数据 (Instance Data) 和 对文填充 (Padding)。 对象内部结构分为:对象头、实例数据、对齐填充(保证8个字节的…

软件设计师——计算机组成原理(三)

📑前言 本文主要是【计算机组成原理】——软件设计师——计算机组成原理的文章,如果有什么需要改进的地方还请大佬指出⛺️ 🎬作者简介:大家好,我是听风与他🥇 ☁️博客首页:CSDN主页听风与他 …

runCatching异常捕获onSuccess/onFailure返回函数,Kotlin

runCatching异常捕获onSuccess/onFailure返回函数,Kotlin fun test(a: Int, b: Int) {runCatching {a / b}.onSuccess {println("onSuccess: $it")return ok(it)}.onFailure {println("onFailure: $it")return fail(it)} }fun ok(o: Any) {prin…

echarts地图的常见用法:基本使用、区域颜色分级、水波动画、区域轮播、给地图添加背景图片和图标、3d地图、飞线图

前言 最近几天用echarts做中国地图,就把以前写的demo:在vue中实现中国地图 拿来用,结果到项目里直接报错了,后来发现是因为版本的问题,没办法只能从头进行踩坑了。以下内容基于vue3 和 echarts 5.32 基本使用 获取地…

Linux环境下HTTP请求的代码详解与实例

嘿,Linux狂热者们,是时候让我们在这个充满激情的平台上探索一下HTTP协议的奥秘了。我知道,对于这个我们每天都在使用,但却可能没深入了解过的HTTP,你们一定充满了好奇和期待。那么,让我们一起踏上这趟探索之…

教师如何维护学生的自尊心

作为教师,我们不仅要传授知识,更要关心学生的身心健康,特别是他们的自尊心。自尊心是个人自我价值的重要体现,对学生的学习、生活和未来的发展都有深远的影响。因此,维护学生的自尊心是教师的重要责任。 教师要尊重每…

波奇学Linux:进程终止

写时拷贝底层原理图 子进程谁先运行,由调度器决定 进程退出场景 代码运行完毕,结果正确:有返回值,返回0 代码运行完毕,结果不正确:有返回值,返回非0 代码异常终止。没有返回值 return 0的…

十七、如何将MapReduce程序提交到YARN运行

1、启动某个节点的某一个用户 hadoopnode1:~$ jps 13025 Jps hadoopnode1:~$ yarn --daemon start resourcemanager hadoopnode1:~$ jps 13170 ResourceManager 13253 Jps hadoopnode1:~$ yarn --daemon start nodemanager hadoopnode1:~$ jps 13170 ResourceManager 15062 Jp…

【小沐学Python】Python实现通信协议(grpc)

文章目录 1、简介2、安装3、定义接口4、编译生成5、代码编写5.1 服务端5.2 客户端5.3 运行测试 结语 1、简介 https://grpc.io/docs/what-is-grpc/introduction/ https://github.com/grpc/grpc gRPC 是一种现代、开源、高性能的远程过程调用 (RPC) 可以…

Python生成器(Generator)的应用场景和使用(继续更新...)

学习网页: Welcome to Python.orghttps://www.python.org/https://www.python.org/ Python生成器(Generator) 生成器在Python中有很多应用场景,以下是一些常见的应用场景: 处理大数据量和耗时操作的场景&#xff…

【STM32】STM32学习笔记-对射式红外传感器计次 旋转编码器计次(12)

00. 目录 文章目录 00. 目录01. NVIC相关函数1.1 NVIC_PriorityGroupConfig函数1.2 NVIC_PriorityGroup类型1.3 NVIC_Init函数1.4 NVIC_InitTypeDef类型 02. 外部中断相关API2.1 GPIO_EXTILineConfig2.2 EXTI_Init2.3 EXTI_GetITStatus2.4 EXTI_ClearITPendingBit2.5 中断回调函…

大数据技术之 Kettle(PDI)

Kettle 第一章 Kettle概述1.1、ETL简介1.2、Kettle简介1.3、作业 和 转换 概念1.4、核心组件1.5、下载安装 第二章 控件使用2.1、初体验:csv 转换 excel 示例2.2、转换2.2.1、输入控件2.2.1.1、表输入 2.2.2、输出控件2.2.2.1、表输出2.2.2.2、更新&插入/更新2.…

【数据结构—队列的实现】

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录 前言 一、队列 1.1队列的概念及结构 二、队列的实现 2.1头文件的实现—Queue.h 2.2源文件的实现—Queue.c 2.3源文件的测试—test.c 三、测试队列实际数据的展示 3.…

Python语言学习笔记之八(文件IO)

本课程对于有其它语言基础的开发人员可以参考和学习,同时也是记录下来,为个人学习使用,文档中有此不当之处,请谅解。 1、什么是文件I/O 在Python中,文件IO(输人/输出)是指与文件进行交互的过程。这包括读…