当前位置:

首页 > 编程开发 > Java继承与多态的概念是什么及怎么实现

Java继承与多态的概念是什么及怎么实现

一、继承1、继承的概念继承机制:是面向对象程序设计是代码可以复用的最重要手段,允许程序员在保持原有类特性的基础上进行扩展,增加新的功能,产生的新类,成为派生类/子类。继承主要解决的问题是:共性的抽取,实现代码的复用。2、继承的语法表示类与类的继承关系,需要借助关键字extends,语法如下:修饰符class子类/派生类extends父类/基类/超类{//…………}子类会将父类的成员变量或者成员方法继承到子类中子类继承父类后,必须添加自己特有的成员,体

本文目录

      一、继承

      1、继承的概念

      继承机制:是面向对象程序设计是代码可以复用的最重要手段,允许程序员在保持原有类特性的基础上进行扩展,增加新的功能,产生的新类,成为派生类/子类。继承主要解决的问题是:共性的抽取,实现代码的复用。

      Java继承与多态的概念是什么及怎么实现

      2、继承的语法

      表示类与类的继承关系,需要借助关键字extends,语法如下:

      修饰符  class  子类/派生类   extends  父类/基类/超类{

             //…………

      }

      • 子类会将父类的成员变量或者成员方法继承到子类中

      • 子类继承父类后,必须添加自己特有的成员,体现与基类的不同

      3、父类成员访问

      (1)子类中访问父类的成员变量
      • 不存在同名成员变量时,正常访问就行

      • 存在同名成员变量,使用(super.变量名)实现父类成员变量的访问

      public class Base {
          int a;
          int b;
          int c;
      } 
      public class Derived extends Base{
          int a; // 与父类中成员a同名,且类型相同
          char b; // 与父类中成员b同名,但类型不同
          public void method(){
              a = 100; // 访问父类继承的a,还是子类自己新增的a?
              b = 101; // 访问父类继承的b,还是子类自己新增的b?
              c = 102; // 子类没有c,访问的肯定是从父类继承下来的c
          }
      }
      • 访问成员变量时,优先访问自己的成员变量。即同名成员变量访问时,优先访问子类的。即:子类将父类的成员隐藏了

      • 成员变量访问遵循就近原则,自己有优先自己的,自己没有则向父类中查找。

      (2)子类中访问父类的成员方法
      • 成员方法名字不同,正常访问即可

      • 成员方法名字相同,可以通过 【super.方法名】访问同名父类方法

      如果父类和子类同名方法的参数列表不同(重载),根据调用方法时传递的参数选择合适的方法访问。

      如果父类和子类的同名方法原型一致,则访问子类的

      4、super关键字

      super关键字的主要作用是:在子类方法中访问父类的同名成员。(只能在非静态方法中使用)

      public class Base {
          int a;
          int b;
          public void methodA(){
              System.out.println("Base中的methodA()");
          }
          public void methodB(){
              System.out.println("Base中的methodB()");
      }
      public class Derived extends Base{
          int a; 
          char b; 
          // 与父类中methodA()构成重载
          public void methodA(int a) {
              System.out.println("Derived中的method()方法");
          }
          // 与父类中methodB()构成重写
          public void methodB(){
              System.out.println("Derived中的methodB()方法");
          }
          public void methodC(){
              a = 100; // 等价于: this.a = 100;
              b = 101; // 等价于: this.b = 101;
              // 访问父类的成员变量时,需要借助super关键字
              // super是获取到子类对象中从基类继承下来的部分
              super.a = 200;
              super.b = 201;
              methodA(); // 没有传参,访问父类中的methodA()
              methodA(20); // 传递int参数,访问子类中的methodA(int)
              methodB(); // 直接访问,则永远访问到的都是子类中的methodA(),基类的无法访问到
              super.methodB(); // 访问基类的methodB()
          }
      }

      5、子类构造方法

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

      public class Base {
          public Base(){
              System.out.println("Base()");
          }
      }
      public class Derived extends Base{
          public Derived(){
         // super(); // 注意子类构造方法中默认会调用基类的无参构造方法:super(),
         // 用户没有写时,编译器会自动添加,而且super()必须是子类构造方法中第一条语句,
         // 并且只能出现一次
              System.out.println("Derived()");
          }
      }
      • 若父类显示定义无参或者默认的构造函数,在子类的构造方法第一行默认有隐含的super()调用。

      • 父类定义带参数的构造方法时,编译器不会再给子类生成默认的构造方法,需要子类显式定义,并在子类构造方法中调用合适的父类构造方法

      • 子类构造方法中,super(……)调用父类构造方法,必须是子类构造方法的第一条语句

      • super(……)只能在子类构造方法中出现一次,并且不能和this同时出现

      6、super和this

      super和this都可以在成员方法中用来访问成员变量和调用其他的成员函数,都可以作为构造方法的第一条语句,那么它们之间的区别是什么?

      (1)相同点

      • 都是java的关键字

      • 只能在类的非静态方法中使用,用来访问非静态成员方法和属性

      • 必须作为构造方法中的第一条语句,并且不能同时存在

      (2)不同点

      • this是当前对象的引用,super是子类对象中从父类继承的成员的引用

      • this是非静态成员方法的一个隐藏参数,super不是隐藏参数

      • 在构造方法中:this()用于调用本类的构造方法,super()用来调用父类构造方法,两种调用不能同时出现在构造方法中

      • 子类的构造方法中一定会存在super()的调用,但是this()用户不写就没有

      7、代码块执行顺序

      【普通类】

      • 静态代码块先执行,并且只执行一次,在类加载阶段执行

      • 当有对象创建时,才会执行实例代码块,最后执行构造方法

      【继承关系上的执行顺序】

      • 父类静态代码块优先于子类静态代码块执行,最早执行

      • 父类实例代码块和父类构造方法紧接着执行

      • 子类的实例代码块和构造方法最后执行

      • 第二次实例化子类对象时,父类和子类的静态代码块不会再执行

      8、继承方式

      【注】Java中不支持多继承

      Java继承与多态的概念是什么及怎么实现

      • super只能指代直接父类

      • 继承关系一般不超过三层

      9、final关键字

      • 修饰变量时,表示常量(不能修改)

      • 修饰类:此类不能被继承

      • 修饰方法:表示方法不能被重写

      10、继承和组合

      组合和继承都能实现代码的复用。组合没有涉及到特殊的语法(如extend关键字),仅仅是将一个类的实例作为另一个类的属性。

      • 继承表示对象与对象之间是is-a的关系

      • 组合表示对象与对象之间是has-a的关系

      一般建议:能用组合尽量用组合

      二、多态

      1、向上转型

      通过父类类型的引用调用子类对象,向上转型是安全的

      【发生向上转型的时机】

      • 直接赋值

      • 方法传参

      • 函数的返回值

      public class TestAnimal {
          // 2. 函数传参:形参为父类引用,可以接收任意子类的对象
          public static void eatFood(Animal a) {
              a.eat();
          }
       
          // 3. 作返回值:返回任意子类对象
          public static Animal buyAnimal(String var) {
              if ("狗" == var) {
                  return new Dog("狗狗", 1);
              } else if ("猫" == var) {
                  return new Cat("猫猫", 1);
              } else {
                  return null;
              }
          }
       
          public static void main(String[] args) {
              Animal cat = new Cat("元宝", 2); // 1. 直接赋值:子类对象赋值给父类对象
              Dog dog = new Dog("小七", 1);
          }
      }

      优缺点:

      • 优点:让代码更加灵活

      • 缺点:不能访问到子类特有的方法

      2、重写

      函数名相同、参数列表相同、返回值相同或是【协变类型】(父子类关系)

      【方法重写的规则】

      • 重写的方法访问权限不能比父类中原方法的的权限低;

      • 父类中被static、private、final修饰的方法、构造方法不能被重写;

      • 重写的方法,可以使用 @override 注解来显示指定(帮助我们进行一些合法性的检验)。比如方法名拼写错误,编译会报错;

      • 重写的返回值类型可以不同,但是必须具有父子关系。

      • 被final修饰的方法,叫做密封方法,该方法不能被重写。

      • 外部类只能是public或者默认权限

      【动态绑定和静态绑定】

      • 动态绑定:发生的条件(1、父类引用引用子类对象;2、通过父类引用,可以访问到子类中的方法)。后期绑定,即在编译时不能确定方法的行为,需要等到程序运行时,才能够确定调用哪个类的方法;

      • 静态绑定:前期绑定,编译时,根据用户传递的参数类型确定具体的调用方法(函数重载)

      3、多态

      一个引用调用同一个方法,可以表现出不同的形式,这种思想称为多态。在父类的构造方法中不要调用重写的方法。

      【多态实现的条件】

      • 必须在继承条件下

      • 子类对父类方法进行重写

      • 通过父类引用调用重写的方法

      • 发生了向上转型

      public class Animal(){
          String name;
          int age;
          public Animal(String name, int age){
              this.name = name;
              this.age = age;
          }
          public void eat(){
              System.out.println(name + "吃饭");
              }
      }
      public class Cat extends Animal{
          public Cat(String name, int age){
              super(name, age);
          }
          @Override
          public void eat(){
              System.out.println(name+"吃鱼~~~");
          }
      }
      public class Dog extends Animal {
          public Dog(String name, int age){
              super(name, age);
          }
          @Override
          public void eat(){
              System.out.println(name+"吃骨头~~~");
          }
      }
      public class TestAnimal {
          // 编译器在编译代码时,并不知道要调用Dog 还是 Cat 中eat的方法
         // 等程序运行起来后,形参a引用的具体对象确定后,才知道调用那个方法
         // 注意:此处的形参类型必须时父类类型才可以
          public static void eat(Animal a){
              a.eat();
          }
          public static void main(String[] args) {
              Animal animal1 = new Cat("元宝",2);
              Animal animal2 = new Dog("小七", 1);
              eat(animal1);
              eat(animal2);
          }
      }

      【注】Java中所有的类默认继承Object类

      本站声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系bd@zhengruan.com
      作者最新文章
      编程开发 Java
      相关文章 更多
      Java单元测试入门:使用JUnit 5编写第一个测试用例
      Java单元测试入门:使用JUnit 5编写第一个测试用例

      面向初学者的JUnit 5实用入门指南。从测试概念、Maven依赖配置,到手把手编写首个单元测试用例及断言验证,助你掌握Java单元测试的核心流程。

      Java变量未初始化报错解析:局部变量与成员变量默认值差异
      Java变量未初始化报错解析:局部变量与成员变量默认值差异

      深入解析Java中局部变量未初始化编译报错与成员变量自动赋予默认值的机制差异,涵盖JVM内存分配、编译期确定性赋值检查与实际排查修复方案。

      Java获取当前时间并格式化输出:DateTimeFormatter与SimpleDateFormat
      Java获取当前时间并格式化输出:DateTimeFormatter与SimpleDateFormat

      详细讲解在Java中获取当前系统时间并进行格式化输出的两种核心方案:基于Java 8全新日期时间API的DateTimeFormatter与传统遗留的SimpleDateFormat,包含完整代码示例、线程安全机制对比及生产选型建议。

      Java中final与static final常量的定义及初始化规则
      Java中final与static final常量的定义及初始化规则

      深入解析Java中final变量与static final常量的定义、内存语义、初始化时机及合法赋值路径,涵盖编译期常量优化与实战避坑指南。

      Java抽象方法与接口方法的区别及选型建议
      Java抽象方法与接口方法的区别及选型建议

      深入对比Java中抽象类抽象方法与接口方法的语法演进、设计意图及运行期差异,并提供清晰的架构选型决策流程与实战范例。

      Java实现HTTP请求与JSON解析的完整代码示例
      Java实现HTTP请求与JSON解析的完整代码示例

      本文提供Java标准库HttpClient发起HTTP GET/POST请求并结合Jackson进行JSON数据反序列化与序列化的完整代码示例与工程实践指南。

      Java递归出现StackOverflowError的原因分析及栈空间优化方案
      Java递归出现StackOverflowError的原因分析及栈空间优化方案

      详细分析Java递归调用出现StackOverflowError的原因,结合代码说明线程栈、栈帧和递归深度之间的关系,并介绍终止条件排查、迭代改写、减少栈帧开销以及通过-Xss调整JVM栈空间的方法。

      Java空指针异常(NPE)的代码排查与修复实例
      Java空指针异常(NPE)的代码排查与修复实例

      针对Java中常见的NullPointerException(NPE),本文从堆栈日志定位、典型代码触发场景、具体修复代码对比到防御体系进行系统讲解,提供实用且易上手的排查与修复方案。

      selenium上传文件教程本地文件路径设置方法
      selenium上传文件教程本地文件路径设置方法

      深入解析Selenium处理文件上传的技术细节,涵盖标准HTML控件的路径直接注入法与非标准控件的系统级模拟方案,提供Windows与Linux环境下的路径设置最佳实践及常见异常排查。

      大数据开发语言选型:Java对比Scala与Python的优缺点及适用场景
      大数据开发语言选型:Java对比Scala与Python的优缺点及适用场景

      针对大数据工程场景,系统对比Java、Scala与Python在执行性能、生态结合、开发效率和维护成本上的核心差异,给出清晰的架构选型依据与落地方案。

      查看更多
      精品专题 更多
      装机必备
      装机必备

      正软商城装机必备专区,精选办公、浏览器、安全防护、影音播放、压缩解压、设计创作和系统工具等电脑常用正版软件,帮助用户快速完成新电脑软件配置。

      Windows
      Windows

      正软商城Windows软件专区,汇集适用于Windows电脑的办公、设计、安全防护、影音播放、开发工具和系统优化软件,提供软件介绍、系统要求、正版授权及购买下载服务。

      PDF教程
      PDF教程

      正软商城PDF教程频道提供PDF编辑、转换、合并、拆分、压缩及格式处理方法,同时介绍常用PDF软件和工具的使用技巧。

      Mac软件 更多
      讯飞智作 网页版
      讯飞智作 网页版
      Windows/ macOS/ Linux

      讯飞智作是一款基于语音合成技术、虚拟人驱动技术与数字人形象声音构建能力的 AI 数字人音视频创作平台。

      火山引擎 网页版
      火山引擎 网页版
      Windows/ macOS/ Linux

      火山引擎是字节跳动旗下企业级云与AI服务平台。聚焦大模型核心能力,依托字节自研豆包多模态大模型,凭借火山方舟一站式平台,提供模型精调、推理部署、智能应用搭建等全链路服务,结合高性能AI算力,助力各行业快速落地大模型数字化与智能化应用。

      Aperty macOS版
      Aperty macOS版
      macOS

      Aperty 是 Skylum 推出的 AI 人像修图软件,支持自然肤质修饰、瑕疵处理、面部与身体调整、预设及批量同步。

      WINDOWS 更多
      讯飞智作 网页版
      讯飞智作 网页版
      Windows/ macOS/ Linux

      讯飞智作是一款基于语音合成技术、虚拟人驱动技术与数字人形象声音构建能力的 AI 数字人音视频创作平台。

      火山引擎 网页版
      火山引擎 网页版
      Windows/ macOS/ Linux

      火山引擎是字节跳动旗下企业级云与AI服务平台。聚焦大模型核心能力,依托字节自研豆包多模态大模型,凭借火山方舟一站式平台,提供模型精调、推理部署、智能应用搭建等全链路服务,结合高性能AI算力,助力各行业快速落地大模型数字化与智能化应用。

      PixTV 网页版
      PixTV 网页版
      Windows

      PixTV 是一款在浏览器中使用的 AI 视觉内容创作平台,提供图片、视频、音频、文字生成、AI 分镜、局部重绘、提示词反推和无限画布等工具,适合短剧、漫剧、广告及社交媒体内容制作。