Java 多态、包、final、权限修饰符、静态代码块
多态
Java多态是指一个对象可以具有多种形态。它是面向对象编程的一个重要特性,允许子类对象可以被当作父类对象使用。多态的实现主要依赖于继承、接口和方法重写。
在Java中,多态的实现主要通过以下两种方式:
-
继承:子类继承父类的属性和方法,可以对方法进行重写(覆盖),从而实现不同的行为。
-
接口:类可以实现一个或多个接口,从而拥有接口中定义的方法。接口中的方法默认是抽象的,需要类来实现。
下面是一个简单的Java多态示例:
// 父类
class Animal {public void makeSound() {System.out.println("动物发出声音");}
}// 子类
class Dog extends Animal {@Overridepublic void makeSound() {System.out.println("狗汪汪叫");}
}// 子类
class Cat extends Animal {@Overridepublic void makeSound() {System.out.println("猫喵喵叫");}
}public class Main {public static void main(String[] args) {// 使用父类引用指向子类对象,实现多态Animal myAnimal = new Dog();myAnimal.makeSound(); // 输出:狗汪汪叫myAnimal = new Cat();myAnimal.makeSound(); // 输出:猫喵喵叫}
}
在这个示例中,Dog 和 Cat 类都继承了 Animal 类,并重写了 makeSound 方法。在 main 方法中,我们使用父类 Animal 的引用来指向子类 Dog 和 Cat 的对象,实现了多态。当我们调用 makeSound 方法时,会根据实际对象的类型来执行相应的方法。
核心要素
多态的存在依赖于三个核心要素:
- 继承:多态的实现基于类的继承关系。这意味着必须有一个父类和至少一个子类,子类从父类那里继承了某些属性和方法。
- 方法重写:在子类中对继承自父类的方法进行重写(覆盖)。这样,当调用这些方法时,可以根据对象的实际类型(父类或子类)来执行相应的方法版本。
- 父类引用指向子类对象:使用父类类型的引用来指向子类的对象实例。这使得可以通过父类引用来操作子类对象,实现在不同子类对象上执行相同的操作,但表现出不同的行为。
此外,多态性通常与方法有关,与类的属性无关。这是因为多态性主要关注通过同一个接口(父类引用)调用不同类(子类)中的方法时,如何根据对象的实际类型来执行相应的方法版本。
多态的弊端
多态在面向对象编程中是一种强大的特性,它允许不同类的对象对同一消息做出响应。然而,尽管多态性提高了代码的灵活性和可维护性,但它也有一些弊端。具体来说,多态的弊端主要包括以下几点:
- 不能直接使用子类的特有属性和行为:当使用父类引用指向子类对象时,只能访问到父类中定义的属性和方法,而不能直接访问子类特有的属性和方法。这是因为在多态的情况下,编译器只知道该引用是父类类型,而不知道具体是哪个子类的实例。
- 需要进行向下转型(强制类型转换):为了能够访问子类特有的属性和方法,需要将父类引用显式地转换为子类类型,这个过程称为向下转型。然而,向下转型可能会带来风险,如果转型的类型不正确,就会抛出
ClassCastException异常。 - 可能导致设计上的问题:过度依赖多态可能会导致设计上的问题,例如破坏了封装性,因为需要在外部代码中进行类型转换,这可能会增加代码的复杂性和出错的可能性。
instanceof 关键字
instanceof是Java中的一个关键字,用于检查一个对象是否属于某个类或接口的实例。它的语法格式为:
object instanceof ClassName
其中,object是要检查的对象,ClassName是要检查的类或接口的名称。如果object是ClassName的实例,那么表达式的结果为true,否则为false。
例如,假设我们有一个名为Animal的类和一个名为Dog的子类,我们可以使用instanceof来检查一个对象是否是Animal或Dog的实例:
Animal animal = new Animal();
Dog dog = new Dog();if (animal instanceof Animal) {System.out.println("animal 是 Animal 的实例");
}if (dog instanceof Animal) {System.out.println("dog 是 Animal 的实例");
}if (dog instanceof Dog) {System.out.println("dog 是 Dog 的实例");
}
输出结果为:
animal 是 Animal 的实例
dog 是 Animal 的实例
dog 是 Dog 的实例
包
Java 包是一种命名空间,用于将类和接口进行分组管理,它有助于提高代码的可读性、查找效率以及控制访问权限。以下是关于Java包的一些基本信息:
- 概念:Java 包是组织类和接口的一种机制,它可以防止命名冲突,并且有助于管理大型项目中的代码。
- 声明:在Java文件中,使用
package关键字来声明一个包。例如,package com.example;表明该文件属于com.example这个包。 - 导入:要使用其他包中的类,可以使用
import关键字来导入。例如,import java.util.List;表示导入了java.util包下的List类。 - 作用域:包的作用域决定了类和接口的可见性。默认情况下,类和接口的访问级别是包私有的,即只有相同包内的其他类可以访问。
- 命名规范:包的命名通常采用全小写字母,并使用点号
.分隔不同的名称层级,如com.example.myapp。这种命名方式有助于避免与标准Java类库的名称冲突,并且反映了组织的域名结构。 - 创建包:在IDE(如IntelliJ IDEA)中,可以通过右键点击项目目录结构来创建新的包。然后,可以在新包中创建类和其他资源。
- 访问方法:要访问不同包中的类,可以使用类的完全限定名(包括包名和类名),或者通过import语句导入后直接使用类名。
- 注意事项:在设计包结构时,应该考虑到代码的逻辑分组和功能划分,以便于维护和扩展。同时,避免创建过于庞大或过于细化的包,以免造成管理上的不便。
Java 包是管理Java代码的一个重要工具,它不仅能够帮助开发者组织代码结构,还能够提供访问控制和命名空间的管理功能。在大型项目中,合理地使用包可以大大提高代码的可维护性和可读性。
fianl 关键字
final关键字在Java中确实扮演着重要的角色,它可以用来修饰类、方法和变量,下面是对这些用途的详细介绍:
- 修饰类:当一个类被声明为
final时,它不能被继承。这通常用于那些包含核心功能且不希望被修改的类。例如,Java中的String类就是一个final类,因为它的设计不允许更改其核心行为。final class FinalClass {// 该类不能被继承 }// class SubFinalClass extends FinalClass { // 错误,无法继承final类 // // ... // } - 修饰方法:
final方法不能被子类重写。这通常用于确保某些方法的行为在子类中保持一致,或者出于安全考虑,防止子类改变其行为。class MyClass {public final void printMessage() {System.out.println("This is a final method.");} }class SubClass extends MyClass {// 无法重写父类的final方法// public void printMessage() {// System.out.println("Cannot override final method.");// } } - 修饰成员变量:成员变量被声明为
final后,只能被赋值一次,即它们的值在初始化后就不能再更改。这有助于确保数据的不变性,这对于创建不可变对象非常有用。final int MAX_VALUE = 100; // 定义一个常量,其值不能被修改 int count = 0; count = MAX_VALUE; // 正确赋值 // count = 200; // 错误赋值,会编译报错 - 修饰局部变量:局部变量被声明为
final后,也必须在声明时或构造函数内赋值,之后不能再更改。这有助于提高代码的可读性和可维护性,因为它明确表明了变量的值在初始化后不会发生变化。public void myMethod() {final int localVar = 10; // 局部变量被声明为final// localVar = 20; // 错误,无法修改final变量的值 } - 修饰方法参数:当方法参数被声明为
final时,它可以确保参数在方法执行期间不会被修改。这有助于避免在方法内部意外修改参数值的错误。public void myMethod(final int value) {// value = 20; // 错误,无法修改final参数的值 }
final关键字是Java中一个重要的工具,它通过限制类的继承、方法的重写和变量的修改,帮助开发者编写更安全、更稳定的代码。在使用final关键字时,需要根据具体的需求和设计考虑来决定是否使用,以及如何使用,以确保代码的可读性和可维护性。
权限修饰符
在Java中,权限修饰符是用来控制类、变量、方法和构造函数访问权限的一种机制。它们定义了其他类对这些成员的访问级别。Java提供了以下几种权限修饰符:
- public:公共的,没有访问限制。任何外部类都可以访问公共的成员。
public class MyClass {public int publicVar; // 公共变量,可以在任何地方访问 }class AnotherClass {MyClass obj = new MyClass();obj.publicVar = 10; // 可以访问公共变量 } - private:私有的,只能在其定义的类内部访问。从外部类无法直接访问私有成员,但可以通过公共方法(如getter和setter)进行访问。
public class MyClass {private int privateVar; // 私有变量,只能在类内部访问public void setPrivateVar(int value) {privateVar = value; // 通过公共方法设置私有变量的值}public int getPrivateVar() {return privateVar; // 通过公共方法获取私有变量的值} }class AnotherClass {MyClass obj = new MyClass();// obj.privateVar = 10; // 错误,无法直接访问私有变量obj.setPrivateVar(10); // 通过公共方法设置私有变量的值int value = obj.getPrivateVar(); // 通过公共方法获取私有变量的值 } - protected:受保护的,可以在同一个包内以及子类中访问。如果试图从其他包的非子类中访问,则会出错。
public class MyClass {protected int protectedVar; // 受保护的变量,可以在同一个包内以及子类中访问 }class AnotherClass {MyClass obj = new MyClass();obj.protectedVar = 10; // 可以访问受保护变量(在同一个包内) }class SubClass extends MyClass {void accessProtectedVar() {protectedVar = 20; // 可以访问受保护变量(在子类中)} } - 默认(无修饰符):也称为包级私有,只能在同一个包内访问。如果试图从其他包中访问,则会出错。
package com.example;public class MyClass {int defaultVar; // 默认访问权限的变量,只能在同一个包内访问 }class AnotherClass {MyClass obj = new MyClass();obj.defaultVar = 10; // 可以访问默认访问权限的变量(在同一个包内) }
这些修饰符可以用来控制对类、变量、方法和构造函数的访问,从而确保数据的安全性和封装性。在编写Java代码时,应根据具体需求选择适当的权限修饰符来保护成员的访问权限。
| public | protected | 默认 | private | |
|---|---|---|---|---|
| 同一类中 | √ | √ | √ | √ |
| 同一包中的类 | √ | √ | √ | |
| 不同包的子类 | √ | √ | ||
| 不同包中的无关类 | √ |
静态代码块
静态代码块是指在Java类中定义的静态代码块,它在类被加载时执行一次。静态代码块通常用于初始化静态变量或执行一些只需要执行一次的操作。以下是一个简单的Java静态代码块示例:
public class MyClass {static {System.out.println("This is a static block.");}public static void main(String[] args) {System.out.println("Hello, World!");}
}
在这个示例中,当MyClass类被加载时,静态代码块会被执行一次,输出"This is a static block."。然后,程序进入main方法,输出"Hello, World!"。
相关文章:
Java 多态、包、final、权限修饰符、静态代码块
多态 Java多态是指一个对象可以具有多种形态。它是面向对象编程的一个重要特性,允许子类对象可以被当作父类对象使用。多态的实现主要依赖于继承、接口和方法重写。 在Java中,多态的实现主要通过以下两种方式: 继承:子类继承父类…...
基于Spring boot + Vue协同过滤算法的电影推荐系统
末尾获取源码作者介绍:大家好,我是墨韵,本人4年开发经验,专注定制项目开发 更多项目:CSDN主页YAML墨韵 学如逆水行舟,不进则退。学习如赶路,不能慢一步。 目录 一、项目简介 二、开发技术与环…...
Chrome之解决:浏览器插件不能使用问题(十三)
简介: CSDN博客专家,专注Android/Linux系统,分享多mic语音方案、音视频、编解码等技术,与大家一起成长! 优质专栏:Audio工程师进阶系列【原创干货持续更新中……】🚀 优质专栏:多媒…...
【正版特惠】IDM 永久授权 优惠低至109元!
尽管小编有修改版IDM,但是由于软件太好用了,很多同学干脆就直接购买了正版,现在正版也不贵,并且授权码绑定自己的邮箱,直接官方下载激活,无需其他的绿化修改之类的操作,不喜欢那么麻烦的&#x…...
SpringBoot与Prometheus监控整合
参考: springboot实战之prometheus监控整合-腾讯云开发者社区-腾讯云 https://www.cnblogs.com/skevin/p/15874139.html https://www.jianshu.com/p/e5dc2b45c7a4...
Linux 系统 docker搭建LNMP环境
1、安装nginx docker pull nginx (默认安装的是最新版本) 2、运行nginx docker run --name nginx -p 80:80 -d nginx:latest 备注:--name nginx 表示容器名为 nginx -d 表示后台运行 -p 80:80 表示把本地80端口绑定到Nginx服务端的 80端口 nginx:lates…...
拉普拉斯变换
定义: 拉普拉斯变换是一种在信号处理、控制理论和其他领域中广泛使用的数学工具,用于将一个函数从时域转换到复频域。拉普拉斯变换将一个函数 f(t) 变换为一个复变量函数 F(s),其中 s 是复数变量。下面是拉普拉斯变换的推导过程:…...
Mashup-Math_Topic_One
Tutorial and Introspection A Rudolf and 121 注意到第 1 1 1 位只能被第 2 2 2 位影响,以此类推位置,对于 a i a_i ai , 如果 < 0 < 0 <0 ,不合法 ; 否则, a i − a i , a i 1 − 2 ∗ a i , a i 2 − a …...
基于JavaWEB SSM SpringBoot婚纱影楼摄影预约网站设计和实现
基于JavaWEB SSM SpringBoot婚纱影楼摄影预约网站设计和实现 博主介绍:多年java开发经验,专注Java开发、定制、远程、文档编写指导等,csdn特邀作者、专注于Java技术领域 作者主页 央顺技术团队 Java毕设项目精品实战案例《1000套》 欢迎点赞 收藏 ⭐留言…...
逐步学习Go-Select多路复用
概述 这里又有多路复用,但是Go中的这个多路复用不同于网络中的多路复用。在Go里,select用于同时等待多个通信操作(即多个channel的发送或接收操作)。Go中的channel可以参考我的文章:逐步学习Go-并发通道chan(channel)…...
王道:OJ15
课时15作业 Description 读取10个元素 87 7 60 80 59 34 86 99 21 3,然后建立二叉查找树,排序后输出3 7 21 34 59 60 80 86 87 99,针对有序后的元素,存入一个长度为10的数组中,通过折半查找找到21的下标(…...
【案例·查】数据类型强制转换,方便查询匹配
问题描述: MySQL执行中需要将某种数据类型的表达式显式转换为另一种数据类型,可以使用 SQL 中的cast()来处理 案例: SELECT CAST(9.0 AS decimal) #String化为小数类型SELECT * FROM table_1 WHERE 1888-03-07 CAST(theDate AS DATE) …...
spring boot3自定义注解+拦截器+Redis实现高并发接口限流
⛰️个人主页: 蒾酒 🔥系列专栏:《spring boot实战》 🌊山高路远,行路漫漫,终有归途 目录 写在前面 内容简介 实现思路 实现步骤 1.自定义限流注解 2.编写限流拦截器 3.注册拦截器 4.接口限流测试 写在前…...
使用certbot为网站启用https
1. 安装certbot客户端 cd /usr/local/bin wget https://dl.eff.org/certbot-auto chmod ax ./certbot-auto 2. 创建目录和配置nginx用于验证域名 mkdir -p /data/www/letsencryptserver {listen 80;server_name ~^(?<subdomain>.).ninvfeng.com;location /.well-known…...
Unity 背包系统中拖拽物体到指定位置或互换位置效果的实现
在Unity中,背包系统是一种常见的游戏系统,可以用于管理和展示玩家所持有的物品、道具或装备。 其中的拖拽功能非常有意思,具体功能就是玩家可以通过拖拽物品图标来移动物品在背包中的位置,或者将物品拖拽到其他位置或界面中&…...
iOS客户端自动化UI自动化airtest+appium从0到1搭建macos+脚本设计demo演示+全网最全最详细保姆级有步骤有图
Android客户端自动化UI自动化airtest从0到1搭建macos脚本设计demo演示全网最全最详细保姆级有步骤有图-CSDN博客 避坑系列-必读: 不要安装iOS-Tagent ,安装appium -这2个性质其实是差不多的都是为了安装wda。注意安装appium最新版本,安装完…...
每周编辑精选|在线运行 Deepmoney 金融大模型、AI 偏好等多个优质数据集上线
目前,AI 领域对金融模型的研究成果大多是基于公共知识进行训练的,但在实际的金融实践中,这些公共知识对于当前市场的可解释性往往严重不足。一个理想的金融大模型应该能够理解新闻或数据事件,并能够即时地从主观和量化两个角度对事…...
C++多重继承与虚继承
多重继承的原理 多重继承(multiple inheritance)是指从多个直接基类中产生派生类的能力。 多重继承的派生类继承了所有父类的属性。 在面向对象的编程中,多重继承意味着一个类可以从多个父类继承属性和方法。 就像你有一杯混合果汁,它是由多种水果榨取…...
请简单介绍一下Shiro框架是什么?Shiro在Java安全领域的主要作用是什么?Shiro主要提供了哪些安全功能?
请简单介绍一下Shiro框架是什么? Shiro框架是一个强大且灵活的开源安全框架,为Java应用程序提供了全面的安全解决方案。它主要用于身份验证、授权、加密和会话管理等功能,可以轻松地集成到任何Java Web应用程序中,并提供了易于理解…...
TouchGFX之Button
TouchGFX中的按钮是一种感应触控事件的控件,能够在按钮被按下/释放时发送回调 代码 #ifndef TOUCHGFX_ABSTRACTBUTTON_HPP #define TOUCHGFX_ABSTRACTBUTTON_HPP #include <touchgfx/Callback.hpp> #include <touchgfx/events/ClickEvent.hpp> #includ…...
浏览器访问 AWS ECS 上部署的 Docker 容器(监听 80 端口)
✅ 一、ECS 服务配置 Dockerfile 确保监听 80 端口 EXPOSE 80 CMD ["nginx", "-g", "daemon off;"]或 EXPOSE 80 CMD ["python3", "-m", "http.server", "80"]任务定义(Task Definition&…...
Chapter03-Authentication vulnerabilities
文章目录 1. 身份验证简介1.1 What is authentication1.2 difference between authentication and authorization1.3 身份验证机制失效的原因1.4 身份验证机制失效的影响 2. 基于登录功能的漏洞2.1 密码爆破2.2 用户名枚举2.3 有缺陷的暴力破解防护2.3.1 如果用户登录尝试失败次…...
Python爬虫实战:研究feedparser库相关技术
1. 引言 1.1 研究背景与意义 在当今信息爆炸的时代,互联网上存在着海量的信息资源。RSS(Really Simple Syndication)作为一种标准化的信息聚合技术,被广泛用于网站内容的发布和订阅。通过 RSS,用户可以方便地获取网站更新的内容,而无需频繁访问各个网站。 然而,互联网…...
电脑插入多块移动硬盘后经常出现卡顿和蓝屏
当电脑在插入多块移动硬盘后频繁出现卡顿和蓝屏问题时,可能涉及硬件资源冲突、驱动兼容性、供电不足或系统设置等多方面原因。以下是逐步排查和解决方案: 1. 检查电源供电问题 问题原因:多块移动硬盘同时运行可能导致USB接口供电不足&#x…...
多模态商品数据接口:融合图像、语音与文字的下一代商品详情体验
一、多模态商品数据接口的技术架构 (一)多模态数据融合引擎 跨模态语义对齐 通过Transformer架构实现图像、语音、文字的语义关联。例如,当用户上传一张“蓝色连衣裙”的图片时,接口可自动提取图像中的颜色(RGB值&…...
JavaScript基础-API 和 Web API
在学习JavaScript的过程中,理解API(应用程序接口)和Web API的概念及其应用是非常重要的。这些工具极大地扩展了JavaScript的功能,使得开发者能够创建出功能丰富、交互性强的Web应用程序。本文将深入探讨JavaScript中的API与Web AP…...
Kafka入门-生产者
生产者 生产者发送流程: 延迟时间为0ms时,也就意味着每当有数据就会直接发送 异步发送API 异步发送和同步发送的不同在于:异步发送不需要等待结果,同步发送必须等待结果才能进行下一步发送。 普通异步发送 首先导入所需的k…...
Razor编程中@Html的方法使用大全
文章目录 1. 基础HTML辅助方法1.1 Html.ActionLink()1.2 Html.RouteLink()1.3 Html.Display() / Html.DisplayFor()1.4 Html.Editor() / Html.EditorFor()1.5 Html.Label() / Html.LabelFor()1.6 Html.TextBox() / Html.TextBoxFor() 2. 表单相关辅助方法2.1 Html.BeginForm() …...
Python 高效图像帧提取与视频编码:实战指南
Python 高效图像帧提取与视频编码:实战指南 在音视频处理领域,图像帧提取与视频编码是基础但极具挑战性的任务。Python 结合强大的第三方库(如 OpenCV、FFmpeg、PyAV),可以高效处理视频流,实现快速帧提取、压缩编码等关键功能。本文将深入介绍如何优化这些流程,提高处理…...
Sklearn 机器学习 缺失值处理 获取填充失值的统计值
💖亲爱的技术爱好者们,热烈欢迎来到 Kant2048 的博客!我是 Thomas Kant,很开心能在CSDN上与你们相遇~💖 本博客的精华专栏: 【自动化测试】 【测试经验】 【人工智能】 【Python】 使用 Scikit-learn 处理缺失值并提取填充统计信息的完整指南 在机器学习项目中,数据清…...
