JavaSE——类与对象(5)
一、抽象类
1.1为什么需要抽象类
父类的某些方法,不确定怎么实现,也不需要实现。
class Animal{public String name;public Animal(String name){this.name = name;}public void eat()//这里实现了也没有意义{System.out.println("这是一个动物,但是不知道吃什么..");}
}
像上面这个例子,属于一个父类方法不确定性问题,可以考虑将这个方法设计为抽象方法。所谓的抽象方法就是没有实现的方法,没有实现的方法就是没有方法体,当一个类中存在抽象方法时,需要将这个类声明为抽象类。一般来讲,抽象类会被继承,由其子类来实现抽象方法。
1.2抽象类的细节
- 抽象类不能被实例化。
- 抽象类不一定要包含abstract方法,也就是说,抽象类可以没有abstract方法。
- 一旦类包含了abstract方法,那么这个类必须时abstract类。
- abstract只能修饰类和方法,不能修饰属性和其它的。
- 抽象类可以拥有任意成员,抽象类的本质还是类。
- 如果一个类继承了抽象类,则它必须实现抽象类的所有方法,除非它自己也声明为抽象类。
- 抽象方法,不能使用private、final和static来修饰。
二、接口
2.1接口的基本介绍
接口就是给出一些没有实现的方法,封装到一起,到某个类要使用的时候,再根据具体情况把这些方法写出来。
定义的基本语法:
interface 接口名{属性方法
}
调用的基本语法:
class 类名 implements 接口{自己属性;自己方法;必须实现的接口的方法;
}
在JDK7以前,接口中的所有方法都是抽象方法,在JDK7以后的版本中,可以有静态方法和默认方法。另外接口不需要声明为抽象类。
2.2接口的使用细节
- 接口不能被实例化。
- 接口中的所有方法都是public方法,即使没有使用public修饰符,它也是public的。
- 接口中抽象方法,可以不用abstract修饰。
- 一个普通类上实现接口,必须将该接口的所有方法都实现。
- 抽象类实现接口,可以不用实现接口的方法。
- 一个类允许实现多个接口。
- 接口中的属性,只能是final的,而且默认是public static final修饰符。
- 接口中属性的访问形式:接口名.属性名。
- 一个接口不能继承其它类,但是可以继承多个别的接口。
- 接口的修饰符只能是public和默认。
2.3接口与继承
- 继承和接口解决的问题不同:
- 继承的价值在于:解决代码的复用性和可维护性。
- 接口的价值在于:设计好各种规范和方法,让其它类去实现这些方法。
- 接口比继承更加灵活,可以说是对Java单继承方式的一种补充,继承满足is-a关系,接口只需要满足like-a关系。
- 接口在一定程度上实现代码解耦。
2.4接口的多态特性
- 多态参数:接口引用可以指向实现了接口的类的对象。
public class Interface01{public static void main(String[] args) {IH ih = new A();IG ig = new A();} }interface IH{} interface IG{}class A implements IH{} - 多态数组:多态性允许一个引用类型指向多种实际类型的对象。这种特性在处理数组时尤为有用,因为数组可以存储指向不同子类对象的引用,即使数组的声明类型是父类类型。
- 接口存在多态传递现象
public class Interface01{public static void main(String[] args) {IH ih = new A();IG ig = new A();} }interface IH{} interface IG{} //interface IH extends IG{};A实现IH的同时把IG也实现了class A implements IH{}
三、内部类
3.1什么是内部类
一个类的内部完整的嵌套了另一个类结构,被嵌套的类称为内部类,嵌套其它类的类被称为外部类。一个内部类:
class Outer{//外部类private int i = 100;//属性public Outer(int n1){//构造器this.i = n1;}public void m1(){//方法System.out.println("m1()");}{//代码块System.out.println("代码块...");}class Inner{//内部类}
}
3.2内部类的分类
定义在外部类局部位置上(比如方法内):
- 局部内部类(没有类名)
- 匿名内部类(没有类名)
定义在外部类的成员位置上:
- 成员内部类(未用static修饰)
- 静态内部类(使用static修饰)
3.3局部内部类
局部内部类定义在外部类的局部位置,比如方法中,并且有类名。
class Outer{//外部类private int i = 100;//属性public Outer(int n1){//构造器this.i = n1;}public void m1(){//方法System.out.println("m1()");}{//代码块System.out.println("代码块...");}public void m2(){class Inner{ //不能添加访问修饰符,因为它是一个局部变量,局部变量不能使用修饰符。//但是可以用final修饰public void m3(){System.out.println(i);//可以直接访问外部类的所有成员,包含私有的。}}Inner i = new Inner();//外部类访问内部类,先创建对象再访问,必须在作用域内。i.m3();}
}
总结:
- 内部类可以直接访问外部类的所有成员,包括私有的。
- 外部类访问内部类的成员需要先创建内部类的对象,再访问,并且必须在作用域内部。
- 作用域:仅仅在定义它的方法或者代码块中。
- 除final之外不能使用访问修饰符。
- 局部内部类本质是一个类也可以被继承。
- 如果外部类和内部类的成员重名,默认遵循就近原则,如果想要访问外部类的成员,使用外部类名.this.变量名。
3.4匿名内部类
匿名内部类是定义在外部类的局部位置,没有名字的类(其实有,只不过是由编译器取的,程序员看不见也不能干涉)。
假设我们有一个接口A,内部有一个未被实现的方法eat,如果想要在main中直接调用eat方法,按照传统思路是先用一个类来实现接口A,同时再创建B的对象来调用A。
public class Interface01 {public static void main(String[] args) {B b = new B();b.eat();}
}
interface A{public void eat();
}
class B implements A{@Overridepublic void eat() {System.out.println("正在调用eat方法");}
}
但是,如果这个方法只会实现一次,如果为此单独写一个类还要再创建对象的化,未免有些古板,这里就可以采用匿名内部类。
public class Interface01 {public static void main(String[] args) {new A(){@Overridepublic void eat() {System.out.println("正在调用eat方法");}}.eat();}
}
interface A{public void eat();
}
这是的匿名内部类相当于一个对象,所以它的后面可以直接调用eat方法。当A里面有多个方法时,如果想要同时调用,可以采用下面的方法。
public class Interface01 {public static void main(String[] args) {//编译器创建了一个类继承了A类,并且在内部重写了下面这些方法。//编译类型是A,运行类型是Interface01$1A a = new A(){@Overridepublic void eat() {System.out.println("正在调用eat方法");}public void drink(){System.out.println("正在调用drink方法");}};a.eat();a.drink();}
}
interface A{public void eat();public void drink();
}
匿名内部类常用做实参进行传递:
public class InnerClassExercise {public static void main(String[] args) {Cellphone cellphone = new Cellphone();cellphone.alarmlock(new Bell(){@Overridepublic void ring() {System.out.println("懒猪起床了");}});Bell innerclass = new Bell(){@Overridepublic void ring() {System.out.println("小伙伴上课了");}};cellphone.alarmlock(innerclass);}
}interface Bell{void ring();
}class Cellphone{public void alarmlock(Bell bell){bell.ring();}
}
总结:
- 匿名内部类本身既是一个类的定义,也是一个对象,所以从语法上看,它既有定义类的特征,也有创建对象的特征。
- 可以直接访问外部类的所有成员,包含私有的。
- 不能直接添加访问修饰符,因为他的地位就是一个局部变量。
- 作用域:仅仅再定义它的方法内部或者代码块中。
- 外部的其它类不能访问内部匿名类。
- 如果外部类和匿名内部类的成员重名,默认遵循就近原则,也可以通过(外部类名.this.成员名)去访问。
3.5成员内部类
成员内部类是定义再外部类的成员位置,并且没有static修饰。
public class MemberInnerClass01 {public static void main(String[] args) {Outer01 outer01 = new Outer01();outer01.t1();}
}class Outer01{private int a = 10;public String name = "张三";class InnerClass{public void say(){//可以直接访问外部类的成员System.out.println("Outer01的a = " + a + "\tOuter01的name + " + name);}}public void t1(){InnerClass innerClass = new InnerClass();innerClass.say();}
}
总结:
- 可以直接访问外部类的所有成员,包含私有的。
- 可以添加任意访问修饰符(public、protected、默认、private),因为它的地位是一个成员。
- 作用域:和外部域的其他成员一样,为整个类体比如前面案例。在外部类的成员方法中创建成员内部类对象,再调用方法。
- 成员内部类访问外部类成员:直接访问。
- 外部类访问成员内部类:先创建对象,再访问。
外部其它类访问成员内部类:
- 可以依托这样的语法:
OuterClass.InnerClass inner = OuterClass.new InnerClass() - 在外部类中编写一个方法返回一个成员内部类的对象。
public class MemberInnerClass01 {public static void main(String[] args) {Outer01 outer01 = new Outer01();Outer01.InnerClass inner01 = outer01.new InnerClass();inner01.say();Outer01.InnerClass inner02 = outer01.getInnerClass();inner02.say();}
}class Outer01{private int a = 10;public String name = "张三";class InnerClass{int a = 20;public void say(){System.out.println("Outer01的a = " + a + "\tOuter01的name + " + name);}}public InnerClass getInnerClass(){return new InnerClass();}
}
3.6静态内部类
静态内部类定义在外部类的成员位置,并且有static修饰。
public class StaticInnerClass {public static void main(String[] args) {Outer outer = new Outer();//使用固定的语法Outer.Inner inner1 = new Outer.Inner();inner1.say();System.out.println("----------");//编写一个函数,返回静态内部类的对象实例Outer.Inner inner2 = outer.getInner();inner2.say();System.out.println("----------");//静态函数版本Outer.Inner inner3 = Outer.getInner_();inner3.say();}
}class Outer {private int n1 = 10;private static int n2 = 20;public static class Inner{//可以添加访问修饰符public void say(){//System.out.println(n1);//报错,不能访问非静态成员System.out.println(n2);//正确。}}public Inner getInner(){return new Inner();}public static Inner getInner_() {//静态版本return new Inner();}
}
总结:
- 可以直接访问外部类的所有静态成员,包含私有的,但是不能直接访问非静态成员。
- 可以添加任意访问修饰符,因为它的低位就是一个成员。
- 作用域:等同于其他成员,为整个类体。
- 静态内部类访问外部类:直接访问。
- 外部类访问静态内部类:创建对象在访问。
- 外部其它类访问静态内部类:
- 使用语法进行访问:
Outer.Inner inner1 = new Outer.Inner(); - 编写一个函数,返回内部类的一个对象。函数可以有static版本。
- 使用语法进行访问:
- 当与外部类成员重名时,采用外部类名.成员来访问。
相关文章:
JavaSE——类与对象(5)
一、抽象类 1.1为什么需要抽象类 父类的某些方法,不确定怎么实现,也不需要实现。 class Animal{public String name;public Animal(String name){this.name name;}public void eat()//这里实现了也没有意义{System.out.println("这是一个动物&am…...
Istio笔记01--快速体验Istio
Istio笔记01--快速体验Istio 介绍部署与测试部署k8s安装istio测试istio 注意事项说明 介绍 Istio是当前最热门的服务网格产品,已经被广泛应用于各个云厂商和IT互联网公司。企业可以基于Istio轻松构建服务网格,在接入过程中应用代码无需更改,…...
面试小札:Java如何实现并发编程
多线程基础 继承Thread类 定义一个类继承自 Thread 类,重写 run 方法。在 run 方法中编写线程要执行的任务逻辑。例如: java class MyThread extends Thread { Override public void run() { System.out.println("线程执行的任务…...
java-a+b 开启java语法学习
代码 (ab) import java.util.Scanner; //导入 java.util包中的Scanner 类,允许读取键盘输入数据public class Main { // 创建一个公共类 Mainpublic static void main(String[] args) {//程序入口点,main方法Scanner scanner new Scanner(…...
RNN模型文本预处理--数据增强方法
数据增强方法 数据增强是自然语言处理(NLP)中常用的一种技术,通过生成新的训练样本来扩充数据集,从而提高模型的泛化能力和性能。回译数据增强法是一种常见的数据增强方法,特别适用于文本数据。 回译数据增强法 定义…...
maven 中<packaging>pom</packaging>配置使用
在 Maven 项目的 pom.xml 文件中, 元素用于指定项目的打包类型。默认情况下,如果 元素没有被显式定义,Maven 会假设其值为 jar。但是,当您设置 pom 时,这意味着该项目是一个 POM(Project Object Model&…...
【Python中while循环】
一、深拷贝、浅拷贝 1、需求 1)拷贝原列表产生一个新列表 2)想让两个列表完全独立开(针对改操作,读的操作不改变) 要满足上述的条件,只能使用深拷贝 2、如何拷贝列表 1)直接赋值 # 定义一个…...
【深度学习】服务器常见命令
1、虚拟环境的安装位置 先进入虚拟环境 which python2、升序查看文件内容 ls -ltr3、查看服务器主机空间使用情况 df -hdf -h .4、查看本地空间使用情况 du -sh ./*du -sh * | sort -nr5、查找并删除进程 # 查找 ps aux# 删除 kill -KILL pid6、查看服务器配置 lscpuuna…...
技术分析模板
文章目录 概要整体架构流程技术名词解释技术细节小结 概要 提示:这里可以添加技术概要 例如: openAI 的 GPT 大模型的发展历程。 整体架构流程 提示:这里可以添加技术整体架构 例如: 在语言模型中,编码器和解码器…...
python:文件操作
一、文件路径 在Windows系统中,每个磁盘都有自己的根目录,用分区名加反斜杠来表示。我们定位文件的位置有两种方法,一种是绝对路径,另一种是相对路径。绝对路径是从根目录出发的路径,路径中的每个路径之间用反斜杠来分…...
Nginx和Apache有什么异同?
Nginx和Apache都是广泛使用的Web服务器软件,它们各自具有独特的特点和优势,适用于不同的应用场景。以下是关于Nginx和Apache的不同、相同以及使用区别的详细分析: 一、不同点 资源占用与并发处理能力: Nginx使用更少的内存和CPU资…...
泰州榉之乡全托机构探讨:自闭症孩子精细动作训练之法
当发现自闭症孩子精细动作落后时,家长们往往会感到担忧和困惑。那么,自闭症孩子精细动作落后该如何训练呢?今天,泰州榉之乡全托机构就来为大家详细解答。 榉之乡大龄自闭症托养机构在江苏、广东、江西等地都有分校,一直…...
Cookie跨域
跨域:跨域名(IP) 跨域的目的是共享Cookie。 session操作http协议,每次既要request,也要response,cookie在创建的时候会产生一个字符串然后随着response返回。 全网站的各个页面都会带着登陆的时候的cookie …...
qt QGraphicsPolygonItem详解
1、概述 QGraphicsPolygonItem是Qt框架中QGraphicsItem的一个子类,它提供了一个可以添加到QGraphicsScene中的多边形项。通过QGraphicsPolygonItem,你可以定义和显示一个多边形,包括其填充颜色、边框样式等属性。QGraphicsPolygonItem支持各…...
“harmony”整合不同平台的单细胞数据之旅
其实在Seurat v3官方网站的Vignettes中就曾见过该算法,但并没有太多关注,直到看了北大张泽民团队在2019年10月31日发表于Cell的《Landscap and Dynamics of Single Immune Cells in Hepatocellular Carcinoma》,为了同时整合两类数据…...
如何构建一个可扩展、全球可访问的 GenAI 架构?
你有没有尝试过使用人工智能生成图像? 如果你尝试过,你就会知道,一张好的图像的关键在于一个详细具体的提示。 我不擅长这种详细的视觉提示,所以我依赖大型语言模型来生成详细的提示,然后使用这些提示来生成出色的图像…...
QT实战--qt各种按钮实现
本篇介绍qt一些按钮的实现,包括正常按钮;带有下拉箭头的按钮的各种实现;按钮和箭头两部分分别响应;图片和按钮大小一致;图片和按钮大小不一致的处理;文字和图片位置的按钮 效果图如下: 详细实现…...
RNN And CNN通识
CNN And RNN RNN And CNN通识一、卷积神经网络(Convolutional Neural Networks,CNN)1. 诞生背景2. 核心思想和原理(1)基本结构:(2)核心公式:(3)关…...
生产环境中:Flume 与 Prometheus 集成
在生产环境中,将 Apache Flume 与 Prometheus 集成的过程,需要借助 JMX Exporter 或 HTTP Exporter 来将 Flume 的监控数据转换为 Prometheus 格式。以下是详细的实现方法,连同原理和原因进行逐步解释,让刚接触的初学者也能完成集…...
求平均年龄
求平均年龄 C语言代码C 代码Java代码Python代码 💐The Begin💐点点关注,收藏不迷路💐 班上有学生若干名,给出每名学生的年龄(整数),求班上所有学生的平均年龄,保留到小数…...
MongoDB学习和应用(高效的非关系型数据库)
一丶 MongoDB简介 对于社交类软件的功能,我们需要对它的功能特点进行分析: 数据量会随着用户数增大而增大读多写少价值较低非好友看不到其动态信息地理位置的查询… 针对以上特点进行分析各大存储工具: mysql:关系型数据库&am…...
高等数学(下)题型笔记(八)空间解析几何与向量代数
目录 0 前言 1 向量的点乘 1.1 基本公式 1.2 例题 2 向量的叉乘 2.1 基础知识 2.2 例题 3 空间平面方程 3.1 基础知识 3.2 例题 4 空间直线方程 4.1 基础知识 4.2 例题 5 旋转曲面及其方程 5.1 基础知识 5.2 例题 6 空间曲面的法线与切平面 6.1 基础知识 6.2…...
WEB3全栈开发——面试专业技能点P2智能合约开发(Solidity)
一、Solidity合约开发 下面是 Solidity 合约开发 的概念、代码示例及讲解,适合用作学习或写简历项目背景说明。 🧠 一、概念简介:Solidity 合约开发 Solidity 是一种专门为 以太坊(Ethereum)平台编写智能合约的高级编…...
ardupilot 开发环境eclipse 中import 缺少C++
目录 文章目录 目录摘要1.修复过程摘要 本节主要解决ardupilot 开发环境eclipse 中import 缺少C++,无法导入ardupilot代码,会引起查看不方便的问题。如下图所示 1.修复过程 0.安装ubuntu 软件中自带的eclipse 1.打开eclipse—Help—install new software 2.在 Work with中…...
浅谈不同二分算法的查找情况
二分算法原理比较简单,但是实际的算法模板却有很多,这一切都源于二分查找问题中的复杂情况和二分算法的边界处理,以下是博主对一些二分算法查找的情况分析。 需要说明的是,以下二分算法都是基于有序序列为升序有序的情况…...
Maven 概述、安装、配置、仓库、私服详解
目录 1、Maven 概述 1.1 Maven 的定义 1.2 Maven 解决的问题 1.3 Maven 的核心特性与优势 2、Maven 安装 2.1 下载 Maven 2.2 安装配置 Maven 2.3 测试安装 2.4 修改 Maven 本地仓库的默认路径 3、Maven 配置 3.1 配置本地仓库 3.2 配置 JDK 3.3 IDEA 配置本地 Ma…...
《C++ 模板》
目录 函数模板 类模板 非类型模板参数 模板特化 函数模板特化 类模板的特化 模板,就像一个模具,里面可以将不同类型的材料做成一个形状,其分为函数模板和类模板。 函数模板 函数模板可以简化函数重载的代码。格式:templa…...
深度学习水论文:mamba+图像增强
🧀当前视觉领域对高效长序列建模需求激增,对Mamba图像增强这方向的研究自然也逐渐火热。原因在于其高效长程建模,以及动态计算优势,在图像质量提升和细节恢复方面有难以替代的作用。 🧀因此短时间内,就有不…...
ubuntu22.04有线网络无法连接,图标也没了
今天突然无法有线网络无法连接任何设备,并且图标都没了 错误案例 往上一顿搜索,试了很多博客都不行,比如 Ubuntu22.04右上角网络图标消失 最后解决的办法 下载网卡驱动,重新安装 操作步骤 查看自己网卡的型号 lspci | gre…...
前端高频面试题2:浏览器/计算机网络
本专栏相关链接 前端高频面试题1:HTML/CSS 前端高频面试题2:浏览器/计算机网络 前端高频面试题3:JavaScript 1.什么是强缓存、协商缓存? 强缓存: 当浏览器请求资源时,首先检查本地缓存是否命中。如果命…...
