抽象类和接口

article/2025/10/14 0:23:43

目录

抽象类

抽象类使用abstract修饰类

抽象类当中可以包含普通类所能包含的成员

抽象类和普通类不一样的是,抽象类当中可以包含抽象方法。

抽象类方法是使用abstract修饰的,这个方法没有具体的实现

不能实例化抽象类

抽象类存在的意义是为了被继承

抽象类的方法不能是私有的(private),要满足重写的规则。

抽象类当中可以有构造方法,为了方便子类能够调用,来初始化抽象类当中的成员

接口

1.使用interface来修饰接口

2.接口当中的成员方法不能有具体的实现。

 在接口中抽象方法默认是public abstract的方法

接口不可以被实例化,也就是说接口不能有静态代码块和构造方法

可以通过implements实现接口,接口里面的抽象方法必须重写,默认方法可重写也可以不重写,静态方法不能被重写。

接口的使用

实现多个接口

 抽象类和接口的区别:

Object类

toString

equals


抽象类

抽象类使用abstract修饰类

抽象类当中可以包含普通类所能包含的成员

抽象类和普通类不一样的是,抽象类当中可以包含抽象方法。

抽象类方法是使用abstract修饰的,这个方法没有具体的实现

abstract class Shape{public int a;public abstract void draw();public void func(){}
}

不能实例化抽象类

public class Test {public static void main(String[] args) {Shape shape = new Shape();//报错}
}

抽象类存在的意义是为了被继承

如果一个普通类继承了抽象类,此时必须重写抽象类中的方法。

class Rect extends Shape{@Overridepublic void draw() {System.out.println("矩形");}
}

一个抽象类A继承一个抽象类B,此时不需要重写B中的抽象方法,但当A被继承时,还是要重写B中的抽象方法。

抽象类的方法不能是私有的(private),要满足重写的规则。

抽象类当中可以有构造方法,为了方便子类能够调用,来初始化抽象类当中的成员

接口

Java中,接口可以看成是:多个类的公共规范,是一种引用数据类型。

1.使用interface来修饰接口

2.接口当中的成员方法不能有具体的实现。

interface IShape {public abstract void func1();public void func2(){//报错}
}

 在接口中抽象方法默认是public abstract的方法

从JDK1.8开始,允许有方法的实现,但是这个方法必须是有default修饰的

可以实现有静态方法

成员变量默认是public static final修饰的,子类如果重写抽象方法必须由public修饰

interface IShape {public static final int a = 10;int b = 20;//默认也是public static final修饰的public abstract void func1();void func();//默认也是public abstract修饰的public void func2(){//报错}default public void func3(){System.out.println("默认方法");}public static void func4(){System.out.println("static修饰的方法");}
}

接口不可以被实例化,也就是说接口不能有静态代码块和构造方法

 public static void main(String[] args) {IShape ishape = new IShape();//报错}

可以通过implements实现接口,接口里面的抽象方法必须重写,默认方法可重写也可以不重写,静态方法不能被重写。

class A implements IShape{public void func1(){System.out.println("重写抽象方法");}
}

接口的使用

请实现笔记本电脑使用 USB 鼠标、 USB 键盘的例子
1. USB 接口:包含打开设备、关闭设备功能
//USB接口
public interface USB {void openDevice();void closeDevice();
}
2. 鼠标类:实现 USB 接口,并具备点击功能
public class Mouse implements USB{@Overridepublic void openDevice() {System.out.println("打开鼠标");}@Overridepublic void closeDevice(){System.out.println("关闭鼠标");}public void click(){System.out.println("鼠标点击");}
}

3. 键盘类:实现USB接口,并具备输入功能

public class KeyBoard implements USB {@Overridepublic void openDevice() {System.out.println("打开键盘");}@Overridepublic void closeDevice() {System.out.println("关闭键盘");}public void inPut(){System.out.println("键盘输入");}
}

4. 笔记本类:包含开机功能、关机功能、使用 USB 设备功能
public class Computer{public void powerOn(){System.out.println("打开笔记本电脑");}public void powerOff(){System.out.println("关闭笔记本电脑");}public void useDevice(USB usb){usb.openDevice();if(usb instanceof Mouse){Mouse mouse = (Mouse) usb;mouse.click();}if(usb instanceof KeyBoard){KeyBoard keyboard = (KeyBoard) usb;keyboard.inPut();}usb.closeDevice();}
}

测试:

//测试
public class TestUsb {public static void main(String[] args){Computer computer = new Computer();computer.powerOn();computer.useDevice(new Mouse());computer.useDevice(new KeyBoard());computer.powerOff();}
}

实现多个接口

一个类可以实现多个接口,使用implements 用逗号隔开。(可以解决多继承的问题)
interface  A{void func1();
}
interface B{void func2();
}
class C implements A,B{@Overridepublic void func1() {System.out.println(1);}@Overridepublic void func2() {System.out.println(2);}
}

接口实现多继承和多态简单实例

class Animal{public String name;public int age;public Animal(String name,int age){this.name = name;this.age = age;}public void eat(){System.out.println("吃饭");}
}
interface IRuning{void runing();
}
interface ISwimming{void swimming();
}
interface IFly{void fly();
}
class Dog extends Animal implements IRuning,ISwimming{public Dog(String name,int age){super(name,age);}@Overridepublic void runing() {System.out.println(name+"正在跑");}@Overridepublic void swimming() {System.out.println(name+"正在游泳");}
}
class Duck extends Animal implements IRuning,ISwimming,IFly{public Duck(String name,int age){super(name,age);}@Overridepublic void runing() {System.out.println(name+"正在跑");}@Overridepublic void swimming() {System.out.println(name+"正在游泳");}@Overridepublic void fly() {System.out.println(name+"正在飞");}
}
public class Test {public static void walk(IRuning iruning){iruning.runing();//多态}public static void main(String[] args) {walk(new Dog("小黑",2));walk(new Duck("可达鸭",3));}
}

 继承表达的含义是 is - a 语义, 而接口表达的含义是 具有 xxx 特性

有了接口之后 , 类的使用者就不必关注具体类型 , 而只关注某个类是否具备某种能力
class Robot implements IRuning{@Overridepublic void runing() {System.out.println("机器人正在跑步");}
}
public class Test {public static void walk(IRuning iruning){iruning.runing();}public static void main(String[] args) {walk(new Dog("小黑",2));walk(new Duck("可达鸭",3));walk(new Robot());}
}

机器人不是动物,但仍然可以实现多态,因为接口只关注某个类是否具有某种能力。机器人有跑步的能力,那他就可以实现。

 抽象类和接口的区别:

抽象类可以包含普通字段和成员,接口中不能包含普通方法,子类必须重写所有的抽象方法

抽象方法由普通类(普通字段和方法)和抽象方法组成

接口由抽象方法和全局常量组成

使用extends继承抽象类,使用implements关键字实现接口

一个抽象类可以实现若干个接口,接口不能继承抽象类,接口可以使用extends继承多个父类接口

一个子类只能继承一个抽象类,一个子类可以实现多个接口

Object类

Object类是所以类的父类,我们自己写的类就算没有写extends Object,默认也是继承的

class Teacher{}
class Student{}
public class Test2 {public static void func(Object object){}public static void main(String[] args) {func(new Student());//向上转型,不报错func(new Teacher());}
}

Object类当中的一些方法:

toString

输出对象的名称,和@符号后面跟一串16进制数字,该数字是由hashCode这个方法产生的 

equals

Java 中, == 进行比较时:
如果==左右两侧是基本类型变量,比较的是变量中值是否相同
如果==左右两侧是引用类型变量,比较的是引用变量地址是否相同
如果要比较对象中内容,必须重写Object中的equals方法,因为equals方法默认也是按照地址比较的
Object类中的equals方法

 可见Object类中的equals是使用引用中的地址来进行比较的

class Person{String name;int age;public Person(String name,int age){this.name = name;this.age = age;}
}
public class Test3 {public static void main(String[] args) {Person per1 = new Person("zhangsan",20);Person per2 = new Person("zhangsan",20);int a = 10;int b = 10;System.out.println(a==b);System.out.println(per1==per2);System.out.println(per1.equals(per2));}
}

Person类重写equals方法:

class Person{String name;int age;public Person(String name,int age){this.name = name;this.age = age;}@Overridepublic boolean equals(Object obj) {if(obj==null){return false;}if(this == obj){return true;}if(!(obj instanceof Person)){return false;}Person per = (Person) obj;if(this.name.equals(per.name) && this.age == per.age){return true;}else{return false;}}
}
public class Test3 {public static void main(String[] args) {Person per1 = new Person("zhangsan",20);Person per2 = new Person("zhangsan",20);int a = 10;int b = 10;System.out.println(a==b);System.out.println(per1==per2);System.out.println(per1.equals(per2));}
}


http://chatgpt.dhexx.cn/article/4KDJaXvr.shtml

相关文章

Java抽象类和接口 -- 深度剖析

💖欢迎来阅读子豪的博客(Java语法篇🧔) 👉有什么宝贵的意见或建议可以在留言区留言 💻欢迎 素质三连 点赞 关注 收藏 🧑‍🚀码云仓库:补集王子的代码仓库 Java抽象类和接…

Java学习系列之抽象类和接口的区别和联系

导读 本文首先分别介绍抽象类和接口的基础概念、特征和应用场景,然后介绍其区别和联系。 1 抽象类 1.1 定义抽象类 在Java中被abstract关键字修饰的类称为抽象类,被abstract关键字修饰的方法称为抽象方法,抽象方法只有方法的声明&#xff…

从抽象类到接口—手把手教你写抽象类(一)—还在Ctrl C的伙伴们看过来了

目录 一、抽象类概述 二、抽象类的特点 三、抽象类的案例 四、抽象类的细节 五、抽象类的思想 抽象类概述 抽象定义 –抽象是从多个事物中将共性的,本质的内容抽取出来。 –例:狼和狗共性都是犬科,犬科就是抽象出来的概念。 抽象类 –…

Java基础学习:抽象类和接口

目录,更新ing,学习Java的点滴记录 目录放在这里太长了,附目录链接大家可以自由选择查看--------Java学习目录 抽象类和接口_抽象类和抽象方法 抽象类是普通的类与接口之间的一种中庸之道,尽管你可能在构建某些未实现方法的类是,第一想法可能是创建接口,但是抽象类仍旧是用于此…

SVD奇异值分解(理论与C++实现)

SVD奇异值分解 前言理论推导部分代码实现 前言 奇异值分解(singular value decomposition,以下简称SVD)是线性代数中一种重要的矩阵分解。SVD将矩阵分解为奇异向量(singular vector)和奇异值(singular value)。SVD将矩阵 A A A分解成三个矩阵的乘积 A U D V T A …

matlab实现奇异值分解

一、原理 二、实现 %% 两种方法计算矩阵 A 的 SVD A [0,1; 1,1; 1,0];%% 方法一:利用特征分解eig % 计算右奇异矩阵V [V,D1] eig(A*A); n size(D1,1); index n:-1:1; D1 diag(D1); D1 D1(index); D1 diag(D1, 0); V V(:,index); % 计算左奇异矩阵U [U,D2…

特征值分解和奇异值分解

特征值分解 特征值分解是将一个方阵A分解为如下形式: A Q Σ Q − 1 AQ\Sigma Q^{-1} AQΣQ−1 其中,Q是方阵A的特征向量组成的矩阵, Σ \Sigma Σ是一个对角矩阵,对角线元素是特征值。 通过特征值分解得到的前N个特征向量&am…

奇异值分解的揭秘(一):矩阵的奇异值分解过程

转载来源: 作者:Xinyu Chen 链接:https://zhuanlan.zhihu.com/p/26306568 来源:知乎 矩阵的奇异值分解(singular value decomposition,简称SVD)是线性代数中很重要的内容,并且奇…

奇异值分解(Singular Values Decomposition,SVD)

奇异值分解 1.奇异值分解1.1 变换(Transformations)1.2 线性变换(Linear Transformations)1.3 降维(Dimensionality Reduction)1.4 奇异值分解(SVD)1.4.1 如果矩阵 A A A是方阵&…

奇异值分解(SVD)的原理详解及推导

1. 写在前面 最近整理推荐系统模型的时候, 第二个模型打算整理一下隐语义模型, 这里面绕不开一种思想就是矩阵分解, 而作为矩阵分解的经典方法SVD感觉这次有必要学学了, SVD不仅是一个数学问题,在工程应用中的很多地方…

机器学习(29)之奇异值分解SVD原理与应用详解

微信公众号 关键字全网搜索最新排名 【机器学习算法】:排名第一 【机器学习】:排名第一 【Python】:排名第三 【算法】:排名第四 前言 奇异值分解(Singular Value Decomposition,简称SVD)是在机器学习领域广泛应用的算法,它不光可以用于降维算法中的特征分解,还可以用于…

【机器学习】这次终于彻底理解了奇异值分解(SVD)原理及应用

奇异值分解(Singular Value Decomposition,以下简称SVD)是在机器学习领域广泛应用的算法,有相当多的应用与奇异值都可以扯上关系,它不光可以用于降维算法中的特征分解,比如做feature reduction的PCA,做数据压缩&#x…

联邦学习——用data-free知识蒸馏处理Non-IID

《Data-Free Knowledge Distillation for Heterogeneous Federated Learning》ICML 2021 最近出现了利用知识蒸馏来解决FL中的用户异构性问题的想法,具体是通过使用来自异构用户的聚合知识来优化全局模型,而不是直接聚合用户的模型参数。然而&#xff0c…

【FLIS】Clustered Federated Learning via Inference Similarity for Non-IID Data Distribution

Clustered Federated Learning via Inference Similarity for Non-IID Data Distribution 基于推理相似性的非iid数据分布聚类联邦学习 Abstract1.INTRODUCTION2.FEDERATED LEARNING WITH CLUSTERINGA. Overview of FLIS AlgorithmB. Clustering Clients 3.EXPERIMENTSA. Exper…

Federated Learning with Non-IID Data 论文笔记

本文提出联邦学习中的由于Non-IID数据分布而精度降低是因为权重分散(weight divergence),而权重散度可以用搬土距离(EMD)量化,最后提出了一种策略:通过创建一个在所有边缘设备之间全局共享的数据…

论文分享:「FED BN」使用LOCAL BATCH NORMALIZATION方法解决Non-iid问题

‍ ‍ 本次分享内容基于ICLR 2021收录的一篇文章:《FED BN: FEDERATED LEARNING ON NON-IID FEATURES VIA LOCAL BATCH NORMALIZATION》,这篇论文主要探讨了使用LOCAL BATCH NORMALIZATION方法解决Non-iid问题。围绕这篇论文的分享将分为4个部分&#…

On the convergence of FedAvg on non-iid data

在这篇blog中我们一起来阅读一下 On the convergence of FedAvg on non-iid data 这篇 ICLR 2020 的paper. 主要目的 本文的主要目的是证明联邦学习算法的收敛性。与之前其他工作中的证明不同,本文的证明更贴近于实际联邦学习的场景。特别的, 所有用户…

Federated Learning with Non-IID Data

Federated Learning with Non-IID Data 论文中分析了FedAvg算法在Non-IID数据时,准确率下降的原因。并提出共享5%的数据可提高准确率。 论文笔记参考:https://blog.csdn.net/GJ_007/article/details/104768415 Federated Learning with Non-IID Data …

什么是TLB文件,怎样从dll文件中提取TYPEID信息?- IID

文章目录 1.TLB是什么?2.怎样从dll中导出TLB文件?3.怎样创建TLB文件?4.如何导入TLB5.作者答疑Com是windows平台提供的二进制互操作解决方案。如果给你一个dll,或者windows自带的dll,是否有可能提取其Com接口信息,答案是可以的。 1.TLB是什么? TLB文件是一个说明文件,通…

怎么实现联邦学习中的Non-IID?

联邦学习的一大特点就是数据分布是Non-IID,Non-IID意为非独立同分布。那么怎么在实验中实现non-iid呢?这是我这篇博客想讨论的问题。 part 1: 在堪称联邦学习“开山之作”FedAvg这篇论文中,是这样描述的: 数据集是MN…