类和对象之 封装 继承 与 多态

news2024/9/22 23:33:49

1.进行类继承的前提是我们要有两个类,且已经确定好了这两个类谁为父类谁为子类

2.先创建父类然后再创建子类

3.创建子类的时候我们要使用继承语法,使用的方式是在创建子类时的第一条代码的最后面加上冒号 : 和父类的类名 

4.继承的本质就是将父类中的代码全都拷贝了一份到子类中,此时子类具有父类的代码,但是父类不具有子类的代码

(换句话说就是子类能够使用父类和自己的成员,但是父类只能够使用父类成员)

5.父类的 public 成员既能够被其子类调用,也能被进行其它类外调用

procted 成员只能够被其子类调用,不能够进行其它类外调用

private 成员只能够在父类中调用,不能够进行任何形式的类外调用

6.上图就是父类型的引用能够指向子类型的在堆区中实例化的对象 

7.父类型的引用指向子类对象后,我们通过父类引用 + 点操作符能够访问到的子类对象成员只有子类继承过来的父类成员

8.如果想要既能访问父类成员,又能访问子类成员的话我们必须用子类引用来指向子类对象

(上面那个父类引用中装着子类对象的地址,但是这个地址不能直接传给子类引用,因为这个地址的类型是父类引用类型,如果想传的话我们必须先将父类引用强制类型转换为子类引用后,才能将数据进行传递)

 (子类对象的地址在传给父类引用的时候已经进行了隐式类型转换了,但是在在从父类引用传给子类引用的时候没有进行隐式类型转换,而是必须进行显式类型转换后才能进行传递)

父类引用在转换为子类引用的时候需要强制类型转换,但是这个强制类型转换不要直接用括号那种类型,而是要用 :

在父类引用后面加上 as  然后再加上要转换的子类类名(如上图)

这样做的好处是:

如果父类引用指向的是与要转换的子类引用不对应的子类对象的话,在进行类型转换后传数据时会传一个 null 给子类引用,起到报错和检查的作用 

静态部分 

1.首先提出一个问题,当我们通过类实例化对象的时候,是不是每个对象都会各自拥有一份类中包含的所有字段(成员变量)?
答案是否定的,这要从类中字段(成员变量)的分类开始说起:
一个类中的字段分为两类,这两类字段在实例化对象的时候会有区别:

一种字段是在实例化对象的时候每个对象都会在堆区中开辟空间并自己拥有一份

还有一种字段是在实例化第一个对象的时候单独在堆区为其开辟一个空间,这个空间可以被所有同类的对象访问和操作,也就是说这个类中字段可以被所有的同类对象访问

(PS:空间只会开辟一次,后面再实例化对象的时候就不会再开辟了,这个空间是同类对象的共有空间)

在类中共有字段的语法是:

在正常对象的访问权限后面加上 static 关键字进行修饰 ,就可以将这个字段变为共有字段,又称为静态字段 

需要注意的一点是共有字段(静态字段)只能够通过类名 + 点操作符 + 字段名的方式去访问 

现在我们回到我们的主题 --- Static

首先static是一个关键字

1.static关键字除了可以修饰成员变量(字段)外,还可以修饰构造函数和成员方法(函数)

2.静态成员变量属于类的意思就是这个成员变量是属于所有通过该类实例化的对象的,是共有物,而实例成员对象则是每个对象在实例化的时候都会拥有的,是属于对象本身的

3.在堆区中为静态成员变量开辟的空间称为静态区(是共享区域),在通过类实例化对象的时候,如果静态区没有被创建则会进行创建,如果已经创建好了的话就不会再重复创建了。

4.静态成员变量直接通过类名访问,而实例成员变量则是通过对象名进行访问

 

 

1.出现类名的时候,类本身被加载(类先于对象加载,所以此时还没有对象),此时类中的静态数据成员加载(在堆区中开辟存储它的静态区) --- 类只会被加载一次

2.在堆区中开辟的静态区属于常驻内存,它只有在程序关闭后才会被GC(garbage collection)清除

(构造函数也需要加访问权限,修饰数据成员的关键字都在数据成员最前面,其中访问权限在最前面 ,另外不加访问权限的数据成员会有一个默认的访问权限-- private)

1.静态构造函数不能够有访问修饰符 --- 即静态构造函数不能够有访问权限修饰,只能够有一个static 关键字修饰

2.静态构造函数在出现类名的时候会自动调用,它的作用是初始化静态成员变量(字段)

3.构造函数是用来初始化分配给每个对象的实例成员变量的,它无法初始化静态成员变量,原因是静态成员变量在对象被创建前(出现类的时候)就需要初始化了,而在对象被创建的时候才会调用的构造函数自然无法初始化静态成员变量

1.静态构造函数在类被加载的时候(类名出现的时候)会被调用一次,而且仅会被调用一次,以后都不会再调用了

2.成员变量(无论是静态的还是实例的)的初始化工作都集中在对应的构造函数中进行,而声明工作则是正常在类中实现

3.静态代码块只能够访问静态成员

1.通过对象的引用调用实例方法的时候,都会自动的将引用传给实例方法,让方法能够锁定到自己要操作和处理的是那个对象的实例成员变量 

2.传进来的引用都被存储到类中方法中自动创建的 this 指针里了(一般这个this指针的调用都会被隐藏起来),通过this 指针方法就能够明确的找到自己要处理的数据对象所在的内存空间的内存地址了

3.调用静态成员方法和调用实例成员方法的区别就在于:

a. 在类外调用实例成员方法的时候我们都会将调用这个方法的对象的引用传给方法中的this指针

b. 而其与静态成员方法最大的一个区别就是:静态成员方法中没有this 指针,而且我们在类外调用它的时候只能够通过类名进行调用,调用时也不会进行引用传递(对象都没有哪来的引用传递)

这两个区别就决定了我们在静态成员方法中无法处理实例成员变量,在实例成员方法中无法处理实例成员变量

同时我们也无法通过类名调用实例成员方法和通过对象名调用静态成员方法

(1) 让方法处理实例成员变量的时候我们必须先确定是那个实例(对象)的成员变量,这就需要调用方法的实例传一个引用进到方法中用来定位数据成员,如果通过类名调用方法的话就没有引用传入,就无法进行成员定位,自然就报错了

(2)通过对象名调用静态成员方法的话也会调用失败,原因是调用时对象会传引用,但是静态成员方法中没有接收引用的 this 指针,这又会导致出错

问题又来了,为什么我们会需要对象传引用呢?

原因很简单,当我们在实例化了多个对象的时候相当于创建了多份实例成员变量,如果我们想调用实例成员方法去处理某个对象的实例成员变量而只给一个成员变量名的话,问题就出现了

每一个对象拥有的实例成员变量都是同名的,只通过一个变量名方法无法确定到底要处理那一个变量,自然就会导致出错。

这个问题的解决方案就是在对象调用方法的时候传一个引用进来(用this指针来接收),然后通过这个指针(引用)先访问到要处理的成员变量(这一步都被隐藏了),然后再进行处理

为什么静态成员方法处理静态成员变量的时候不需要传引用呢?

首先静态成员方法中就没有接收引用的this指针,其次静态成员变量最为特别的是它只有一份,这一份是所有对象共享的,大家都可以进行访问。正是因为它只有一份没有克隆体,所以方法在找变量的时候不会出现二义性问题

PS:实例代码块既能够访问实例成员变量也能够访问静态成员变量(因为无论是那种变量都能够准确的找到它们的位置)

第三条应该改为静态类不能被继承(不能够当别人的爸爸),普通类中的静态方法,字段和属性都能够被正常继承 

静态特性在什么时候适用呢?如上图

1.在通过类实例化一个对象的时候,在堆区中为对象开辟内存空间存储实例成员变量,不需要存储静态成员变量,静态成员变量存在专门为它准备的静态区中

2.静态区中同一个变量被两个对象同时访问时就会出现资源争抢问题,即并发问题,解决这个问题的方法就是加锁,当变量被一个对象访问时将变量锁上,不让其它人访问,访问完后再解锁再继续

3.静态类往往作为工具类来使用,工具类中放的是我们常用的一些方法(函数,在这里会被处理为静态成员函数),这样子做就是为了方便我们使用工具方法和增加代码的可读性,直接通过类名 + 方法(静态方法)名的方式就能够调用我们想用的工具方法,不需要像普通类那样先声明和实例化对象,然后再通过对象调用这么麻烦。 

1.这里面存在有两个属性,一个是上面的普通属性Rindex,写这个属性之前我们还需要创建一个对应的成员字段才行(首字母小写)

2.下面那个则是自动属性,创建这个属性的时候编译器就会自动的(隐式的)帮我们创建一个对应的成员字段,同时这个自动属性自己就具有最基础的get和set --- 注意这两个只能够返回字段和接收数据给字段,没有其它的功能,无法像普通的属性那样对get 和 set 进行拓展,无法进行额外的逻辑判断,同时也无法删去 get 和 set 中的任何一个来屏蔽接口

3.关于属性的补充:

没有对应字段的时候属性依然可以被创建,而且能够被正常的使用,因为属性的本质其实就是一个方法集成区,如果是直接调用属性的话那就相当于调用属性中的 get 方法(一定要有return),如果调用属性后给其赋值的话则相当于调用属性中的 set 方法(可以没有return)

没有对应字段时也可以正常的调用方法,而且get 和 set都可以自己选择是保留还是删除,如果删除的话就相当于屏蔽了接口,无法再调用对应的方法

 PS:list类中存在一个将对象转换为数组的方法 --- ToArray() --- 通过list类实例化的对象都是对应数组的升级版,拥有更多的功能,使用起来更加的方便。

二维数组中也有GetLength方法,不过和一维数组不同的是,二维数组使用这个方法的时候需要传参,如果传0的话则是获取二维数组的总行数,传的是1的话则获取到的是二维数组的总列数

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

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

相关文章

[附源码]Python计算机毕业设计Django药品仓库及预警管理系统

项目运行 环境配置: Pychram社区版 python3.7.7 Mysql5.7 HBuilderXlist pipNavicat11Djangonodejs。 项目技术: django python Vue 等等组成,B/S模式 pychram管理等等。 环境需要 1.运行环境:最好是python3.7.7,…

【Vue基本功】权限路由(1)

1 初始化项目 1.1 安装 yarn create vite … yarn 依赖: yarn add axios yarn add vuexnext vue-router4 -D yarn add typesvue-router -D vuex有ts支持,所以不需要安装类型文件 1.2 配置 1.2.1 别名 引入path时,发现有警告&#x…

Spring MVC 高级框架的核心

目录 1. 什么是 Spring MVC 1.1 如何理解 MVC 1.2 Spring MVC 和 MVC 的关系 2. 如何学习 Spring MVC 2.1 将浏览器和服务器连接起来 2.1.1 RequestMapping, GetMapping, PostMapping 三个注解的区别 2.2 在程序中获取前端传递过来的参数 2.2.1 传递单个参数 2.2.2 传…

CSS 实现音频loding动画

前言 👏实现一个音频loading动画还蛮有趣的,速速来Get吧~ 🥇文末分享源代码。记得点赞关注收藏! 1.实现效果 2.实现步骤 定义css变量:父容器高度为–h,可以动态设置loading的高度 :root {--h: 80px;}父…

遗传算法在机器人路径规划中的应用研究(Matlab代码实现)

目录 💥1 概述 📚2 运行结果 🎉3 参考文献 👨‍💻4 Matlab代码 💥1 概述 机器人运动规划是移动机器人导航的核心技术之一。40多年来,运动规划技术发展迅速,涌现出了许多规划算法,但因为环境描述方式差异…

JavaScript -- 数组及对象解构赋值方法总结

文章目录1 数组解构赋值1.1 保留默认值1.2 接受剩余的所有参数1.3 对函数执行结果解构1.4 交换两个变量的值1.5 二维数组结构2 对象的解构2.1 声明对象同时解构对象2.2 先声明再解构2.3 解构不存在的属性2.4 设置解构别名2.5 设置解构默认值1 数组解构赋值 案例:将…

红队隧道应用篇之Netsh端口转发

简介 netsh是从Windows 2000开始就有的一个用于配置网络设备的命令行工具 其中netsh interface portproxy是一个配置网络代理的命令, 可以配置ipv4或ipv6的端口转发代理以及双向端口转发代理 学习隧道应用前必须了解的知识:https://blog.csdn.net/xf555er/article/details/1…

LeetCode刷题复盘笔记—一文搞懂完全背包之279. 完全平方数问题(动态规划系列第十五篇)

今日主要总结一下动态规划完全背包的一道题目,279. 完全平方数 题目:279. 完全平方数 Leetcode题目地址 题目描述: 给你一个整数 n ,返回 和为 n 的完全平方数的最少数量 。 完全平方数 是一个整数,其值等于另一个整…

技术开发93

技术开发93 业务内容: . 马达零部件 . 汽车零部件 . 音响用零部件 . 农用机零部件 . 建筑模具 公司简介: 资本金:2000万日元(约120万元人民币) 员工数:17名 成立时间:1923年4月 资格认…

Linux文件及目录管理操作

Linux文件及目录管理实验目的及要求1.了解Linux文件与目录的访问权限2.熟悉Linux文件与目录的打包和压缩3.掌握Linux文件与目录的相关管理操作实验原理实验步骤对文件管理和压缩归档进行了解,具体步骤如下:1.用mkdir命令在"/root"目录下创建一…

[附源码]Python计算机毕业设计Django线上社区管理系统

项目运行 环境配置: Pychram社区版 python3.7.7 Mysql5.7 HBuilderXlist pipNavicat11Djangonodejs。 项目技术: django python Vue 等等组成,B/S模式 pychram管理等等。 环境需要 1.运行环境:最好是python3.7.7,…

C#语言入门详解 第十七讲 (字段、属性、索引器、常量)

C#语言入门详解 第十七讲 (字段、属性、索引器、常量) 在C#语言中,类(或结构体)包含以下成员: 什么是字段 字段(field)是一种表示与对象或类型(类与结构体&#xff0…

【传输层】概述、复用分用、UDP详解、UDP校验

文章目录传输层概述----为应用层服务TCP靠谱--大文件、时延大 与UDP不可靠--小文件、时延小传输层的寻址与端口------复用---应用层所有进程通过传输层再传输到网络层----------分用---------传输层从网络层收到数据后交付给指定应用程序套接字------Socket---IP:端…

足球冷知识:球队之间比分相同,怎么排名?

在足球比赛的小组赛中,往往会有胜、平、负三种结局,球队胜一场得三分、平一场得一分、输一场不得分。 如果球队积分相同,排名的时候,还会通过净胜球(就是进球数减丢球数)、相互交战的成绩、总进球数、球队累…

2023年天津美术学院专升本专业课报名缴费时间及考试安排

天津美术学院2023 年高职升本专业考试报名考试公告 一、报名时间 2022 年 12 月 9 日 10:00 至 12 月 12 日 17:00(逾期不予补报,考生也不得再修改报名信息) 注:每日 23:00 至次日 7:00 是报名系统维护时间,届时报名相…

搭建Python虚拟环境

搭建Python虚拟环境虚拟环境概述安装虚拟环境Windows环境下Linux环境下创建虚拟环境使用虚拟环境虚拟机环境下安装包PyCharm中使用虚拟环境虚拟环境 概述 为什么需要搭建Python的虚拟环境? 正常情况下,在一台电脑上, 想开发多个不同的项目, 需要用到同…

【GNN基础学习】图模块基本定义 || 图的邻接矩阵 || GNN中常见任务有哪些? || GNN消息传递方法 || 多层GCN有什么作用?

声明:仅学习使用~ 目录 一、图模块基本定义二、图的 邻接矩阵三、GNN中常见任务:点级别 任务、边级别 任务、图级别 任务。四、消息传递方法五、多层GCN的作用一、图模块基本定义 点、边、图。 对点的特征、边的特征、图的特征 等都要做重构。 借助于 图 这一结构,对事物…

39. 组合总和

39. 组合总和 给你一个 无重复元素 的整数数组 candidates 和一个目标整数 target ,找出 candidates 中可以使数字和为目标数 target 的 所有 不同组合 ,并以列表形式返回。你可以按 任意顺序 返回这些组合。 candidates 中的 同一个 数字可以 无限制重…

C++并发编程

目录一、并发编程相关的基础概念1、操作系统(Linux)2、任务和通信3、多进程和多线程4、C中的多线程发展史二、pthread线程使用讲解和实战1、pthread基本使用2、线程的分离3、线程属性4、关于线程的几个值得注意的点三、线程的同步之互斥锁、读写锁、非阻…

MySQL 数据库主从复制

参考视频教程: https://www.bilibili.com/video/BV13a411q753?p172 参考博客: https://blog.csdn.net/main_Scanner01/article/details/124259050 1. 介绍 1.1 要点 主库(master): 负责增删改 从库(slave) : 负责查询 主从库关系: 一对多 1.2 步骤 ● master将改变记录到_…