接口的顶级理解

目录

1.基本介绍

1.1定义接口

1.2接口使用

 2.接口特性

3.实现多个接口

4.接口间的继承

5.接口使用实例

5.1对象比大小

5.1.1方法1:Comparable 接口法

 5.1.2构造比较器(Comparator接口法)

5.2对象数组排序

5.2.1 实现 Comparable 接口,

 5.2.2构造比较器(实现Comparator接口)

6.Clonable 接口和深拷贝

6.1Clonable 接口

6.2 浅拷贝

6.3深拷贝  


1.基本介绍

接口就是公共的行为规范标准,大家在实现时,只要符合规范标准,就可以通用 Java 中,接口可以看成是:多个类的公共规范,是一种引用数据类型。

上述可能过于抽象,我们可以通过语法来理解。

接口就是给出一些没有实现的方法,封装到一起,到某个类要使用的时候,在根据具体情况把这些方法写出来。

1.1定义接口

public interface 接口名称 {
// 抽象方法
void method ();
}
注意:
1. 创建接口时, 接口的命名一般以大写字母 I 开头 .
2. 接口的命名一般使用 " 形容词" 词性的单词.

1.2接口使用

接口不能直接使用,必须要有一个"实现类"来"实现"该接口,实现接口中的所有抽象方法。
public class 类名称 implements 接口名称 {
// ...
}

 2.接口特性

1. 接口类型是一种引用类型,但是不能直接new接口的对象

2. 接口中每一个方法都是public的抽象方法, 即接口中的方法会被隐式的指定为 public abstract

只能是 public abstract,其他修饰符都会报错

3. 接口中的方法是不能在接口中实现的,只能由实现接口的类来实现,但两个方法除外,static修饰的方法和default修饰的方法.
IText 接口
public interface IText {void A();public static void AAwork(){System.out.println("AAwork()");}public default void BBwork(){System.out.println("BBwork()");}
}
Dometext implements IText
class Dometext implements IText{@Overridepublic void A() {System.out.println("Dometext的A()");}
}
Test1
public class Test1 {public static void main(String[] args) {IText.AAwork();Dometext dometext = new Dometext();dometext.BBwork();dometext.A();}
}

运行结果:

 小结:static修饰不可重写,default修饰可重写也可以不重写。

4.接口中可以含有变量,但是接口中的变量会被隐式的指定为 public static final 变量

故为常量,不可修改。

5.接口中不能有静态代码块,实例代码块和构造方法

 6.接口虽然不是类,但是接口编译完成后字节码文件的后缀格式也是.class

7.如果类没有实现接口中的所有的抽象方法,则类必须设置为抽象类


3.实现多个接口

Java 中,类和类之间是单继承的,一个类只能有一个父类, Java中不支持多继承,但是一个类可以实现多个接
下面通过类来表示一组动物 .
Animal
abstract class Animal {public String name;public int age;public Animal(String name, int age) {this.name = name;this.age = age;}public abstract void eat();
}
另外我们再提供一组接口 , 分别表示 " 会飞的 ", " 会跑的 ", " 会游泳的 ".
interface IFlying 
interface IFlying {void fly();
}
interface IRunning
interface IRunning {void run();
}
interface ISwimming
interface ISwimming {void swim();
}
接下来我们创建几个具体的动物
, 是会跑的 .
class Cat extends Animal implements IRunning {public Cat(String name, int age) {super(name, age);}@Overridepublic void eat() {System.out.println(name+"吃猫粮");}@Overridepublic void run() {System.out.println(this.name + "正在用四条腿跑");}}
青蛙 , 既能跑 , 又能游 ( 两栖动物 )
class Frog extends Animal implements IRunning, ISwimming {public Frog(String name, int age) {super(name, age);}@Overridepublic void run() {System.out.println(this.name + "正在往前跳");}@Overridepublic void swim() {System.out.println(this.name + "正在蹬腿游泳");}@Overridepublic void eat() {System.out.println(name+"吃青蛙粮");}
}
水陆空三栖" 鸭子 "
class Duck extends Animal implements IRunning, ISwimming, IFlying {public Duck(String name, int age) {super(name, age);}@Overridepublic void fly() {System.out.println(this.name + "正在用翅膀飞");}@Overridepublic void run() {System.out.println(this.name + "正在用两条腿跑");}@Overridepublic void swim() {System.out.println(this.name + "正在漂在水上");}@Overridepublic void eat() {System.out.println(name+"吃鸭粮");}
}

Text1

public class Text1 {public static void func(Animal animal){animal.eat();}public static void main(String[] args) {func(new Cat("mimi",1));func(new Frog("vava",1));func(new Duck("yaya",1));}
}

运行结果:

Text2

public class Text2 {public static void func(Animal animal){animal.eat();}public static void fFly(IFlying flying){flying.fly();}public static void fRun(IRunning running){running.run();}public static void fSwim(ISwimming swimming){swimming.swim();}public static void main(String[] args) {fSwim(new Frog("vava",1));fRun(new Frog("vava",1));}}

运行结果: 

 图解:

                                                                图解3-1

这样设计有什么好处呢 ? 时刻牢记多态的好处 , 让程序猿 忘记类型 . 有了接口之后 , 类的使用者就不必关注具体类型 , 而只关注某个类是否具备某种能力.

再如Text3

甚至参数可以不是 " 动物 ", 只要会跑 !
public class Text2 {public static void main(String[] args) {fRun(new Robot("1hao"));}public static void fRun(IRunning running){running.run();}
}

运行结果:


4.接口间的继承

子类和父类之间是extends 继承关系,类与接口之间是 implements 实现关系。

  

接口与接口之间可以多继承,即:用接口可以达到 多继承的目的。
接口可以继承一个接口, 达到复用的效果. 使用 extends 关键字.

 图解:

 

                                                               图解4-1

举例: 

interface IRunning {
void run ();
}
interface ISwimming {
void swim ();
}
// 两栖的动物 , 既能跑 , 也能游
interface IAmphibious extends IRunning , ISwimming {
}
class Frog implements IAmphibious {
...
}

5.接口使用实例

5.1对象比大小

不难发现 , 和普通的整数不一样 , 两个整数是可以直接比较的 , 大小关系明确 . 而两个学生对象的大小关系 怎么确定? 需要我们额外指定 .
学生类
class Student {String name;int age;public Student(String name, int age) {this.name = name;this.age = age;}@Overridepublic String toString() {return "Student{" +"name='" + name + '\'' +", age=" + age +'}';}
}
Student wang = new Student("wang", 20);
Student li = new Student("li", 19);

如:我们现在想要比较两个学生的年龄。

5.1.1方法1:Comparable 接口法

让我们的 Student 类实现 Comparable 接口, 并实现其中的 compareTo 方法

代码(5-1-1)  

class Student implements Comparable<Student>{String name;int age;public Student(String name, int age) {this.name = name;this.age = age;}@Overridepublic int compareTo(Student o) {if(this.age>o.age){return 1;} else if (this.age < o.age) {return -1;}else {return 0;}}@Overridepublic String toString() {return "Student{" +"name='" + name + '\'' +", age=" + age +'}';}
}
如果当前对象应排在参数对象之前 , 返回-1 的数字 ;
如果当前对象应排在参数对象之后 , 返回1   的数字 ;
如果当前对象和参数对象不分先后 , 返回 0;

运行结果:1

 5.1.2构造比较器(Comparator接口法)

实现Comparator接口, 并实现其中的 compare 方法

代码(5-1-2) 

class AgecompareTo implements Comparator<Student> {@Overridepublic int compare(Student o1, Student o2) {return o1.age-o2.age;}
}

返回年龄差

 运行结果:11

5.2对象数组排序

sort 方法中会自动调用 compareTo 方法 . compareTo 的参数是 Object , 其实传入的就是 Student 类型的对象 . 然后比较当前对象和参数对象的大小关系( 按分数来算 ).
注意事项 : 对于 sort 方法来说 , 需要传入的数组的每个对象都是 " 可比较 " , 需要具备 compareTo 这样的能力 . 通 过重写 compareTo 方法的方式 , 就可以定义比较规则 .

 

如:我们现在想要排序学生的年龄。 

5.2.1 实现 Comparable 接口,

实现 Comparable 接口, 并重写其中的 compareTo 方法

让我们的 Student 实现 Comparable 接口, 并实现其中的 compareTo 方法为代码(5-1-1) 

Text代码:

public class Text {public static void main(String[] args) {Student wang = new Student("wang", 200);Student li = new Student("li", 19);Student hu = new Student("hu", 11);Student[] students ={wang,li,hu};Arrays.sort(students);System.out.println(Arrays.toString(students));}
}

  运行结果:

 5.2.2构造比较器(实现Comparator接口)

实现Comparator接口, 并实现其中的 compare 方法

构造比较器实现Comparator接口, 并实现其中的 compare 方法的代码为代码(5-1-2) 

 Text代码:

public class Text {public static void main(String[] args) {Student wang = new Student("wang", 200);Student li = new Student("li", 19);Student hu = new Student("hu", 11);Student[] students ={wang,li,hu};AgecompareTo agecompareTo = new AgecompareTo();Arrays.sort(students,agecompareTo);System.out.println(Arrays.toString(students));}
}

运行结果:

为了进一步加深对接口的理解, 我们可以尝试自己实现一个 sort 方法来完成刚才的排序过程(使用冒泡排序)
  public static void bsort(Comparable[] comparables){for (int i = 0; i < comparables.length - 1; i++) {for (int j = 0; j < comparables.length - 1 - i; j++) {if(comparables[j].compareTo(comparables[j+1])>0){Comparable tmp=comparables[j];comparables[j]=comparables[j+1];comparables[j+1]=tmp;}}}}

6.Clonable 接口和深拷贝

6.1Clonable 接口

Java 中内置了一些很有用的接口 , Clonable 就是其中之一 .
Object 类中存在一个 clone 方法 , 调用这个方法可以创建一个对象的 " 拷贝 ". 但是要想合法调用 clone 方法 , 必须要 先实现 Clonable 接口 , 否则就会抛出 CloneNotSupportedException 异常 .
class Student
class Student implements Cloneable{String name;int age;public Student(String name, int age) {this.name = name;this.age = age;}@Overridepublic String toString() {return "Student{" +"name='" + name + '\'' +", age=" + age +'}';}@Overrideprotected Object clone() throws CloneNotSupportedException {return super.clone();}
}
Text1
public class Text1 {public static void main(String[] args) throws CloneNotSupportedException {Student wang = new Student("wang", 21);Student student= (Student) wang.clone();System.out.println(student);}}

 空接口、标记接口

作用:表示当前类可以被克隆。

6.2 浅拷贝

Cloneable 拷贝出的对象是一份 "浅拷贝"
回答  运行结果:
Money
class Money {public double m = 99.99;
}
改造class Student
class Student implements Cloneable{String name;int age;Money money=new Money();public Student(String name, int age) {this.name = name;this.age = age;}@Overridepublic String toString() {return "Student{" +"name='" + name + '\'' +", age=" + age +", money=" + money.m +'}';}@Overrideprotected Object clone() throws CloneNotSupportedException {return super.clone();}
}

改造Text1

public class Text1 {public static void main(String[] args) throws CloneNotSupportedException {Student wang = new Student("wang", 21);Student student= (Student) wang.clone();System.out.println(wang);System.out.println(student);System.out.println("=======================");wang.money.m=100;System.out.println(wang);System.out.println(student);}}

  运行结果:

如上代码,我们可以看到,通过 clone,我们只是拷贝了Student 对象。但是Student 对象中的Money 对象,并 没有拷贝。通过wang 这个引用修改了 m 的值后,stydent 这个引用访问 m 的时候,值也发生了改变。这里 就是发生了浅拷贝。

 这是为啥?

6.3深拷贝  

 改造2class Student

class Student implements Cloneable{String name;int age;Money money=new Money();public Student(String name, int age) {this.name = name;this.age = age;}@Overridepublic String toString() {return "Student{" +"name='" + name + '\'' +", age=" + age +", money=" + money.m +'}';}@Overrideprotected Object clone() throws CloneNotSupportedException {Student tmp=(Student)super.clone();tmp.money=(Money) tmp.money.clone();return tmp;}
}

    改造 Money     

class Money implements Cloneable{public double m = 99.99;@Overrideprotected Object clone() throws CloneNotSupportedException {return super.clone();}
}

改造2Text1     

public class Text1 {public static void main(String[] args) throws CloneNotSupportedException {Student wang = new Student("wang", 21);Student student= (Student) wang.clone();System.out.println(wang);System.out.println(student);System.out.println("=======================");wang.money.m=100;System.out.println(wang);System.out.println(student);}}

  运行结果:

       


以上为我个人的小分享,如有问题,欢迎讨论!!! 

都看到这了,不如关注一下,给个免费的赞 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/78672.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【力扣刷题 | 第二十四天】

目录 前言&#xff1a; 1049. 最后一块石头的重量 II - 力扣&#xff08;LeetCode&#xff09; 494. 目标和 - 力扣&#xff08;LeetCode&#xff09; 总结&#xff1a; 前言&#xff1a; 今天我们依然暴打动态规划 1049. 最后一块石头的重量 II - 力扣&#xff08;LeetCod…

每天一道leetcode:剑指 Offer 53 - II. 0~n-1中缺失的数字(适合初学者二分查找)

今日份题目&#xff1a; 一个长度为n-1的递增排序数组中的所有数字都是唯一的&#xff0c;并且每个数字都在范围0&#xff5e;n-1之内。在范围0&#xff5e;n-1内的n个数字中有且只有一个数字不在该数组中&#xff0c;请找出这个数字。 示例1 输入: [0,1,3] 输出: 2 示例2 …

uniapp 返回上一页并刷新

如要刷新的是mine页面 在/pages/mine/improveInfo页面修改信息&#xff0c;点击保存后跳转到个人中心&#xff08;/pages/mine/index&#xff09;页面并刷新更新数据 点击保存按钮时执行以下代码&#xff1a; wx.switchTab({url: /pages/mine/index }) // 页面重载 let pages …

在线文本转语音播放 (TTS)

具体请前往&#xff1a;在线文本转语音播放(TTS)

彩虹云商城搭建完整教程 完整的学习资料

彩虹云商城搭建完整教程 完整的学习资料提供给大家学习 随着电子商务的快速发展&#xff0c;越来越多的企业开始意识到开设一个自己的电子商城对于销售和品牌推广的重要性。然而&#xff0c;选择一家合适的网站搭建平台和正确地构建一个商城网站并不是一件容易的事情。本文将为…

Python操作MySQL将数据库表中的数据导出到excel

Author: liukai 2810248865qq.com Date: 2022-08-18 04:28:52 LastEditors: liukai 2810248865qq.com LastEditTime: 2023-06-29 09:35:25 FilePath: \PythonProject01\Python操作MySQL数据库及excel将数据库表中的数据导出到excel中.py Description: 这是默认设置,请设置custo…

华夏ERP信息泄露

声明 本文仅用于技术交流&#xff0c;请勿用于非法用途 由于传播、利用此文所提供的信息而造成的任何直接或者间接的后果及损失&#xff0c;均由使用者本人负责&#xff0c;文章作者不为此承担任何责任。 文章作者拥有对此文章的修改和解释权。如欲转载或传播此文章&#xff0c…

14-4_Qt 5.9 C++开发指南_QUdpSocket实现 UDP 通信_UDP组播

文章目录 1. UDP组播的特性2. UDP 组播实例程序的功能3. 组播功能的程序实现4. 源码4.1 可视化UI设计4.2 mainwindow.h4.3 mainwindow.cpp 1. UDP组播的特性 下图简单表示了组播的原理。UDP 组播是主机之间“一对一组”的通信模式&#xff0c;当多个客户端加入由一个组播地址定…

智慧工地云平台源码,基于微服务+Java+Spring Cloud +UniApp +MySql开发

智慧工地可视化系统利用物联网、人工智能、云计算、大数据、移动互联网等新一代信息技术&#xff0c;通过工地中台、三维建模服务、视频AI分析服务等技术支撑&#xff0c;实现智慧工地高精度动态仿真&#xff0c;趋势分析、预测、模拟&#xff0c;建设智能化、标准化的智慧工地…

uni-app:实现列表单选功能

效果图&#xff1a; 核心解析&#xff1a; 一、 <view class"item_all" v-for"(item, index) in info" :key"index"><view classposition parameter-info text-over :classitem.checked?"checked_parameter":""…

ubuntu 暂时不能解析域名 解决办法

需要修改系统DNS 打开终端&#xff1a;输入 sudo vi /etc/resolv.conf 回车 在打开的配置文件中添加DNS信息 nameserver 114.114.114.114 nameserver 8.8.8.8 保存退出&#xff0c;重启系统即可。

【Nacos篇】Nacos基本操作及配置

官方文档&#xff1a;https://nacos.io/zh-cn/docs/v2/ecology/use-nacos-with-spring-cloud.html 前置条件&#xff1a;SpringCloud脚手架 单机模式下的Nacos控制台&#xff1a; <dependencies><!-- Registry 注册中心相关 --><dependency><groupId>…

《golang设计模式》第一部分·创建型模式-04-抽象工厂模式(Abstract Factory)

文章目录 1. 概述1.1 角色1.2 类图 2. 代码示例2.1 设计2.2 代码2.3 类图 1. 概述 1.1 角色 AbstractFactory&#xff08;抽象工厂&#xff09;&#xff1a;它声明了一组用于创建产品的方法&#xff0c;每一个方法对应一种产品。ConcreteFactory&#xff08;具体工厂&#xf…

系统架构设计高级技能 · 软件可靠性分析与设计(三)【系统架构设计师】

系列文章目录 系统架构设计高级技能 软件架构概念、架构风格、ABSD、架构复用、DSSA&#xff08;一&#xff09;【系统架构设计师】 系统架构设计高级技能 系统质量属性与架构评估&#xff08;二&#xff09;【系统架构设计师】 系统架构设计高级技能 软件可靠性分析与设计…

HCIP 三层交换机

一、实现VLAN间通信 在传统的交换机组网中&#xff0c;默认所有网络都处于同一个广播域&#xff0c;带来了许多问题&#xff0c;VLAN技术的提出&#xff0c;满足了二层组网隔离广播域需求&#xff0c;使得属于不同的VLAN间网络无法通信&#xff0c;但不同VLAN之间又存在着互相…

MybatisPlus存在 sql 注入漏洞(CVE-2023-25330)解决办法

首先我们了解下这个漏洞是什么&#xff1f; MyBatis-Plus TenantPlugin 是 MyBatis-Plus 的一个为多租户场景而设计的插件&#xff0c;可以在 SQL 中自动添加租户 ID 来实现数据隔离功能。 MyBatis-Plus TenantPlugin 3.5.3.1及之前版本由于 TenantHandler#getTenantId 方法在…

快速排序【Java算法】

文章目录 1. 概念2. 思路3. 代码实现 1. 概念 快速排序是一种比较高效的排序算法&#xff0c;采用 “分而治之” 的思想&#xff0c;通过多次比较和交换来实现排序&#xff0c;在一趟排序中把将要排序的数据分成两个独立的部分&#xff0c;对这两部分进行排序使得其中一部分所有…

Python web实战之Django用户认证详解

关键词&#xff1a; Python Web 开发、Django、用户认证、实战案例 概要 今天来探讨一下 Django 的用户认证吧&#xff01;在这篇文章中&#xff0c;我将为大家带来一些有关 Django 用户认证的最佳实践。 1. Django 用户认证 在开发 Web 应用程序时&#xff0c;用户认证是一个…

05 Ubuntu下安装.deb安装包方式安装vscode,snap安装Jetbrains产品等常用软件

使用deb包安装类型 deb包指的其实就是debian系统&#xff0c;ubuntu系统是基于debian系统的发行版。 一般我们会到需要的软件官网下载deb安装包&#xff0c;然后你既可以采用使用“软件安装”打开的方法来进行安装&#xff0c;也可以使用命令行进行安装。我推荐后者&#xff…

Mr. Cappuccino的第58杯咖啡——MacOS配置Maven和Java环境

MacOS配置Maven和Java环境 查看Mac使用的是哪个shell下载并准备Maven下载Maven配置前准备 下载并安装JDK下载JDK安装JDK 配置Maven和Java环境添加配置加载配置 验证环境 查看Mac使用的是哪个shell echo $SHELL如果使用的是bash&#xff0c;则使用以下命令 open ~/.bash_profi…