详解final, abstract, interface关键字
一.final关键字
1.final关键字介绍
——final关键字可以去修饰类、方法、属性和局部变量
2.final关键字的作用
1)final修饰类,这个类不能被其他类继承
2)final修饰方法,方法不能被重写
3)final修饰属性,属性的值不能被修改
4)final修饰局部变量,局部变量的值不能被修改
public class Test {public static void main(String[] args) {}
}//1.final修饰类,类不能被继承
final class Person {
}//class Stu extends Person {}
//错误,Person类不能被继承class Animal {//2.final修饰方法,方法不能被重写public final void say() {}
}class Dog extends Animal {//错误,不能重写final的方法//public void say() {}
}//3.final修饰属性,属性的值不能被修改
class Cat {private final int age = 10;public void setAge() {//错误,final修饰的属性不能被修改//age = 19;}
}//4.final修饰局部变量,局部变量的值不能被修改
class Tiger {public void sleep() {final int age = 18;//final修饰的局部变量不能被修改//age = 19;}
}
3.final的细节讨论及实现
1)final修饰的属性叫做常量,常量使用全大写字母表示,若是多单词,单词间使用_隔开
public class Test {public static void main(String[] args) {Person person = new Person();System.out.println(person.MAX_AGE);//130}
}class Person {public final int MAX_AGE = 130;
}
2)final修饰的属性必须要初始化,可以在三个地方初始化:
a.声明定义并初始化
b.构造器中初始化
c.代码块中初始化
public class Test {public static void main(String[] args) {Person person = new Person();//使用System.out.println(person.MAX_AGE);//130System.out.println(person.MIN_AGE);//0System.out.println(person.MAX_NUM);//100}
}class Person {//声明定义并初始化public final int MAX_AGE = 130;//构造器中初始化public final int MIN_AGE;public Person() {MIN_AGE = 0;}//代码块中初始化public final int MAX_NUM;{MAX_NUM = 100;}
}
3)若final修饰的属性是静态的,可以在两个地方初始化:
a.声明定义并初始化
b.静态代码块中初始化
public class Test {public static void main(String[] args) {//使用System.out.println(Person.MAX_AGE);//130System.out.println(Person.MIN_AGE);//0}
}class Person {//声明定义并初始化public final static int MAX_AGE = 130;//静态代码块中初始化public final static int MIN_AGE;static {MIN_AGE = 0;}
}
4)final类不能被继承,但是可以实例化
public class Test {public static void main(String[] args) {//final类不能被继承,但是可以实例化Person person = new Person();}
}final class Person {
}
5)若类不是final类,但含有final方法,那么final方法可以被继承,但不能被重写
public class Test {public static void main(String[] args) {Colleague colleague = new Colleague();colleague.say();//final方法可以被继承}
}class Person {public final void say() {System.out.println("I say: you must success!");}
}class Colleague extends Person {//不能重写父类中final修饰的方法//public void say() {}
}
6)若一个类已经是final类了,那么其方法没有必要设置为final方法了:因为final类不可能被继承,有final方法也不可能被重写
public class Test {public static void main(String[] args) {}
}final class Person {//类已经是final修饰的了,那么方法不需要再使用final修饰//public final void say() {// System.out.println("I will say: you must success!");//}public void say() {System.out.println("I will say: you must success!");}
}
7)final不能修饰构造器,能不能说说为什么?
——final修饰的方法约束在子类中不能进行重写,而构造器本身就不能在子类中重写,所以无需final修饰
public class Test {public static void main(String[] args) {}
}class Person {//final不能修饰构造器//final public Person() {}
}
8)final和static搭配使用效率更高,不会导致类的加载就可以使用
public class Test {public static void main(String[] args) {System.out.println(Person.MAX_AGE);}
}class Person {//final和static搭配使用效率更高,不会导致类的加载就可以使用public static final int MAX_AGE = 150;//静态代码块随着类的加载而加载static {System.out.println("静态代码块被加载~");}
}
9)包装类(Integer、Double等)和String类均是使用final修饰的
二.抽象类
1.什么是抽象类?什么是抽象方法?
——使用abstract关键字修饰的类/方法叫做抽象类/方法
2.抽象类/方法格式
抽象类:权限修饰符 abstract class 类名 {}
抽象方法:权限修饰符 abstract 返回类型 方法名(形参列表...);
public class Test {public static void main(String[] args) {}
}//当父类的某些方法需要声明,但是又不确定要怎么使用的时候,可以将方法声明为抽象类,那么这个类也是抽象类
//注意,只要方法是抽象方法,那么类也必须是抽象类
abstract class A {public abstract void say();
}//使用abstract关键字修饰一个类时,这个类就叫做抽象类
abstract class B {//使用abstract修饰一个方法的时候,这个方法就是抽象方法,抽象方法无方法体public abstract void hi();
}
3.抽象类的应用场景
——当我们不知道父类的方法怎么使用的时候,可以把父类方法设置为抽象方法,让子类去实现这个抽象方法,含有抽象方法的类叫做抽象类
4.抽象类的细节讨论及实现
1)抽象类不能被实例化
public class Test {public static void main(String[] args) {}
}//3.抽象类不能被实例化
abstract class C {
}
2)抽象类不一定要包含abstract方法,换种说法,抽象类可以没有抽象方法
3)一个类中只要有abstract方法,那么这个类也要使用abstract修饰
public class Test {public static void main(String[] args) {}
}//抽象类不一定要包含abstract方法,也就是说,抽象类可以没有抽象方法
//一旦一个类中含有了抽象方法,那么这个类必须声明为抽象类
abstract class D {//抽象方法public abstract void method();//非抽象方法public void depart() {System.out.println("启程~");}
}
4)abstract只能修饰类和方法,不能修修饰其他属性
public class Test {public static void main(String[] args) {}
}abstract class E {//抽象方法public abstract void radiant();//6.abstract只能修饰类和方法,不能修饰其他属性//public abstract int aae;
}
5)抽象类本质还是类,抽象类可以有任意成员【向上转型解决】
public class Test {public static void main(String[] args) {}
}//抽象类的本质还是类,可以有任意成员: 非抽象方法、构造器、静态属性
abstract class F {//抽象方法public abstract void live();//成员变量public static int age = 10;public int data = 11;//构造器public F() {}//非抽象方法public void board() {System.out.println("board的意思是董事会~");}
}
6)抽象方法不能有方法体
7)如果一个类继承了抽象类,则它必须实现抽象类中的所有抽象方法或它也声明为抽象类
public class Test {public static void main(String[] args) {}
}//如果一个类继承了抽象类,那么它必须实现抽象类的所有抽象方法,或者它也声明为抽象类
//抽象类
abstract class Person {//抽象方法不能有方法体public abstract void hi();public abstract void go();
}//1)实现全部的抽象方法
class Teacher extends Person {public void hi() {System.out.println("hi,bro~");}public void go() {System.out.println("bro,go,go,go~");}
}//2) 将自己也声明为抽象类
abstract class Stu extends Person {
}
8)抽象方法不能使用private、final和static关键字修饰,因为这些关键字都与重写相违背
//1)为什么不能使用private? ——使用private修饰抽象方法后,这个抽象方法只能在本类使用,其他类不能实现它
//2)为什么不能使用final? ——使用final修饰抽象方法后,该方法不能被重写
//3)为什么不能使用static? ——抽象类不能被实例化,而且静态方法在类加载的时候就加载了,已经分配好了内存空间,
// 抽象类的抽象方法是需要被继承的子类进行重写的
5.抽象类最佳实践 —— 模板设计模式
1)什么是模板设计模式?
——定义一个操作中算法的骨架,而将一些步骤延迟到子类中,模板方法使得子类可以不改变算法的结构,只是重定义该算法的某些特定步骤
2)模板设计模式的优点
——编写一个抽象父类,父类提供了多个子类的通用方法,并把一个或多个方法留给其他子类实现(实现了代码的复用)
3)一个小case快速了解模板设计模式
public class Test {public static void main(String[] args) {Calculate calculate = new Calculate();calculate.getDistance();//调用}
}abstract class Pattern {//抽象方法public abstract void cal();public void getDistance() {long start = System.currentTimeMillis();cal();//存在动态绑定机制long end = System.currentTimeMillis();System.out.println("计算的时间是:" + (end - start));}
}class Calculate extends Pattern {//重写了父类的抽象方法public void cal() {long sum = 0;for (int i = 0; i < 10000000; i++) {sum += i;}}
}
三.接口
1.什么是接口?
——接口就是给出一些没有实现的方法,把这些方法封装到一起,当某个类要使用的时候,根据具体情况把这些方法写出来
2.接口的格式
interface 接口名 {
属性
抽象方法
}
interface Computer {int age = 10;void say();
}
3.类如何和接口完成对接?
class 类名 implements 接口 {
类的属性;
类的方法;
必须实现接口的抽象方法;
}
interface Computer {int age = 10;void say();
}//类实现接口
class Usb implements Computer {public void say() {System.out.println("hello~");}
}
4.接口的细节讨论及实现
1)接口不能实例化
public class Test {public static void main(String[] args) {//Person person = new Person();//接口不能实例化}
}//接口不能实例化
interface Person {void say();
}
2)接口中方法都是抽象方法(除掉默认方法、静态方法),且这些抽象方法均是public的,接口中的抽象方法,不需要再写abstract
public class Test {public static void main(String[] args) {}
}interface Computer {//public void connect();//abstract void connect();//抽象方法void connect();void listen();void keyBoard();//默认方法: 可以在接口中实现具体的方法体default void say() {}//静态方法: 可以在接口中实现具体的方法体static void sing() {}
}
3)普通类实现接口,必须把接口中的所有方法均实现
public class Test {public static void main(String[] args) {}
}interface Computer {//抽象方法void connect();void keyBoard();
}//普通类实现接口中的方法
class Laptop implements Computer {public void connect() {System.out.println("连接网络~");}public void keyBoard() {System.out.println("打字~");}
}
4)抽象类实现接口,可以不用实现接口中的方法
public class Test {public static void main(String[] args) {}
}interface Computer {//抽象方法void connect();void keyBoard();
}//抽象类可以不用实现接口中的方法
abstract class Honor implements Computer {
}
5)一个类可以同时实现多个接口,接口之间使用逗号隔开
public class Test {public static void main(String[] args) {}
}interface Computer {//抽象方法void watch();void keyBoard();
}interface Usb {void connect();
}//一个类可以同时继承多个接口
class Laptop implements Computer,Usb {@Overridepublic void watch() {}@Overridepublic void keyBoard() {}@Overridepublic void connect() {}
}
6)接口中的属性是public static final 修饰的,所以我们需要初始化
7)接口中的属性访问形式:接口名.属性名
public class Test {public static void main(String[] args) {//接口中的属性访问形式:接口名.属性名System.out.println(Computer.AGE);//18}
}interface Computer {//接口中的属性是public static final 修饰的//public static final int age = 10;int AGE = 18;
}
8)接口不能继承其他的类,但是可以继承一个或多个接口,接口间逗号隔开
public class Test {public static void main(String[] args) {}
}interface Computer {void watch();
}interface Laptop {void listen();
}//接口不能继承其他的类,但是可以继承接口
interface Phone extends Computer,Laptop {
}
9)接口的修饰符只能是pubic和默认,这点跟对类的修饰符是相同的
public class Test {public static void main(String[] args) {}
}//默认接口
interface Computer {void watch();
}//单开文件
//public接口
public interface Laptop {
}
5.继承和接口的区别
1)继承解决了代码的复用性和可维护性
2)接口设计好了各种规范,让其他类去实现这些规范(灵活性)
3)继承是拥有了父类的各种功能,而接口可以理解为对子类扩展功能,也可以理解为接口是对Java单继承机制的一种补充
6.接口的多态特性
public class Test {public static void main(String[] args) {//接口数组Computer[] computers = new Computer[2];//给数组里填充内容computers[0] = new Laptop();//向上转型computers[1] = new Phone();//向上转型print(computers);}private static void print(Computer[] computers) {for (int i = 0; i < computers.length; i++) {computers[i].listen();computers[i].watch();if (computers[i] instanceof Laptop) {((Laptop) computers[i]).play();//向下转型} else if (computers[i] instanceof Phone) {((Phone) computers[i]).game();} else {System.out.print("");}}}
}//接口
interface Computer {void watch();void listen();
}class Laptop implements Computer {@Overridepublic void watch() {System.out.println("用电脑看视频~");}@Overridepublic void listen() {System.out.println("用电脑听歌~");}//特有方法public void play() {System.out.println("开黑~");}
}class Phone implements Computer {@Overridepublic void watch() {System.out.println("使用手机刷抖音~");}@Overridepublic void listen() {System.out.println("打开QQ音乐听歌~");}//特有方法public void game() {System.out.println("王者荣耀走起~");}
}
7.多态传递现象
public class Test {public static void main(String[] args) {//多态传递:Computer --> Usb --> Phone(实现)//编译类型:Computer 运行类型:PhoneComputer phone = new Phone();phone.watch();phone.listen();//phone.connect();//为什么不能使用?//因为编译类型只会找属于本类的,而connect是Usb的方法,不是Computer的方法Usb phone1 = new Phone();phone1.listen();phone1.listen();phone1.connect();//为什么可以? 因为Usb继承了Computer接口}
}interface Computer {void watch();void listen();
}interface Usb extends Computer {void connect();
}//要全部实现接口中的方法
class Phone implements Usb {@Overridepublic void watch() {System.out.println("看电影~");}@Overridepublic void listen() {System.out.println("听歌~");}@Overridepublic void connect() {System.out.println("连接Usb~");}
}
相关文章:

详解final, abstract, interface关键字
一.final关键字 1.final关键字介绍 ——final关键字可以去修饰类、方法、属性和局部变量 2.final关键字的作用 1)final修饰类,这个类不能被其他类继承 2)final修饰方法,方法不能被重写 3)final修饰属性,属…...
统计特殊四元组
题记: 给你一个 下标从 0 开始 的整数数组 nums ,返回满足下述条件的 不同 四元组 (a, b, c, d) 的 数目 : nums[a] nums[b] nums[c] nums[d] ,且a < b < c < d 示例 1: 输入: nums [1,2,3…...

腾讯云轻量应用服务器“镜像”怎么选择合适?
腾讯云轻量应用服务器镜像怎么选择?如果是用来搭建网站可以选择宝塔Linux面板腾讯云专享版,镜像系统根据实际使用来选择,腾讯云百科txybk.com来详细说下腾讯云轻量应用服务器镜像的选择方法: 腾讯云轻量应用服务器镜像选择 轻量…...
Ruby模块和程序组织
和类一样,模块是一组方法和常量的集合。 和类不同,模块没有实例,取而代之的是可以将特殊模块的功能添加到一个类或者指定对象之中。 Class类是Module类的一个子类,因此每一个类对象也是一个模块对象 一、模块创建和基础应用 编写…...
14、SpringCloud -- WebSocket 实时通知用户
目录 实时通知用户需求:代码:前端:后端:WebSocket创建 websocket-server 服务添加依赖:配置 yml 和 启动类:前端:后端代码:注意:测试:总结:实时通知用户 需求: 用户订单秒杀成功之后,对用户进行秒杀成功通知。 弹出个提示框来提示。 代码: 前端:...

智能井盖传感器推荐,万宾科技助力城市信息化建设
随着科技产品更新换代进程加快,人工智能在人们日常生活之中逐渐普及开来,深入人们生活的方方面面,影响城市基础设施建设工程。例如在大街小巷之中的井盖作为城市基础建设的一个重要部分,一旦出现松动倾斜或凸起等异常问题…...

3D模型格式转换工具HOOPS Exchange对工业级3D产品HOOPS的支持与应用
一、概述 HOOPS Exchange是一套高性能模型转换软件库,可以给软件提供强大的模型的导入和导出功能,我们可以将其单独作为转换工具使用,也可以将其集成到自己的软件中。 同样,HOOPS 的其它产品,也离不开HOOPS Exchange…...

table 表体滚动, 表头、表尾固定
在开发报表中,如果报表数据行过多页面无法全部显示,或者内容溢出div,需要把表头和表尾固定表体滚动这样就可以在页面上全部显示,并且不会溢出div 效果:最终实现效果 代码:<!DOCTYPE html> <html&g…...

第57篇-某钩招聘网站加密参数分析【2023-10-31】
声明:该专栏涉及的所有案例均为学习使用,严禁用于商业用途和非法用途,否则由此产生的一切后果均与作者无关!如有侵权,请私信联系本人删帖! 文章目录 一、前言二、网站分析1.X-S-HEADER参数2.请求参数data3.响应机密值data一、前言 网址: aHR0cHM6Ly93d3cubGFnb3UuY29t…...

C语言数据结构之数据结构入门
目录 数据结构介绍 数据结构发展史 何为算法 数据结构基础 基本概念和术语 四大逻辑结构(Logic Structure) 数据类型 理解复杂度概念 时间空间复杂度定义 度量时间复杂度的方法 程序运行时的内存与地址 编程预备 数据结构介绍 数据结构发展…...

如何知道服务器的某个端口是否打开
1、telnet 命令:telnet ip port,port即端口,我们一般最常见的命令就是telnet,但是telnet使用的是tcp协议,换句话说telnet只能检测tcp的这个端口打开了没 若是端口打开,会出现下列信息 失败的是这个 如…...

【ICCV‘23】One-shot Implicit Animatable Avatars with Model-based Priors
文章目录 前置知识 前置知识 1)SMPL模型 \quad SMPL这类方法只建模穿很少衣服的人体(裸体模型),它只能刻画裸体角色的动画,并不能刻画穿衣服的人体的动画 2)data-efficient \quad 这个词推荐用ÿ…...

关于息肉检测和识别项目的总结
前言 整体的思路:首先息肉数据集分为三类: 1.正常细胞 2. 增生性息肉 3. 肿瘤要想完成这个任务,首先重中之重是分割任务,分割结果的好坏, 当分割结果达到一定的准确度后,开始对分割后的结果进行下游分类…...

Jetson Xavier NX FFmpeg支持硬件编解码
最近在用Jetson Xavier NX板子做视频处理,但是CPU进行视频编解码,效率比较地下。 于是便考虑用硬解码来对视频进行处理。 通过jtop查看,发现板子是支持 NVENC硬件编解码的。 1、下载源码 因为需要对ffmpeg进行打补丁修改,因此需要编译两份源码 1.1、编译jetson-ffmpeg …...

518抽奖软件,为什么说比别的抽奖软件更美观精美?
518抽奖软件简介 518抽奖软件,518我要发,超好用的年会抽奖软件,简约设计风格。 包含文字号码抽奖、照片抽奖两种模式,支持姓名抽奖、号码抽奖、数字抽奖、照片抽奖。(www.518cj.net) 精致美观功能 字体平滑无锯齿图片放大后清晰…...
React的组件学习
React的组件学习 参考资料:https://zh-hans.react.dev/learn/your-first-component 一、定义组件 export default function Profile() {return (<imgsrc"https://i.imgur.com/MK3eW3Am.jpg"alt"Katherine Johnson"/>) }以下是构建组件…...

uni-app配置微信开发者工具
一、配置微信开发者工具路径 工具->设置->运行配置->小程序运行配置->微信开发者工具路径 二、微信开发者工具开启服务端口...

肺癌不再是老年病:33岁作家的离世引发关注,有这些情况的请注意
近期,90后网络小说家七月新番和26岁男艺人蒋某某因肺癌去世,引发关注。他们都没有吸烟习惯,那么他们为什么会得肺癌呢?浙大二院呼吸内科副主任医师兰芬说,现在年轻人熬夜、加班导致身体过劳,在劳累情况下身…...

【兔子王赠书第4期】用ChatGPT轻松玩转机器学习与深度学习
文章目录 前言机器学习深度学习ChatGPT推荐图书粉丝福利尾声 前言 兔子王免费赠书第4期来啦,突破传统学习束缚,借助ChatGPT的神奇力量,解锁AI无限可能! 机器学习 机器学习是人工智能领域的一个重要分支,它的目的是让…...
Ubuntu18.04 ROS Melodic的cv_bridge指向问题(四种方式,包括opencv4)(转载)
转载自: 【精选】Ubuntu18.04 ROS Melodic的cv_bridge指向问题(四种方式,包括opencv4)_XiangrongZ的博客-CSDN博客...

使用docker在3台服务器上搭建基于redis 6.x的一主两从三台均是哨兵模式
一、环境及版本说明 如果服务器已经安装了docker,则忽略此步骤,如果没有安装,则可以按照一下方式安装: 1. 在线安装(有互联网环境): 请看我这篇文章 传送阵>> 点我查看 2. 离线安装(内网环境):请看我这篇文章 传送阵>> 点我查看 说明:假设每台服务器已…...
css的定位(position)详解:相对定位 绝对定位 固定定位
在 CSS 中,元素的定位通过 position 属性控制,共有 5 种定位模式:static(静态定位)、relative(相对定位)、absolute(绝对定位)、fixed(固定定位)和…...
JDK 17 新特性
#JDK 17 新特性 /**************** 文本块 *****************/ python/scala中早就支持,不稀奇 String json “”" { “name”: “Java”, “version”: 17 } “”"; /**************** Switch 语句 -> 表达式 *****************/ 挺好的ÿ…...

【从零学习JVM|第三篇】类的生命周期(高频面试题)
前言: 在Java编程中,类的生命周期是指类从被加载到内存中开始,到被卸载出内存为止的整个过程。了解类的生命周期对于理解Java程序的运行机制以及性能优化非常重要。本文会深入探寻类的生命周期,让读者对此有深刻印象。 目录 …...

Golang——9、反射和文件操作
反射和文件操作 1、反射1.1、reflect.TypeOf()获取任意值的类型对象1.2、reflect.ValueOf()1.3、结构体反射 2、文件操作2.1、os.Open()打开文件2.2、方式一:使用Read()读取文件2.3、方式二:bufio读取文件2.4、方式三:os.ReadFile读取2.5、写…...

Elastic 获得 AWS 教育 ISV 合作伙伴资质,进一步增强教育解决方案产品组合
作者:来自 Elastic Udayasimha Theepireddy (Uday), Brian Bergholm, Marianna Jonsdottir 通过搜索 AI 和云创新推动教育领域的数字化转型。 我们非常高兴地宣布,Elastic 已获得 AWS 教育 ISV 合作伙伴资质。这一重要认证表明,Elastic 作为 …...

Copilot for Xcode (iOS的 AI辅助编程)
Copilot for Xcode 简介Copilot下载与安装 体验环境要求下载最新的安装包安装登录系统权限设置 AI辅助编程生成注释代码补全简单需求代码生成辅助编程行间代码生成注释联想 代码生成 总结 简介 尝试使用了Copilot,它能根据上下文补全代码,快速生成常用…...
Docker、Wsl 打包迁移环境
电脑需要开启wsl2 可以使用wsl -v 查看当前的版本 wsl -v WSL 版本: 2.2.4.0 内核版本: 5.15.153.1-2 WSLg 版本: 1.0.61 MSRDC 版本: 1.2.5326 Direct3D 版本: 1.611.1-81528511 DXCore 版本: 10.0.2609…...

Excel 怎么让透视表以正常Excel表格形式显示
目录 1、创建数据透视表 2、设计 》报表布局 》以表格形式显示 3、设计 》分类汇总 》不显示分类汇总 1、创建数据透视表 2、设计 》报表布局 》以表格形式显示 3、设计 》分类汇总 》不显示分类汇总...

【笔记】结合 Conda任意创建和配置不同 Python 版本的双轨隔离的 Poetry 虚拟环境
如何结合 Conda 任意创建和配置不同 Python 版本的双轨隔离的Poetry 虚拟环境? 在 Python 开发中,为不同项目配置独立且适配的虚拟环境至关重要。结合 Conda 和 Poetry 工具,能高效创建不同 Python 版本的 Poetry 虚拟环境,接下来…...