继承和多态(上)

目录

一.继承

1.何为继承

2.继承的语法

3.子类访问父类

(1)子类访问父类的成员变量

(2)子类访问的父类方法

二.super关键字

1.super用于调用父类的构造方法

2.super用于调用父类的实例方法

3.super用于访问父类的实例变量

三.子父类构造方法 和代码块的执行优先顺序

三.继承总结

1. 单继承

2. 多层继承

3.多个子类继承同一个父类


一.继承

1.何为继承

继承是面向对象编程中的一个重要概念,它允许一个类(称为子类或派生类)继承另一个类(称为父类或基类)的属性方法

通过继承,子类能够直接使用父类的已有功能,避免重复编写代码,同时还能在子类中扩展或修改父类的行为,从而实现代码的重用性和可扩展性。

举一个简单的例子,我们可以认为动物是一个父类,然后猫猫狗狗,牛牛羊羊等是子类。这些猫狗牛羊都拥有一些相同的共性,比如:要睡觉,要吃饭,能跑等等,这些就是通用的属性或方法,然后子类继承父类,子类能够直接使用这些功能,也可以重写该功能(睡觉,吃饭,跑等等),当然这些子类比如说狗,他可以在自己的类中拓展他自己本身有用的独一无二的技能,比如说狗叫汪汪汪等。

2.继承的语法

我们在java中如果想要表示类之间的继承关系的话,需要用到extends关键字,在想要成为子类的类名右旁加上extends 和父类类名。   

修饰符 class 子类 extends 父类 {

   // ...  

}

举一个具体例子,按照上面的例子来写:

//Animal类public class Animal {int age;String name;public void eat(){System.out.println(name+"正在吃饭...");}public void run(){System.out.println(name+"正在跑...");}
}--------------------------------------------------
//Dog类public class Dog extends Animal{//构造方法public Dog() {super();this.name="旺财";this.age=2;}public void bark(){System.out.println(name+"正在狗叫...");}
}--------------------------------------------------
//Cat类
public class Cat extends Animal{//构造方法public Cat() {super();this.name="咪咪";this.age=1;}public void mew(){System.out.println(name+"正在猫叫...");}
}---------------------------------------------------
//测试类
public class Test {public static void main(String[] args) {Dog dog=new Dog();System.out.println(dog.name);System.out.println(dog.age);dog.bark();dog.eat();dog.run();Cat cat=new Cat();System.out.println(cat.name);System.out.println(cat.age);cat.mew();cat.eat();cat.run();}
}

输出结果为:

在代码中测试类我们定义了一个Dog类型的dog对象,可以看到我们可以输出dog.name,dog.age,当然还有方法eat(),run(),这些成员变量和方法Dog类中都没有,但是继承了Animal类后就可以直接使用了,我们在构造方法那里其实就能看出来了。当然Cat类也是如此。

注意:

        继承机制使得子类能够“继承”父类的属性和方法,即子类自动拥有父类中的变量和方法,不需要重新定义。

3.子类访问父类

(1)子类访问父类的成员变量

·当子类成员变量与父类成员变量同名时,优先访问自己的,也就是子类的。(无论类型相同与否)

·当子类和父类都没有定义某个成员变量时,就会编译错误。

·当子类成员变量与父类成员变量不同名时,则会根据情况访问子类或者父类的。

举个例子:

//父类Test
public class Test {static String name = "haha";static int a=66;static int b=77;static String d="父类d";
}-------------------------------------
//子类Demo
public class Demo extends Test{static int a=67;  //与父类同名同类型static int c=88;  //父类没定义该变量static int d=10;  //与父类同名但是不同类型public static void main(String[] args) {System.out.println(a); //输出67  访问的子类System.out.println(b); //输出77  访问的父类System.out.println(name); //输出haha  //访问的父类System.out.println(c); //输出88  //访问的子类System.out.println(d); //输出10  //访问的子类
//        System.out.println(e); //编译错误:父类和子类都没定义d}
}

输出结果:

(2)子类访问的父类方法

子类访问父类的方法分两种情况:

1.方法有参数的情况。

(1)当子类和父类的方法同名但是参数一个有一个无时,如果子类调用有参数的方法,则系统就会自动识别执行有参数的方法,如果调用无参数的方法,那么系统就会执行无参数的方法(无论子类或者父类)。

(2)如果子类父类都有参数且方法同名,系统会根据参数的多少或者类别自动识别并且执行。

2.方法无参数的情况。

(1)子类和父类方法同名都无参时,则会优先执行子类的方法。

注意:成员方法没有同名时,在子类方法中或者通过子类对象访问方法时,则优先访问自己的,自己没有时再到父类中找,如果父类中也没有则报错。

举个例子:

//父类Test
public class Test {public void methodA(){System.out.println("调用父类的方法A");}public void methodB(String str){System.out.println("调用父类的方法B:"+str);}public void methodC(){System.out.println("调用父类的方法C");}
}------------------------------------------------------//子类Demo
public class Demo extends Test{//跟父类的方法A同名且无参数public void methodA(){System.out.println("调用子类的方法A");}//跟父类的方法B同名但是参数不同public void methodB(int a){System.out.println("调用子类的方法B:"+a);}//跟父类的方法C同名但是参数一个有一个无public void methodC(int c){System.out.println("调用子类的方法C:"+c);}public static void main(String[] args) {Demo demo=new Demo();demo.methodA();  //调用子类的方法Ademo.methodB("hello");  //调用父类的方法B:hellodemo.methodB(10);  //调用子类的方法AB:10demo.methodC();  //调用父类的方法Cdemo.methodC(12);  //调用子类的方法C:12}
}

输出结果:

二.super关键字

在子类中,super提供了一种方式,能够直接访问父类被重写的方法、父类的属性,以及父类的构造方法。

注意事项:

  • 必须在子类构造方法的第一行调用父类构造方法:如果需要使用super调用父类的构造方法,它必须是子类构造方法的第一个语句。如果子类构造方法没有显式调用super(),则默认调用父类的无参构造方法。

  • 不能在静态上下文中使用supersuper关键字仅用于实例方法或构造方法中,不能在静态方法或静态代码块中使用,因为静态方法不属于任何实例对象。

1.super用于调用父类的构造方法

在子类的构造方法中,可以通过super关键字来调用父类的构造方法。这在需要初始化父类部分的属性或做一些父类构造的工作时非常有用。如果没有明确使用super调用父类构造方法,系统会默认调用父类的无参构造方法(如果存在)。

class Animal {Animal(String name) {System.out.println("Animal构造方法: " + name);}
}class Dog extends Animal {Dog(String name) {super(name); // 调用父类构造方法System.out.println("Dog构造方法");}
}public class Main {public static void main(String[] args) {Dog dog = new Dog("Buddy");}
}

输出结果:

代码解释:在这个例子中,super(name);调用了Animal类的构造方法,从而完成了父类的初始化工作。

2.super用于调用父类的实例方法

在子类中,可以使用super关键字来调用父类的实例方法,尤其是在子类中重写了该方法的情况下。此时super关键字帮助子类调用到父类版本的实现,避免因方法重写而无法访问原方法。

class Animal {void sound() {System.out.println("Animal makes a sound");}
}class Dog extends Animal {@Overridevoid sound() {super.sound(); // 调用父类的 sound 方法System.out.println("Dog barks");}
}public class Main {public static void main(String[] args) {Dog dog = new Dog();dog.sound();}
}

输出结果:

代码解释:在这个例子中,super.sound()调用了Animal类的sound方法,而后才执行子类Dogsound方法。这种情况在需要在重写方法中保留父类的一部分行为时非常有用。

3.super用于访问父类的实例变量

当子类中有与父类同名的实例变量时,可以使用super来区分和访问父类中的变量。这样做可以避免子类中覆盖父类的变量。

class Animal {String name = "Animal";
}class Dog extends Animal {String name = "Dog";void printNames() {System.out.println(super.name); // 输出父类的 name 属性System.out.println(this.name);  // 输出子类的 name 属性}
}public class Main {public static void main(String[] args) {Dog dog = new Dog();dog.printNames();}
}

输出结果:

代码解释:在这个例子中,super.name用于访问父类Animal中的name属性,而this.name访问的是子类Dog中的name属性。

三.子父类构造方法 和代码块的执行优先顺序

直接上例子,简单记一下就行:

//1、父类静态代码块优先于子类静态代码块执行,且是最早执行
//2、父类实例代码块和父类构造方法紧接着执行
//3、子类的实例代码块和子类构造方法紧接着再执行
//4、第二次实例化子类对象时,父类和子类的静态代码块都将不会再执行
class Person{public Person(){System.out.println("Person父类构造方法执行");}{System.out.println("Person父类实例代码块执行");}static {System.out.println("Person父类静态代码块执行");}
}
public class Student extends Person{public Student(){System.out.println("Student子类构造方法执行");}{System.out.println("Student子类实例代码块执行");}static {System.out.println("Student子类静态代码块执行");}public static void main(String[] args) {Student stu=new Student();System.out.println("===================");Student stu1=new Student();}
}

输出结果:

三.继承总结

1. 单继承

Java中一个类只能直接继承自一个父类,这种机制称为单继承

如下:

class Animal {// 父类代码
}class Dog extends Animal {// Dog类继承了Animal类
}

2. 多层继承

Java支持多层继承,即一个类可以继承另一个类,而这个类本身又可以继承另一个类。

如下:

class Animal {// 父类代码
}class Mammal extends Animal {// Mammal继承Animal
}class Dog extends Mammal {// Dog继承Mammal,也间接继承了Animal
}

3.多个子类继承同一个父类

Java中允许多个不同的类继承同一个父类,这称为多对一继承

class Animal {// 父类代码
}class Mammal extends Animal {// Mammal继承Animal
}class Dog extends Animal {// Dog继承Animal
}

Java中不支持的继承类型:多重继承

Java明确不支持类的多重继承,即一个类不能继承多个父类。

class Animal {}
class Mammal {}
class Dog extends Animal, Mammal {} // 错误

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

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

相关文章

【练习案例】30个 CSS Javascript 加载器动画效果

本文分享一些 Loader CSS、Javascript 示例,这些示例均来源于Codepen网站上,里面有案例的源码与显示效果,您可以用于练习,也可以将您认为有趣的动画,添加到您的项目中,以帮助您创建更加有趣的等待页面加载动…

45.第二阶段x86游戏实战2-hook监控实时抓取游戏lua

免责声明:内容仅供学习参考,请合法利用知识,禁止进行违法犯罪活动! 本次游戏没法给 内容参考于:微尘网络安全 本人写的内容纯属胡编乱造,全都是合成造假,仅仅只是为了娱乐,请不要…

限流算法(令牌通漏桶计数器)

限流算法(令牌桶&漏桶&计数器 ) 什么是限流? 限流是为保护自身系统和下游系统不被高并发流量冲垮,导致系统雪崩等问题 限流在很多场景中用来限制并发请求量,比如说秒杀抢购、双11高并发流量等 在保证系统可…

❤React-React 组件基础(类组件)

❤React-React 组件基础 1、组件化开发介绍 组件化开发思想:分而治之 React的组件按照不同的方式可以分成类组件: 划分方式一(按照组件的定义方式) 函数组件(Functional Component )和类组件(Class Component); …

2024/11/13 英语每日一段

The new policy has drawn many critics. Data and privacy experts said the Metropolitan Transit Authority’s new initiative doesn’t address the underlying problem that causes fare evasion, which is related to poverty and access. Instead, the program tries “…

MySQL重难点(一)索引

目录 一、引子:MySQL与磁盘间的交互基本单元:Page 1、重要问题:为什么 MySQL 每次与磁盘交互,都要以 16KB 为基本单元?为什么不用多少加载多少? 2、有关MySQL的一些共识 3、如何管理 Page 3.1 单个 P…

【软件工程】一篇入门UML建模图(类图)

🌈 个人主页:十二月的猫-CSDN博客 🔥 系列专栏: 🏀软件开发必练内功_十二月的猫的博客-CSDN博客 💪🏻 十二月的寒冬阻挡不了春天的脚步,十二点的黑夜遮蔽不住黎明的曙光 目录 1. 前…

vue2+ element ui 集成pdfjs-dist

目录 1. 下载Pdf.js1.1 下载1.2 修改配置1.2.1 将pdfjs-3.8.162-dist复制到项目中1.2.2 解决跨域问题1.2.3 将pdf.worker.js文件复制到public目录下1.2.4 安装 pdfjs-dist1.2.5 前端vue代码(示例) 3. 参考资料 1. 下载Pdf.js 1.1 下载 下载链接(官方)需…

蓝桥杯每日真题 - 第7天

题目:(爬山) 题目描述(X届 C&C B组X题) 解题思路: 前缀和构造:为了高效地计算子数组的和,我们可以先构造前缀和数组 a,其中 a[i] 表示从第 1 个元素到第 i 个元素的…

大语言模型:解锁自然语言处理的无限可能

0.引言 在当今的科技时代,自然语言处理技术正以前所未有的速度发展,语言大模型作为其中的核心力量,对各个领域产生了深远的影响。本文旨在探讨语言大模型的发展历程、核心技术以及广泛的应用场景,以帮助读者更好地理解这一前沿技…

【vue2.0入门】vue基本语法

目录 引言一、页面动态插值1. 一般用法 二、计算属性computed三、动态class、style绑定四、条件渲染与列表渲染五、事件处理六、表单输入绑定七、总结 引言 本系列教程旨在帮助一些零基础的玩家快速上手前端开发。基于我自学的经验会删减部分使用频率不高的内容,并不…

【STM32F1】——无线收发模块RF200与串口通信

【STM32F1】——无线收发模块RF200与串口通信 一、简介 本篇主要对调试无线收发模块RF200的过程进行总结,实现了以下功能。 串口普通收发:使用STM32F103C8T6的USART2串口接收中断,实现两个无线收发模块RF200间的通信。 二、RF200介绍 电压…

《TCP/IP网络编程》学习笔记 | Chapter 8:域名及网络地址

《TCP/IP网络编程》学习笔记 | Chapter 8:域名及网络地址 《TCP/IP网络编程》学习笔记 | Chapter 8:域名及网络地址域名系统什么是域名?DNS 服务器IP 地址和域名之间的转换使用域名的必要性利用域名获取 IP 地址利用 IP 地址获取域名 基于 Wi…

前端开发中常用的包管理器(npm、yarn、pnpm、bower、parcel)

文章目录 1. npm (Node Package Manager)2. Yarn (Yarn Package Manager)3. pnpm4. Bower5. Parcel总结 前端开发中常用的包管理器主要有以下几个: 1. npm (Node Package Manager) 简介: npm 是 Node.js 的默认包管理器,也是最广泛使用的包…

HarmonyOS 如何实现传输中的数据加密

文章目录 摘要引言数据传输加密概述选择加密算法和传输协议加密实现方案与 Demo 代码配置 HTTPS/TLSAES 加密的实现代码详解RSA加密的实现代码详解 QA环节总结参考资料 摘要 本文将介绍在 HarmonyOS 应用中如何实现数据传输的加密策略。我们将讨论常见的加密算法(如…

ArkTs简单入门案例:简单的图片切换应用界面

在鸿蒙 OS 应用开发的过程中,我们常常需要通过组合各种组件和编写相应的逻辑来实现丰富多样的功能。今天,我就来和大家详细解析一段实现简单图片切换功能的代码,希望能帮助到那些刚接触鸿蒙 OS 应用开发的朋友们。 一、代码导入部分 Entry …

influxDB 时序数据库安装 flux语法 restful接口 nodjsAPI

安装 Install InfluxDB | InfluxDB OSS v2 Documentation Debian和Ubuntu用户可以用apt-get包管理来安装最新版本的InfluxDB。 对于Ubuntu用户,可以用下面的命令添加InfluxDB的仓库,添加之后即可apt-get 安装influxdb2 wget -q https://repos.influx…

丹摩征文活动|丹摩智算平台使用指南

目录 1. 登录平台与工作环境设置1.1 访问与登录1.2 创建或选择项目1.3 初始化项目环境 2. 数据上传与管理2.1 数据上传2.2 数据管理与预处理2.3 数据可视化 3. 模型构建与训练3.1 模型选择3.2 参数配置3.3 模型训练与评估 4. 模型部署与应用4.1 模型部署4.2 接口调用与集成4.3 …

NAT网络工作原理和NAT类型

NAT基本工作流程 通常情况下,某个局域网中,只有路由器的ip是公网的,局域网中的设备都是内网ip,内网ip不具备直接与外部应用通信的能力。 处于内网的设备如何借助NAT来实现访问外网的应用? 对于开启了NAT功能的局域网…

LLMs 如何处理相互矛盾的指令?指令遵循优先级实验

编者按:想象一下,你正在开发一个 AI 助手,突然发现 system message 和用户提示词存在冲突,这时 AI 会听谁的?这种情况不仅困扰着开发者,还可能导致 AI 系统的不稳定和不可预测,影响用户体验和系…