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💐点点关注,收藏不迷路💐 班上有学生若干名,给出每名学生的年龄(整数),求班上所有学生的平均年龄,保留到小数…...

wordpress后台更新后 前端没变化的解决方法
使用siteground主机的wordpress网站,会出现更新了网站内容和修改了php模板文件、js文件、css文件、图片文件后,网站没有变化的情况。 不熟悉siteground主机的新手,遇到这个问题,就很抓狂,明明是哪都没操作错误&#x…...

docker详细操作--未完待续
docker介绍 docker官网: Docker:加速容器应用程序开发 harbor官网:Harbor - Harbor 中文 使用docker加速器: Docker镜像极速下载服务 - 毫秒镜像 是什么 Docker 是一种开源的容器化平台,用于将应用程序及其依赖项(如库、运行时环…...
Admin.Net中的消息通信SignalR解释
定义集线器接口 IOnlineUserHub public interface IOnlineUserHub {/// 在线用户列表Task OnlineUserList(OnlineUserList context);/// 强制下线Task ForceOffline(object context);/// 发布站内消息Task PublicNotice(SysNotice context);/// 接收消息Task ReceiveMessage(…...

为什么需要建设工程项目管理?工程项目管理有哪些亮点功能?
在建筑行业,项目管理的重要性不言而喻。随着工程规模的扩大、技术复杂度的提升,传统的管理模式已经难以满足现代工程的需求。过去,许多企业依赖手工记录、口头沟通和分散的信息管理,导致效率低下、成本失控、风险频发。例如&#…...
Objective-C常用命名规范总结
【OC】常用命名规范总结 文章目录 【OC】常用命名规范总结1.类名(Class Name)2.协议名(Protocol Name)3.方法名(Method Name)4.属性名(Property Name)5.局部变量/实例变量(Local / Instance Variables&…...
vue3 字体颜色设置的多种方式
在Vue 3中设置字体颜色可以通过多种方式实现,这取决于你是想在组件内部直接设置,还是在CSS/SCSS/LESS等样式文件中定义。以下是几种常见的方法: 1. 内联样式 你可以直接在模板中使用style绑定来设置字体颜色。 <template><div :s…...
全面解析各类VPN技术:GRE、IPsec、L2TP、SSL与MPLS VPN对比
目录 引言 VPN技术概述 GRE VPN 3.1 GRE封装结构 3.2 GRE的应用场景 GRE over IPsec 4.1 GRE over IPsec封装结构 4.2 为什么使用GRE over IPsec? IPsec VPN 5.1 IPsec传输模式(Transport Mode) 5.2 IPsec隧道模式(Tunne…...

项目部署到Linux上时遇到的错误(Redis,MySQL,无法正确连接,地址占用问题)
Redis无法正确连接 在运行jar包时出现了这样的错误 查询得知问题核心在于Redis连接失败,具体原因是客户端发送了密码认证请求,但Redis服务器未设置密码 1.为Redis设置密码(匹配客户端配置) 步骤: 1).修…...
C++.OpenGL (20/64)混合(Blending)
混合(Blending) 透明效果核心原理 #mermaid-svg-SWG0UzVfJms7Sm3e {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-SWG0UzVfJms7Sm3e .error-icon{fill:#552222;}#mermaid-svg-SWG0UzVfJms7Sm3e .error-text{fill…...
深入浅出Diffusion模型:从原理到实践的全方位教程
I. 引言:生成式AI的黎明 – Diffusion模型是什么? 近年来,生成式人工智能(Generative AI)领域取得了爆炸性的进展,模型能够根据简单的文本提示创作出逼真的图像、连贯的文本,乃至更多令人惊叹的…...