JAVA基础(JAVA SE)学习笔记(七)面向对象编程(进阶)

news2024/11/16 23:55:41

 前言 

1. 学习视频:

尚硅谷Java零基础全套视频教程(宋红康2023版,java入门自学必备)_哔哩哔哩_bilibili

2023最新Java学习路线 - 哔哩哔哩

第二阶段:Java面向对象编程

6.面向对象编程(基础)

7.面向对象编程(进阶)

8.面向对象编程(高级)

正文

7. 面向对象编程(进阶)

7.1 this关键字

7.1.1 this调用属性、方法 和 在构造器内使用

7.1.2 this 关键字 调用 构造器

如下,只创建了一个对象,使用this调用其他构造器。但是不能在一个类的两个构造方法中使用this互相调用,不然就形成了一个闭环的循环调用。

注意:只能在构造方法中使用this调用其他构造方法,不能在成员方法中使用。

7.2 面向对象特征之二:继承性(Inheritance)

7.2.1 Java中的继承

1. 继承性的好处:

2. 继承性(Inheritance)概念

        在Java中类的继承是指在一个现有类的基础上去构建一个新类,新类被称为子类,现有类被称为父类,子类会自动拥有父类所有可继承的属性和方法。在程序中,声明一个类继承另一个类,需要使用extends关键字。注意:(对比接口,接口是支持多继承的。)

        ①Java中,类只支持单继承,不允许多重继承。一个类只能有一个直接父类

                 (爸爸类属于子类的直接父类,爷爷类属于孙子子类的间接父类

        ②多个类可以继承一个父类。

        ③多层继承是可以的。即一个类的父类可以再去继承另外的父类。

        ④但是由于封装性的问题(例如父类中的属性和方法使用private关键字),子类不能直接访问父类中的属性和方法(但是子类是拥有这些属性和方法的。)。假如父类中的a属性使用了private关键字,且a属性提供了public修饰的get和set方法,那么子类就可以通过get和set方法得到a属性的赋值和获取权限。但是不能使用"子类实例.a属性"的方式。

        ⑤子类继承父类以后,还可以扩展自己特有的功能(体现:增加特有属性、方法)。

3. 默认父类:Object类 (java.lang.Object)

        JDK中提供了一个Object类,它是所有类的父类,即每个类都直接或间接继承自该类。

例如我们自定义一个类,它默认就有Object类的方法:toString等。

7.2.2 继承性的权限问题、子类 重写 父类方法的权限问题

1. 继承性的权限问题详解

上面我们已经知道:

2. 子类 重写 父类方法

在继承关系中,子类会自动继承父类中定义的方法,但是有时在子类中需要对继承的方法进行一些修改,即对父类的方法进行重写。注意:

①子类重写的方法要和父类被重写的方法具有相同的方法名、参数列表、返回值类型。

(没有返回值,父、子就都写void。返回值类型也可以是子类(父方法返回值类型用Person,子重写时,可以用Person的子类Student)。)

                          

子类重写父类方法时,不能使用比父类中被重写的方法更严格的访问权限。(例如父用缺省,子不能用private,子可以用缺省、protected、public。)

③子类中不能重写父类中private权限修饰的方法

④在子类中重写时加上“@Override 重写注解”,可以校验重写格式正误。

区分:方法的 重载与重写

重载(overload):一个类中定义多个同名方法,但参数类型或个数不同。

重写(override):两个类有继承关系,子类覆盖父类中同名、同参数、同返回值类型的方法。

(没有相关性,只是名字长得像。)(有相关性,名字不像。)

7.3 继承性:super关键字的使用

当子类重写父类方法后,子类对象将无法访问(子类.父类成员变量)父类被重写的方法,为了解决这个问题,在Java中专门提供了一个super关键字用于访问父类的成员。例如访问父类的成员变量、成员方法、构造方法。

7.3.1 super调用属性、方法

super.成员变量

super.成员方法([参数1,参数2...])

eat()方法在子类中重写过之后,用this和省略this调用的都是子类重写后的方法。只有使用super.eat()调用的才是父类的eat()方法。

注意:①成员变量的值遵循就近原则查找。即父类name="柳仙仙",子类定义name="仙子仙"。子类最终name="仙子仙"。(先就近在子类找,找到name="仙子柳",不会再去找父类。子类找不到(子类没定义name成员变量,说明name是继承自父类的),才会找父类。)如果写super.name,则代表父类name,直接查找父类name。

7.3.2 super调用父类的构造器

super([参数1,参数2...])

注意:

        ①子类继承父类时,不会继承父类的构造器。只能通过super(形参列表)调用父类构造器。

        ②super调用父类构造方法的代码必须位于子类构造方法的第一行,且只能出现一次。

        ③在子类的构造方法中一定会调用父类的构造方法,可以通过super指定调用父类的哪个构造方法。如果没有指定,(类默认都有一个无参的构造方法)在子类实例化时,会默认调用父类无参的构造方法super()。如下:

public Dog(){ //子类默认无参的构造器

        super(); //父类默认无参的构造器

}             //父类也有无参的构造方法时,public Dog(){ }中可以不写super(); ,会默认调用。

但是如果父类中只写了一个有参的构造方法(编译器不会再默认添加一个无参的构造方法),子类只写public Dog(){ },这时编译器认为不调用父类的任何构造器,会报错。所以必须写为:

public Dog(){   //子类默认无参的构造器

        super(参数);   //调用父类有参的构造器

}       

        可见在定义一个类时,如果没有特殊要求,尽量在类中定义一个无参的构造方法,避免在继承时出现错误。

7.4 继承性:子类对象实例化的全过程

7.5 面向对象特征之三:多态性(方法)(属性不存在多态性)

7.5.1 多态性

在设计一个方法时,通常希望该方法具备一定的通用性。例如实现动物叫,希望方法在传入不同动物类型名时,实现不同动物的叫声。同一个方法中,这种由于参数类型不同而导致执行效果各异的现象就是多态。(方法的多态性:方法的重写——同名,不同参数类型或不同参数个数)

在Java中为了实现多态,允许使用一个父类类型的变量引用一个子类类型的对象,根据被引用子类对象特征的不同,得到不同的运行结果。

子类对象的多态性父类的引用指向子类的对象。(或 子类的对象 赋给 父类的引用)

比如:Person p2 = new Man();

注意:成员变量并不满足多态性。p2是Person,p2的属性也是Person的类型和值。而不是子类。

7.5.2 多态性的应用案例

①多态性的应用:虚拟方法调用。  (也可称动态绑定:编译时和运行时调用的不是一种方法。)

        在多态场景下,调用方法:

                编译时,认为方法是左边声明的父类类型的方法(即被重写的方法)。

                执行时,实际执行的是子类重写父类的方法

        简称为,编译看左边(父类),运行看右边(子类)。

②多态性的使用前提:①要有类的继承关系;②要有方法的重写。

多态的适用性:适用于成员方法,不适用于成员变量(属性)。

④多态的好处和弊端:

弊端:①在多态的场景下,我们创建了子类的对象,也加载了子类特有的属性和方法,但是由于声明为父类的引用,导致我们不能直接调用子类特有的这些属性和方法。只能执行子类重写父类的方法。

好处:①极大的减少了代码的冗余,不需要定义多个重载的方法。

我们只需要传参的时候,传入参数信用卡,cust就知道去信用卡取钱。而不必写两个用户取钱的getAccount()方法去区分信用卡和储蓄卡取钱。

理解:

①解决了方法同名问题,使程序更加灵活,从而有效地提高程序的可扩展性和可维护性。

②高内聚:同一方法实现不同功能;低耦合:大量不同子类具体执行不同行为特征。

7.5.3 多态性的逆过程:向下转型,使用关键字instanceof

基于这个弊端:①在多态的场景下,我们创建了子类的对象,也加载了子类特有的属性和方法,但是由于声明为父类的引用,导致我们不能直接调用子类特有的这些属性和方法。只能执行子类重写的父类的方法。

在这个过程中,子类对象赋值给父类变量的时候,在编译期间,做了一次类型转换。因此,想要调用子类特有的方法,必须再做一次类型转换,使得编译通过。(p2、m1指向堆空间中的同一个对象实体(地址值相同)。所以 m1==p2; 是true。

Person p2 = new Man();  //一次类型转换

Man m1 = (Man)p2; //强制类型转换

向下转型可能出现问题:类型转换异常(ClassCastException)

        假如:Person p3 = new Woman();  //一次类型转换

        显然我们不能把p3进行强制类型转换成man。他们都是子类,不能互相转换。

        可以加一个判断,使用关键字instanceof,判断一个对象是否是某个类(或接口)的实例或者子类实例格式:

                对象(或者对象引用变量)    instanceof     类(或接口)

if(p2 instanceof Man){ //是Man类的实例

        Man m1 = (Man)p2 ; //强制类型转换

}else{

        System.out.println("p2 不是一个Man");

}

7.5.4 练习题

7.6 Object类

7.6.1 Object类介绍与常用方法使用

       JDK中提供了一个Object类,它是所有类的父类,即每个类都直接或间接继承自该类。

例如我们自定义一个类,它默认就有Object类的方法:toString等。

  • Object类型的变量 与 除Object以外的 任意引用数据类型的对象 都存在多态引用。
  • Object类中没有声明属性,只提供了一个空参的构造器。

7.6.2 Object中clone()的使用

所以目前创建对象有两种方式:new和clone()。以后还会见到其他方式。

7.6.3 Object中finalize()的使用(从JDK9开始就过时了!!)

例如关闭浏览器时,临关闭前保存一下你的用户信息,在你再次登录时,就会自动填写上次的用户信息。

之所以过时,是因为可能导致一些问题:finalize()方法可能导致程序内部出现循环引用,导致此对象不能被回收。

7.6. Object中equals()的使用(重写使用IDEA可以自动生成)

任何引用数据类型都可以使用。

①Object中equals()的定义:

②子类使用说明:(重写,比较实体内容;没重写,比较引用地址)

        自定义的类在没有重写Object中equals()方法的情况下,调用的就是Object类中声明的equals()方法,即比较两个对象的引用地址是否相同。(或 比较两个对象是否指向了堆空间中的同一个对象实体)

重写了equals()方法:对于像String、File、Date和包装类等,他们都重写了Object类的equals()方法,用于比较两个对象的实体内容是否相同。

③平常比较我们为了比较实体内容,要重写equals()方法。不重写直接用==就可以了。

例如:为了比较两个对象的信息

public boolean equals( Object obj){
    if(this == obj){//1.先判断地址值
        return true;
    }
    if(obj instanceof User){//2.判断是否是同类或子类
        User user = (User)obj; //Object类先强转成User
        //3.比较具体内容
        //方式一: name要比较每一个字符
        if(this.name.equals(user.name) && this.age == user.age){
            return true;
        }else{return false;}
        //方式二
       // return (this.name.equals(user.name) && this.age == user.age);
    }else{
        return false;
    }
}

多态性:引用形式是Object,得强转成子类User的类型,才能调用子类的方法和属性, 否则调用的是父类Object的方法。

④我们还可以让IDEA自动实现:

        alt+insert出现:选择生成equals()方法

⑤在开发中的使用:

注意相同字符串使用的地址值也是相同的:

应用:

因为Customer是类,要在Customer类中重写equals()方法,比较。结果是false。是因为Customer类的属性中Account也是一个类,也要重写equals()方法。这样结果才是true。

7.6. Object中toString()的使用(重写:具体内容,不重写:地址值)

类名+@+地址值。和直接打印u1(是去Object中调toString())效果一样。

同样可重写可自动生成:

复习

Java的单继承是因为:子类对象实例化的时候没办法区分从多个父类继承的同名方法或构造器,属性也不好区分。所以单继承,只有一个父类。

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

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

相关文章

Autosar代码阅读和调试方法

一、前言 众所周知Autosar工程代码量非常庞大,而且有非常多的宏定义,代码可读性非常不友好。但是目前国内外很多OEM和Tire1都是基于Autosar系统进行项目开发的。在开发过程中,出现一些BUG时必须去阅读和调试代码。这就要求开发人员具备很强代…

JavaScript基础知识16——分支语句

哈喽,大家好,我是雷工。 今天学习JavaScript基础知识的分支语句,以下为学习笔记。 1、程序三大流程控制语句 ○写几句就从上往下执行几句,这种叫做顺序结构; ○有时要根据条件选择执行代码,这种叫分支结构…

深度学习 | Pytorch深度学习实践 (Chapter 10、11 CNN)

十、CNN 卷积神经网络 基础篇 首先引入 —— 二维卷积:卷积层保留原空间信息关键:判断输入输出的维度大小特征提取:卷积层、下采样分类器:全连接 引例:RGB图像(栅格图像) 首先,老师…

2001-2022年全国290+个地级市高铁开通数据

2001-2022年全国290个地级市高铁开通数据 1、时间:2001-2022年 2、范围:298地级市(293地级市数(其中莱芜市2019年撤市设区)4直辖市数 ) 3、来源:国家铁路局、铁路客货运输专刊及相关统计 国…

Homeassistant docker配置

Homeassistant docker配置 【说明】本系列为自用教程,记录以便下次使用 【背景】一台J1900 4G64G的小主机,安装了OP系统,里面自带了Docker。为实现Homeassistant(简称HA)控制智能家居设备,进行如下配置。 【…

使用 Data Assistant 快速创建测试数据集

使用 Data Assistant 快速创建测试数据集 Data Assistant 提供超过 100 种数据类型,为任何开发、测试或演示目的生成大量、异构、真实的数据。 官网地址: http://www.redisant.cn/da 主要功能 Windows 原生 Data Assistant 使用 Windows Native 技术…

Redis常见问题的解决方案(缓存穿透/缓存击穿/缓存雪崩/数据库缓存数据不一致)

Redis解决缓存数据库不一致的方案 用 先 操作数据库 再 操作缓存 的策略来实现缓存数据库数据一致具体做法是 更新数据库数据然后删除缓存 虽然还是会有线程安全问题 比如 假设此时缓存刚好失效了 线程1 查询缓存失败 从数据库读取了旧数据 还没写入缓存的时候 被调度到 线程…

C++标准模板(STL)- 类型支持 (运行时类型识别,type_info )

运行时类型识别 定义于头文件 <typeinfo> 含有某个类型的信息&#xff0c;由实现生成。​​这是 typeid 运算符所返回的类。 std::type_info 定义于头文件 <typeinfo> class type_info; 类 type_info 保有一个类型的实现指定信息&#xff0c;包括类型的名称和…

《机器学习》第6章 支持向量机

文章目录 6.1 间隔与支持向量6.2 对偶问题6.3 核函数支持向量展式核函数 6.4 软间隔与正则化6.5 支持向量回归6.6 核方法6.7 阅读材料 6.1 间隔与支持向量 分类学习最基本的想法就是基于训练集D在样本空间中找到一个划分超平面,将不同类别的样本分开.但能将训练样本分开的划分…

UG\NX二次开发 取消抑制特征 UF_MODL_unsuppress_feature

文章作者:里海 来源网站:《里海NX二次开发3000例专栏》 感谢粉丝订阅 感谢 bullzhanghao 订阅本专栏,非常感谢。 简介 UG\NX二次开发 取消抑制特征 UF_MODL_unsuppress_feature 效果 代码 #include "me.hpp" #include <vector> #

100114. 元素和最小的山形三元组 II

如果下标三元组 (i, j, k) 满足下述全部条件&#xff0c;则认为它是一个 山形三元组 &#xff1a;i < j < k nums[i] < nums[j] 且 nums[k] < nums[j] 请你找出 nums 中 元素和最小 的山形三元组&#xff0c;并返回其 元素和 。如果不存在满足条件的三元组&#xf…

昇腾AscendCL推理应用开发入门教程(基于Python语言)

pyACL&#xff08;Python Ascend Computing Language&#xff09;是一套在AscendCL的基础上使用CPython封装得到的Python API库&#xff0c;使用户可以通过Python进行昇腾AI处理器的运行管理、资源管理等&#xff0c;实现在昇腾CANN平台上进行深度学习推理计算、图形图像预处理…

表结构的操作【MySQL】

文章目录 创建表例子 查看表结构修改表新增列属性修改列属性修改列名修改表名删除列 删除表 阅读前导&#xff1a; 一般来说&#xff0c;对表的操作可以分为对表结构和对表内容的操作。 对表结构的操作&#xff0c;就是用数据定义语言 DDL 来创建、修改或删除表中的对象&#…

elementUI 中 date-picker 的使用的坑(vue3)

目录 1. 英文显示2. format 与 value-format 无效3. date-picker 时间范围4. 小结 1. 英文显示 <el-date-pickerv-model"dateValue"type"date"placeholder"选择日期"></el-date-picker>解决方案&#xff1a; 引用 zhCn <script&g…

web开发初级工程师学习笔记

web开发初级工程师学习笔记 前端开发工具实验1 VS Code 初体验介绍 前端开发工具 实验1 VS Code 初体验 介绍 VS Code 环境提供的是一个可以在浏览器中使用原生 VS Code 编辑代码的程序。在该环境中&#xff0c;你可以使用到与本地安装近乎一致的 VS Code 程序来编辑代码文件…

PAM从入门到精通(十九)

接前一篇文章&#xff1a;PAM从入门到精通&#xff08;十八&#xff09; 本文参考&#xff1a; 《The Linux-PAM Application Developers Guide》 PAM 的应用开发和内部实现源码分析 先再来重温一下PAM系统架构&#xff1a; 更加形象的形式&#xff1a; 六、整体流程示例 2.…

linux安装visual studio code

下载 https://code.visualstudio.com/ 下载.deb文件 安装 假如文件被下载到了 /opt目录下 进入Opt目录&#xff0c;右键从当前目录打开终端。 输入下面的安装命令。 sudo apt-get install ./code_1.83.1-1696982868_amd64.deb 安装成功。 配置 打开 visual studio cod…

博客续更(五)

十一、后台模块-菜单列表 菜单指的是权限菜单&#xff0c;也就是一堆权限字符串 1. 查询菜单 1.1 接口分析 需要展示菜单列表&#xff0c;不需要分页。可以针对菜单名进行模糊查询。也可以针对菜单的状态进行查询。菜单要按照父菜单id和orderNum进行排序 请求方式 请求路径…

Sentinel授权规则和规则持久化

大家好我是苏麟 , 今天说说Sentinel规则持久化. 授权规则 授权规则可以对请求方来源做判断和控制。 授权规则 基本规则 授权规则可以对调用方的来源做控制&#xff0c;有白名单和黑名单两种方式。 白名单&#xff1a;来源&#xff08;origin&#xff09;在白名单内的调用…

Linux下Jenkins自动化部署SpringBoot应用

Linux下Jenkins自动化部署SpringBoot应用 1、 Jenkins介绍 官方网址&#xff1a;https://www.jenkins.io/ 2、安装Jenkins 2.1 centos下命令行安装 访问官方&#xff0c;点击文档&#xff1a; 点击 Installing Jenkins&#xff1a; 点击 Linux&#xff1a; 选择 Red Hat/…