权限修饰符,代码块,抽象类,接口.Java

1,权限修饰符

  • 权限修饰符:用来控制一个成员能够被访问的范围
  • 可以修饰成员变量,方法,构造方法,内部类

👻👗👑权限修饰符的分类

  • 🧣四种作用范围由小到大(private<空着不写<protected<public)
修饰符同一个类中

同一个包中的其他类

不同包下的子类不同包下的无关类
private         √
空着不写         √            √
protected         √            √            √
public         √            √            √              √
  •  🧣private:私房钱,只能自己用

  • 🧣空着不写:只能本包中能用

  • 🧣protected:受保护的

  • 🧣public:公共的

2,代码块

👻含义:


 

 👻代码块分类

  • 局部代码块:写在方法或语句中的代码块 。

📝注意:变量的作用范围只在所属的代码块有效,出了代码块,就无法使用 

📝作用:提前结束变量的声明周期

  • 构造代码块

写在成员位置的代码块,在创建本类对象时,会优先与构造方法执行(每次创建对象时都会执行)。可以把多个构造方法中重复的代码写在构造代码块中。(这个方法过于死板,一般采用下面两个方法

  • 静态代码块

格式:static{},在构造代码块的基础上加了static

特点:需要通过static关键字修饰,随着类的加载而加载 ,并且自动触发,只执行一次

3,抽象类

一、什么是抽象类

🍑我们之前学过什么是类,那么抽象类是不是也是类的一种呢?

听名字就感觉好抽象呀!说对了,他就是抽象的,不是具体的。在类中没有包含足够的信息来描绘一个具体的对象,这样的类称为抽象类。

🌰来看一个抽象类的例子

// 抽象类和抽象方法需要被 abstract 关键字修饰
abstract class Shape {
    // 抽象类中的方法一般要求都是抽象方法,抽象方法没有方法体
    abstract void draw();
}

大家觉得这个抽象类是不是什么也没干,他唯一的方法draw()还是空的。

像这样的类是不是就没有包含足够的信息来描绘一个具体的对象,自然也就不能实例化对象了。不信你看:

 🍑那既然一个类不能实例化,那这种抽象类存在的意义是什么呀🤔?别急,存在即合理,听我慢慢道来。


二,抽象类在实现多态中的意义 

🍑抽象类存在的一个最大意义就是被继承,当被继承后就可以利用抽象类实现多态。

来看一段代码

// 抽象类和抽象方法需要被 abstract 关键字修饰
abstract class Shape {
    // 抽象类中的方法一般要求都是抽象方法,抽象方法没有方法体
    abstract void draw();
}
// 当一个普通类继承一个抽象类后,这个普通类必须重写抽象类中的方法
class Cycle extends Shape {
    @Override
    void draw() {  // 重写抽象类中的draw方法
        System.out.println("画一个圆圈");
    }
}
 
public class Test4 {
    public static void main(String[] args) {
        //Shape shape = new Shape();  抽象类虽然不能直接实例化
        // 但可以把一个普通类对象传给一个抽象类的引用呀,即父类引用指向子类对象
        Shape shape = new Cycle(); // 这称作:向上转型
        
        /*Cycle cycle = new Cycle();
          Shape shape = cycle // 这是向上转型的另一种写法
         */
        shape.draw();         // 通过父类引用调用被子类重写的方法
    }
}

运行之后你就会发现神奇的一幕:

📝什么是向上转型:一句话总结就是“父类引用指向子类对象” 

向上转型后的变化

🏀关于方法:父类引用可以调用子类和父类公用的方法(如果子类重写了父类的方法,则调用子类的方法),但子类特有的方法无法调用。
🏀关于属性: 父类引用可以调用父类的属性,不可以调用子类的属性


向上转型的作用

🐟减少一些重复性的代码
🐟对象实例化的时候可以根据不同需求实例化不同的对象

🌰这样的话就我们上面的代码就可以理解了

 🎀看来,我们可以通过子类对抽象类进行继承和重写,抽象类还真有点用呀!

🍑但这和多态有什么关系呢,抽象类用起来这么麻烦,我还不如直接用普通类,也能达到这样的效果,还不用再写一个子类呢😫?

🐟🐟🐟🐟🐟🐟🐟🐟🐟🐟🐟🐟🐟🐟🐟🐟

🌰那行,你再看看下面的代码,你就知道抽象类在实现多态时的好处了。 

abstract class Shape {
    public abstract void draw(); // 抽象方法不能里有具体的语句
}
// 当一个普通类继承一个抽象类的时候,再这个子类中必须重写抽象类中的抽象方法
class Cycle extends Shape {  
    @Override              // 如果不重写会报错,但如果继承的是普通类则不会报错,用抽象类更安全
    public void draw() {
        System.out.println("画一个圆圈");
    }
}
class Flower extends Shape { // 不同的子类对父类的draw方法进行了不同的重写
    @Override
    public void draw() {
        System.out.println("画一朵花");
    }
}
class Square extends Shape {
    @Override
    public void draw() {
        System.out.println("画一个正方形");
    }
}
 
public class Test4 {
    public static void main(String[] args) {
        Cycle cycle = new Cycle();   // 子类引用cycle
        Flower flower = new Flower(); // 子类引用flower
        Square square = new Square();
        
        // 数组的类型是Shape,即数组中每一个元素都是一个父类引用
        // 在这个过程其实也发生了向上转型,对抽象类中的方法进行了重写
        Shape[] shapes = {cycle, flower, square};  // 父类引用引用不同的子类对象
        for (int i = 0; i < shapes.length; i++) {
            Shape shape = shapes[i]; // 父类引用shape指向—>当前所对应的子类对象
 
            shape.draw();  // 通过父类引用调用子类重写的draw方法
        }
 
    }
}

结果 

 

🎠调用同一个方法竟然打印出了不同的结果😮,这难道就是所谓的多态🤔

🧶🧶🧶🧶🧶🧶🧶🧶🧶🧶🧶🧶🧶🧶🧶🧶

🎃原因就是

// 对上面的代码补充一下
// 可能你对 Shape[] shapes = {cycle, flower, square};不太理解
// 但上面的代码就相当于 
 
 Shape[] shapes1 = new Shape[3]; // 有三个不同的子类对象呀!数组大小为3
 
// (将指向->子类对象)的子类引用赋值给父类对象,不就相当于该夫类引用指向->所对应的子类对象吗
//这是向上转型的另一种写法,应为前面已经实例化了子类对象  Cycle cycle = new Cycle();   
 shapes1[0] = cycle;  // 如果前面没实例化子类对象,就要写成shape1[0] = new Cycle
 shapes1[1] = flower;
 shapes1[2] = square;

🎈对于多态来说,他有这三个要素

  • 继承(我们刚才的Cycle类继承Shape抽象类)
  • 重写(我们子类对draw方法的重写)
  • 父类指向子类对象(就是shape1[0] = cycle -->也可以称作向上转型) 

🍑回头再看一下我们的代码,是不是就刚好符合了多态的三要素😉。

📝当我们的父类引用指向不同的子类对象时,当我们调用同一个draw方法时却输出了不同的结果。(其实就是该方法再子类中被重写成了不同形式)这就叫做多态 。

嘻嘻😂,其实只要只要结合着例子来看,多态也没那么难理解呀😎

🍑那为啥一定要用抽象类呢😂?我一个普通类继承普通类来实现多态不可以吗🤔

🌰当然可以,但不太安全有风险;

     

但如果是抽象类的话,就不一样了😉 

 

🍑从这我们也可以看出,当用抽象类的时候,编译器自动就对我们是否重写进行了校验,而充分利用编译器的校验, 在实际开发中是非常有意义的 。所以说抽象类还是有用的,嘻嘻😉

📝好了,相信到这里你对抽象类也有了一个大概的认识😊,下面我们来简单做一下总结

  1. 使用abstract修饰的类或方法,就是抽象类或者抽象方法
  2. 抽象类不能具体的描述一个对象,也就是说不能实例化对象
  3. 抽象类里面的成员变量,都是和普通的类一样;成员方法要加abstract,且没有结构体
  4. 当一个普通类继承抽象类是,这个普通类必须重写抽象类中所有的抽象方法(🍑因为我们之前说抽象类不是具体的,没有包含足够的信息来描述一个对象,所以我们必须把他补充完整)
  5. 但当一个抽象类A继承了抽象类B,这时抽象类A就可以不重写抽象类B中的抽象方法
  6. final不能修饰抽象类和抽象方法(抽象类存在的最大意义就是被继承,而被final修饰的类不能被重写,final和抽象,它们两个就是天敌🎈🎈🎈🎈)
  7. 抽象方法不能被private修饰(抽象方法就是被重写的,被private修饰了,还怎么重写)
  8. 抽象类中不一定有抽象方法,但一个类中由抽象方法,那么这个类一定是抽象类

🐟🐟🐟🐟🐟🐟🐟🐟🐟🐟🐟🐟🐟🐟🐟🐟 

4,接口

一,介绍

👻🧣👑🥇🧸接口用于描述类具有什么功能,但不给出具体实现,当某个类要使用接口时,再去实现接口中的方法。类需要遵循接苦衷描述的统一规则进行定义,所以接口是对外提供的一组规则,标准

二,定义

🦄定义接口要用到关键字interface

  • interface 接口名{}

🦄类和接口之间不是继承关系,而是实现关系,用implements关键字表示。 

  • class 类名 implements 接口名{}

🧩需要注意的是:与类的定义相似,接口的访问权限修饰符只能是public或者默认

三,特点

🎨🎨接口成员变量的特点🎨🎨没有成员变量,只有公共静态常量,即在默认情况下都会有public static final 这三个关键字修饰。如下:

  • public static final  数据类型 常量名=常量值;

🧩注意:final关键字中要求,final属性必须初始化,而对于共有静态常量 (public static final),初始化的途径只有两条------①定义时显示初始化;②在静态代码块中初始化。但是,接口中不允许出现代码块,而且接口中没有构造方法。因此,要求我们在接口中定义公共静态常量时,必须在定义时就赋值否则IDEA就报错。

🎨🎨接口成员方法的特点🎨🎨

在TDK7.0版本及其之前的版本中,接口中仅支持只有公共抽象方法。如下:

  • public abstract 返回值类型 方法名();

🧩事实上,接口中的方法默认就是共有抽象方法,因此在定义时省略也可以。

从JDK8.0开始就可以有默认方法静态方法

  • 默认方法-----public default 返回值类型  方法名(){}
  • 静态方法-----public static 返回值类型 方法名(){} 

🧩注意,想要在接口中定义默认方法必须在前面加default关键字 ,因为接口中的方法你什么都不写,默认的就是共有抽象方法。默认方法可以有方法体,且不需要实现类取实现,其实就是我们平时见到的普通成员方法。但是默认方法是可以被实现重写的(不需要强制重写,需要用到再重写)。default关键字只能在接口中使用,就算实现类要重写方法也不能添加default修饰符,不然JDK报错;如果实现多个接口,不同接口中方法名相同,就必须要重写。

🧩静态方法只能通过接口名调用,不能通过类名或对象名进行调用,且不能被重写(重写是对虚方法表里面的方法进行重写覆盖掉,而static,final,private不在虚方法表里面)

JDK9.0以后,接口中可以有私有方法(private和private static)

  • private 返回值类型 方法名(){}

 

 🎨🎨接口中构造方法的特点🎨🎨:

接口不能被实例化🧸:

  • 只能通过多态的方式实例化“子类”对象(这里的“子类”是指接口的实现类

②接口的子类(实现类)🧸:

  • 可以是抽象类,也可以是普通类 

🧩对于抽象实现类,可以不用实现接口中的所有方法,因为抽象类本身就容许存在抽象方法,语法上是通过的;

🧩对于普通实现类 ,要实现接口中所以抽象方法。

批量实现抽象类的方法:alt+enter

四,接口继承关系的特点

👗①类和接口之间的关系

  • 类和接口是实现关系,支持多实现,即一个类可以实现多个接口

👗②接口和接口之间的关系

  • 接口和接口之间是继承关系,即一个接口可以同时继承多个接口,格式如下:

接口 extends 接口1,接口2,....... 

👗③ 继承和实现的关系

  • 🧩继承体现的是"is a"的关系,父类中定义共性内容
  • 🧩实现体现的是"like a"的关系,父接口中定义扩展内容

 五,适配器

👗当一个接口中的抽象方法过多时,但是我们只要其中一部分的时候,就可以用适配器设计模式

👗书写步骤:

  • 编写中间类XXXAdapter,实现对应的接口;
  • 对接口中的抽象方法进行空实现
  • 让真正的实现类继承中间类,并重写需要的方法;
  • 为了避免其他类创建适配器类的对象,中间的适配器类用abstract修饰

六,案例

 

👗👑🥇结果:

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

魔方网表ERP mailupdate.jsp 任意文件上传漏洞复现

0x01 产品简介 魔方网表ERP是一款高效、灵活的企业资源规划解决方案,旨在帮助企业实现数智化转型,消除信息孤岛,打造全程一体化的管理体系。魔方网表ERP拥有强大的表单功能和模块化的产品特点,使得企业可以根据自身业务需求,通过简单的拖拽和配置,快速搭建符合自身特点的…

linux使用docker实现redis主从复制和哨兵模式

目录 1. 拉取redis镜像 2.使用可视化redis工具 3. 设置从redis 4.设置哨兵模式 5. 使用docker-compose快速创建 1. 拉取redis镜像 docker pull redis 默认拉取最新的镜像。 然后pull结束后使用docker images检查镜像&#xff1a; 然后docker run创建container容器 首先…

测试需求分析

测试需求是什么&#xff1f; --需求文档 测试需求主要解决**“测什么”的问题&#xff0c;一般来自需求规格说明书中原始需求 测试需求应全部覆盖已定义的业务流程&#xff0c;以及功能和非功能**方面的需求 功能&#xff1a;基本用户需求–优先 非功能&#xff1a;界面&#…

使用DSP28335在CCS中生成正弦波

DSP芯片支持数学库&#xff0c;那如何通过DSP芯片生成一个正弦波呢&#xff1f;通过几天研究&#xff0c;现在将我的方法分享一下&#xff0c;如有错误&#xff0c;希望大家及时指出&#xff0c;共同进步。 sin函数的调用 首先看下一sin函数 的使用。 //头文件的定义 #includ…

基于springboot实现教学资源库系统项目【项目源码+论文说明】计算机毕业设计

基于springboot实现教学资源库系统演示 摘要 社会的进步&#xff0c;教育行业发展迅速&#xff0c;人们对教育越来越重视&#xff0c;在当今网络普及的情况下&#xff0c;教学模式也开始逐渐网络化&#xff0c;各大高校开始网络教学模式。 本文研究的教学资源库系统基于Sprin…

Linux的学习之路:8、Linux调试器-gdb使用

摘要 本章主要是说一下gdb的使用&#xff0c;以及把使用指令放入放个指令手册。 目录 摘要 一、背景 二、使用 1、产生debug文件 2、进入gdb 3、使用指令 三、思维导图 一、背景 Linux调试器gdb的背景主要涉及到Linux程序发布方式和调试需求。 在Linux中&#xff0c…

一款自研Python解释器

项目简介: PikaScript是一个完全重写的超轻量级python引擎,具有完整的解释器,字节码和虚拟机架构,可以在少于4KB的RAM下运行,用于小资源嵌入式系统。相比同类产品,如MicroPython,LuaOS等,资源占用减少85%以上。 入选2021年度 Gitee最有价值开源项目,加入RT-Thread嵌入…

动态规划(背包问题)

一:动态规划概述: 动态规划实际上是一种将原本的 大 方面的问题转化为许许多多的 小方面 的一种应用, 在一定程度上避免数据的重复, 并且能够将数据以自己希望的方式进行存储, 用来解决多阶段的数学问题, 从而提高算法的效率 在算法当中, 动态规划主要包括有: 递推, 线性DP 记忆…

不惑之年,反思我如何成为一个程序员

不惑之年&#xff0c;反思我如何成为一个程序员 文章目录 不惑之年&#xff0c;反思我如何成为一个程序员01/偶然掉入码河02/现实撕碎理想03/发展选择方向04/时代成就向往05/幸运装饰未来 在这个充满生机与希望的季节&#xff0c;博主有幸收到一家国企邀约面试&#xff0c;并顺…

【好消息】思维100活动历年真题模拟题700多道上线了,供反复吃透

今天是星期五&#xff0c;距离4月20日举办的上海小学生 2024年春季思维100活动线上比赛还有8天的时间&#xff0c;明天、后天的周末是可以用来备考的大块时间&#xff0c;报名了的同学要充分利用了。 为了帮助各位小朋友了解思维100活动的历年考试真题、官方发布的参考样题&…

ssm044基于java和mysql的多角色学生管理系统+jsp

学生管理系统设计与实现 摘 要 现代经济快节奏发展以及不断完善升级的信息化技术&#xff0c;让传统数据信息的管理升级为软件存储&#xff0c;归纳&#xff0c;集中处理数据信息的管理方式。本学生管理系统就是在这样的大环境下诞生&#xff0c;其可以帮助管理者在短时间内处…

力扣207.课程表

你这个学期必须选修 numCourses 门课程&#xff0c;记为 0 到 numCourses - 1 。 在选修某些课程之前需要一些先修课程。 先修课程按数组 prerequisites 给出&#xff0c;其中 prerequisites[i] [ai, bi] &#xff0c;表示如果要学习课程 ai 则 必须 先学习课程 bi 。 例如…

新版chrome 解决在http协议下无法调用摄像头和麦克风的问题(不安全)

解决办法&#xff1a;亲测可行 chrome浏览器地址栏中输入chrome://flags/#unsafely-treat-insecure-origin-as-secure&#xff0c;回车&#xff0c;如下图&#xff0c;将该选项置为Enabled&#xff0c; edge浏览器打开&#xff1a;edge://flags/#unsafely-treat-insecure-orig…

TDengine taosAdapter启用HTTPS

HTTPS &#xff08;Hypertext Transfer Protocol Secure &#xff09;&#xff0c;是以安全为目标的 HTTP 通道&#xff0c;在HTTP的基础上通过传输加密和身份认证保证了传输过程的安全性 。HTTPS 在HTTP 的基础下加入SSL&#xff0c;HTTPS 的安全基础是 SSL&#xff0c;因此加…

利用细粒度检索增强和自我检查提升对话式问题解答能力

&#x1f349; CSDN 叶庭云&#xff1a;https://yetingyun.blog.csdn.net/ 论文标题&#xff1a;Boosting Conversational Question Answering with Fine-Grained Retrieval-Augmentation and Self-Check 论文地址&#xff1a;https://arxiv.org/abs/2403.18243 检索增强生成…

使用easyexcel读取excel并生成sql语句

1、引入pom依赖 <?xml version"1.0" encoding"UTF-8"?> <project xmlns"http://maven.apache.org/POM/4.0.0"xmlns:xsi"http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation"http://maven.apache.org/POM…

.NET Framework安装失败的原因及解决方法

.NET Framework安装失败的原因及解决方法 大家好我是艾西&#xff0c;一个做服务器租用的游戏爱好者兼网络架构系统环境问题网络工具人。在我们平时使用PC安装某些程序会出现.NET Framework缺失的提示&#xff0c;那么也会有很多的小伙伴搞不懂什么原因导致的&#xff0c;这个问…

MySQL 04-EMOJI 表情与 UTF8MB4 的故事

拓展阅读 MySQL View MySQL truncate table 与 delete 清空表的区别和坑 MySQL Ruler mysql 日常开发规范 MySQL datetime timestamp 以及如何自动更新&#xff0c;如何实现范围查询 MySQL 06 mysql 如何实现类似 oracle 的 merge into MySQL 05 MySQL入门教程&#xff0…

深水采样器小口径特氟龙材质FEP贝勒管

FEP贝勒管&#xff0c;深水采样器(bailers tube)&#xff0c;是一种经济型便携式水质采样器&#xff0c;操作简单&#xff0c;使用方便&#xff0c;性价比高&#xff0c;能大限度的保证样品的真实性。采样管直径很小&#xff0c;能够采取小口径的深水井水样。是一款简单实用&am…

L2-026 小字辈

一、题目要求 本题给定一个庞大家族的家谱&#xff0c;要请你给出最小一辈的名单。 输入格式&#xff1a; 输入在第一行给出家族人口总数 N&#xff08;不超过 100 000 的正整数&#xff09; —— 简单起见&#xff0c;我们把家族成员从 1 到 N 编号。随后第二行给出 N 个编…