详解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博客...
在软件开发中正确使用MySQL日期时间类型的深度解析
在日常软件开发场景中,时间信息的存储是底层且核心的需求。从金融交易的精确记账时间、用户操作的行为日志,到供应链系统的物流节点时间戳,时间数据的准确性直接决定业务逻辑的可靠性。MySQL作为主流关系型数据库,其日期时间类型的…...

Zustand 状态管理库:极简而强大的解决方案
Zustand 是一个轻量级、快速和可扩展的状态管理库,特别适合 React 应用。它以简洁的 API 和高效的性能解决了 Redux 等状态管理方案中的繁琐问题。 核心优势对比 基本使用指南 1. 创建 Store // store.js import create from zustandconst useStore create((set)…...

SCAU期末笔记 - 数据分析与数据挖掘题库解析
这门怎么题库答案不全啊日 来简单学一下子来 一、选择题(可多选) 将原始数据进行集成、变换、维度规约、数值规约是在以下哪个步骤的任务?(C) A. 频繁模式挖掘 B.分类和预测 C.数据预处理 D.数据流挖掘 A. 频繁模式挖掘:专注于发现数据中…...
【决胜公务员考试】求职OMG——见面课测验1
2025最新版!!!6.8截至答题,大家注意呀! 博主码字不易点个关注吧,祝期末顺利~~ 1.单选题(2分) 下列说法错误的是:( B ) A.选调生属于公务员系统 B.公务员属于事业编 C.选调生有基层锻炼的要求 D…...
Caliper 配置文件解析:config.yaml
Caliper 是一个区块链性能基准测试工具,用于评估不同区块链平台的性能。下面我将详细解释你提供的 fisco-bcos.json 文件结构,并说明它与 config.yaml 文件的关系。 fisco-bcos.json 文件解析 这个文件是针对 FISCO-BCOS 区块链网络的 Caliper 配置文件,主要包含以下几个部…...

Android 之 kotlin 语言学习笔记三(Kotlin-Java 互操作)
参考官方文档:https://developer.android.google.cn/kotlin/interop?hlzh-cn 一、Java(供 Kotlin 使用) 1、不得使用硬关键字 不要使用 Kotlin 的任何硬关键字作为方法的名称 或字段。允许使用 Kotlin 的软关键字、修饰符关键字和特殊标识…...
Device Mapper 机制
Device Mapper 机制详解 Device Mapper(简称 DM)是 Linux 内核中的一套通用块设备映射框架,为 LVM、加密磁盘、RAID 等提供底层支持。本文将详细介绍 Device Mapper 的原理、实现、内核配置、常用工具、操作测试流程,并配以详细的…...

AI,如何重构理解、匹配与决策?
AI 时代,我们如何理解消费? 作者|王彬 封面|Unplash 人们通过信息理解世界。 曾几何时,PC 与移动互联网重塑了人们的购物路径:信息变得唾手可得,商品决策变得高度依赖内容。 但 AI 时代的来…...

HDFS分布式存储 zookeeper
hadoop介绍 狭义上hadoop是指apache的一款开源软件 用java语言实现开源框架,允许使用简单的变成模型跨计算机对大型集群进行分布式处理(1.海量的数据存储 2.海量数据的计算)Hadoop核心组件 hdfs(分布式文件存储系统)&a…...
如何配置一个sql server使得其它用户可以通过excel odbc获取数据
要让其他用户通过 Excel 使用 ODBC 连接到 SQL Server 获取数据,你需要完成以下配置步骤: ✅ 一、在 SQL Server 端配置(服务器设置) 1. 启用 TCP/IP 协议 打开 “SQL Server 配置管理器”。导航到:SQL Server 网络配…...