14. 接口(适配器设计模式)

接口

  • 接口
    • 1. 定义格式
    • 2. 成员特点
      • 2.1 成员方法
      • 2.2 默认方法
      • 2.3 静态方法
      • 2.4 变量
    • 3. 接口的实现
      • 3.1 实现规则
      • 3.2 实现格式
        • 3.2.1 单实现格式
        • 3.2.2 多实现格式
      • 3.3 接口的继承
        • 3.3.1 接口与类的继承
        • 3.3.2 接口与接口的继承
    • 4.类与接口的区别
    • 5. 注意事项
  • 适配器设计模式

接口

接口(Interface)是Java中的一种引用类型,它定义了一组方法的规范,但没有具体的实现。

接口可以看作是一个规则,规定了实现该接口的类需要提供哪些方法,并且定义了方法的输入和输出。

1. 定义格式

接口(Interface)的定义格式如下:

public interface 接口名 {// 声明常量// 声明抽象方法// 声明默认方法// 声明静态方法
}

接口的名字通常使用大写字母开头,按照命名规范使用驼峰命名法。

例如:一个定义 Animal 接口

public interface Animal {// 声明常量int LEGS = 4;// 声明抽象方法void eat();void sleep();// 声明默认方法default void move() {System.out.println("Animal is moving.");}// 声明静态方法static void breathe() {System.out.println("Animal is breathing.");}
}

上述示例中,定义了一个 Animal 接口,该接口包含了常量 LEGS、抽象方法 eat()sleep(),以及默认方法 move() 和静态方法 breathe()

接口中的常量默认为 `public`、`static`、`final`,可以直接通过接口名访问。

2. 成员特点

2.1 成员方法

成员方法的格式:

[访问修饰符] 返回类型 方法名([参数列表]);
  • 成员方法在接口中默认为抽象方法,不需要使用 abstract 关键字进行修饰。

  • 方法默认为 public 访问权限,可以省略 public 关键字。

  • 实现类必须提供方法的具体实现。

    示例:

    public interface Animal {void eat();void sleep();
    }
    

2.2 默认方法

默认方法的格式:

default 返回类型 方法名([参数列表]) {// 默认方法的具体实现
}
  • 默认方法使用 default 关键字进行修饰。

  • 默认方法可以有具体的实现代码。

  • 实现类可以选择是否覆写默认方法。

    示例:

    public interface Animal {void eat();void sleep();default void move() {System.out.println("Animal is moving.");}
    }
    

2.3 静态方法

静态方法的格式:

static 返回类型 方法名([参数列表]) {// 静态方法的具体实现
}
  • 静态方法使用 static 关键字进行修饰。

  • 静态方法可以直接通过接口名调用,无需通过实现类的实例来调用。

    示例:

    public interface Animal {void eat();void sleep();static void breathe() {System.out.println("Animal is breathing.");}
    }
    

2.4 变量

变量的格式:

[访问修饰符] [static] [final] 数据类型 常量名 =;
  • 变量默认为 publicstaticfinal 的。

  • 变量必须在声明时进行初始化,并且在后续不能被修改。

  • 变量可以添加 privateprotected 修饰,但需要显式声明为 staticfinal

    示例:

    public interface Animal {int LEGS = 4;String NAME = "Animal";
    }
    

3. 接口的实现

接口的实现是指一个类实现了一个或多个接口,并提供了接口中声明的所有方法的具体实现。

在Java中,使用关键字 `implements` 来实现接口。

接口提供了一种约定,定义了一组方法的规则,而类实现接口时则需要遵守这个规则,并提供相应的方法实现。通过实现接口,类可以获得这些方法的定义,并在需要的时候提供自己的实现。

3.1 实现规则

要实现一个接口,类需要遵循以下规则:

  1. 使用 implements 关键字后跟着要实现的接口名称。
  2. 实现接口的类必须提供接口中定义的所有方法的具体实现。
  3. 可以实现多个接口,多个接口之间使用逗号 , 分隔。

例如:

// 定义一个接口
interface Animal {void eat();void sleep();
}// 实现Animal接口的类
class Cat implements Animal {@Overridepublic void eat() {System.out.println("Cat is eating.");}@Overridepublic void sleep() {System.out.println("Cat is sleeping.");}
}// 实现Animal接口的类
class Dog implements Animal {@Overridepublic void eat() {System.out.println("Dog is eating.");}@Overridepublic void sleep() {System.out.println("Dog is sleeping.");}
}// 主程序
public class Main {public static void main(String[] args) {// 创建实现了Animal接口的实例Cat cat = new Cat();Dog dog = new Dog();// 调用实现的方法cat.eat();cat.sleep();dog.eat();dog.sleep();}
}

在上面的示例中,Cat 类和 Dog 类分别实现了 Animal 接口,并提供了 eat()sleep() 方法的具体实现。然后在主程序中,我们创建了 CatDog 的实例,然后可以通过这些实例调用接口中的方法。

3.2 实现格式

在 Java 中,一个类可以实现一个或多个接口。

接口的单实现指一个类只实现一个接口,而接口的多实现指一个类实现多个接口。
3.2.1 单实现格式

单实现格式:

class ClassName implements InterfaceName {// 实现接口中声明的方法// ...
}

在单实现的情况下,类 ClassName 实现了接口 InterfaceName,并提供了接口中声明的方法的具体实现。

举例:

interface Animal {void eat();
}class Cat implements Animal {@Overridepublic void eat() {System.out.println("Cat is eating.");}
}

在这个例子中,Cat 类实现了 Animal 接口,提供了 eat() 方法的具体实现。

3.2.2 多实现格式

多实现格式:

class ClassName implements Interface1, Interface2, Interface3 {// 实现接口中声明的方法// ...
}

在多实现的情况下,类 ClassName 实现了多个接口 Interface1Interface2Interface3,并提供了这些接口中声明的方法的具体实现。

举例:

interface Swimmer {void swim();
}interface Flyer {void fly();
}class Duck implements Swimmer, Flyer {@Overridepublic void swim() {System.out.println("Duck is swimming.");}@Overridepublic void fly() {System.out.println("Duck is flying.");}
}

在这个例子中,Duck 类实现了 SwimmerFlyer 接口,提供了 swim()fly() 方法的具体实现。

3.3 接口的继承

3.3.1 接口与类的继承

接口与类的继承格式:

class SubClass extends SuperClass {// ...
}

其中,SubClass 是子类的名称,SuperClass 是父类的名称。

例如:

class Animal {public void eat() {System.out.println("Animal is eating.");}
}class Cat extends Animal {public void meow() {System.out.println("Cat is meowing.");}
}public class Main {public static void main(String[] args) {Cat cat = new Cat();cat.eat();cat.meow();}
}

在上面的例子中,定义了一个 Animal 类,其中有 eat() 方法。接着,定义了一个 Cat 类,它继承自 Animal,并且有一个新的方法 meow()。最后,在 main() 方法中,创建了一个 Cat 对象并调用了它的 eat()meow() 方法。

3.3.2 接口与接口的继承

接口与接口的继承格式:

interface SubInterface extends SuperInterface1, SuperInterface2, ... {// ...
}

其中,SubInterface 是子接口的名称,SuperInterface1SuperInterface2 等是父接口的名称。

例如:

interface Shape {void draw();
}interface Circle extends Shape {double getRadius();
}class CircleImpl implements Circle {private double radius;public CircleImpl(double radius) {this.radius = radius;}@Overridepublic void draw() {System.out.println("Drawing circle...");}@Overridepublic double getRadius() {return this.radius;}
}public class Main {public static void main(String[] args) {Circle circle = new CircleImpl(5.0);circle.draw();System.out.println("Radius: " + circle.getRadius());}
}

在上面的例子中,定义了一个 Shape 接口,并有一个 draw() 方法。同时,定义了一个 Circle 接口,它继承自 Shape 并有一个新的抽象方法 getRadius()。接着,在 CircleImpl 类中,实现了 Circle 接口中的 draw()getRadius() 方法。最后,在 main() 方法中,创建了一个 CircleImpl 对象,并调用了 draw()getRadius() 方法。

4.类与接口的区别

类与接口是两种不同的概念。
  1. 实现方式:

    • 类是对对象的实现,描述了对象具有的属性和方法,并提供了具体的实现代码。

    • 接口是一种约定,它定义了一组方法的签名(方法名、参数列表和返回类型),但没有提供具体的实现代码。

  2. 继承关系:

    • 一个类可以继承自另一个类,它可以拥有父类的属性和方法,并可以通过重写和扩展来定制自己的行为。

    • 一个类可以实现一个或多个接口,通过实现接口的方法来定义自己的行为,同时一个类可以继承一个类并实现多个接口。

  3. 多态性:

    • 类的实例可以通过父类引用指向子类对象,从而实现多态性。

    • 接口可以通过接口类型的引用指向实现了该接口的类的对象,也可以实现多态性。

  4. 可继承性:

    • 类可以通过继承来获取父类的属性和方法,并可以进行重写和扩展,从而实现代码的复用。

    • 接口可以通过继承其他接口的方式来扩展自己的方法,从而实现接口之间的代码复用。

  5. 实例化:

    • 类可以被实例化为对象,通过创建对象来调用类中的方法。

    • 接口不能被直接实例化,但是可以通过实现接口的类来创建该类的对象,然后通过接口引用来调用接口中的方法。

5. 注意事项

在使用接口时,有一些需要注意的事项:

  1. 接口不能被实例化:接口本身不能直接创建对象,因为接口没有提供实现。但是可以通过实现接口的类来创建对象。

  2. 接口中的方法默认为抽象方法:接口中的方法默认为抽象方法,没有方法体。实现接口的类必须提供具体的方法实现。

  3. 接口中的字段默认为常量:接口中的字段默认为 public static final,即常量。实现接口的类不可以修改接口中的常量值。

  4. 类可以实现多个接口:一个类可以实现一个或多个接口,通过逗号分隔。

  5. 接口可以继承多个接口:一个接口可以继承一个或多个接口,通过扩展关键字 extends 和逗号分隔。

  6. 接口不能实现其他接口:接口不能实现其他接口,只能继承其他接口。

     "实现"通常指的是在一个类中提供对接口中定义的方法的具体实现。实现是指在实现类中编写实际的代码,以使得类具有接口中声明的方法所描述的行为。
    
  7. 接口可以作为数据类型使用:可以使用接口作为方法的参数类型、返回值类型,或者定义接口类型的变量。

  8. 实现类必须实现接口的所有方法:如果一个类实现了某个接口,那么它必须实现接口中定义的所有方法,除非它自己也是一个抽象类。

  9. 默认方法和静态方法:Java 8 引入了接口中的默认方法和静态方法。默认方法为接口提供了方法的默认实现,而静态方法为接口提供了静态方法的实现。

  10. 接口不能包含实例状态:接口中只能包含方法和常量,不能包含实例变量。

适配器设计模式

适配器设计模式(Adapter Design Pattern)是一种结构型设计模式,用于将一个类的接口转换成客户端所期望的另一个接口。

适配器模式可以让不兼容的类可以一起工作,通过将不同类的接口进行适配,使得它们能够协同工作。

在客户端代码中,先通过一个适配器对象将适配者类转换为目标接口,然后客户端通过目标接口调用适配器类的方法,由适配器类再通过持有的适配者类实例来调用适配者类的不兼容方法,从而实现了目标接口和适配者类的适配。

下面假设有一个目标接口 Target,它定义了客户端所需要的接口,但是该接口与 Adaptee 接口不兼容,我们需要一个适配器来将 Adaptee 转化为 Target 接口的形式。代码如下:

// 目标接口
interface Target {// 客户端所需的接口void request();
}// 适配者类
class Adaptee {// 与目标接口不兼容的接口void specificRequest() {System.out.println("适配者类的方法被调用了。");}
}// 适配器类
class Adapter implements Target {// 持有适配者类的实例private Adaptee adaptee = new Adaptee();@Overridepublic void request() {// 进行适配转换adaptee.specificRequest();}
}// 客户端代码
public class Client {public static void main(String[] args) {// 创建一个适配器对象,将适配者类转换为目标接口Target adapter = new Adapter();// 客户端通过目标接口调用适配者类的方法adapter.request(); // 输出:适配者类的方法被调用了。}
}

在上述代码中,Target 接口定义了客户端所需要的接口,Adaptee 类是需要被适配的类,其接口与目标接口不兼容,即 Adaptee 中的 specificRequest 方法与 Target 中的 request 方法不同。Adapter 类是适配器类,它实现了目标接口 Target,并持有适配者类 Adaptee 的实例。Adapter 类的 request 方法将客户端的请求转发给适配者类,并进行适当的转换,以使得适配者类的接口能够与目标接口兼容。

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

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

相关文章

深入理解 go reflect - 要不要传指针

在我们看一些使用反射的代码的时候,会发现,reflect.ValueOf 或 reflect.TypeOf 的参数有些地方使用的是指针参数,有些地方又不是指针参数, 但是好像这两者在使用上没什么区别,比如下面这样: var a 1 v1 :…

dubbo如何实现像本地方法一样调用远程方法

Dubbo 实现像本地方法一样调用远程方法的核心技术是动态代理。Dubbo 使用JDK 动态代理或者字节码增强技术,生成一个代理类,该代理类实现了本地接口,具有本地接口的所有方法。在调用本地接口方法时,会通过代理类的 invoke 方法将请…

golang Iris 运行多个应用

在 Iris 里面,提供了一种方式可以让我们同时运行多个应用: 这里说的应用只是一个 Iris 框架实例,这个实例可以有完全不同的路由定义、中间件等。 不同端口不同应用 package mainimport ("log""net/http""time"…

二叉树的四种遍历方式

二叉树的遍历 二叉树常见的遍历方式有层序遍历,前序遍历,中序遍历,后序遍历 层序遍历 从顶部到底部,逐层进行遍历,且每一层按照从左到右的顺序遍历 层序遍历本质上是广度优先遍历(BFS) 代码实现 广度优先遍历一般使用队…

AI教我学编程之C#类的基本概念(1)

前言 在AI教我学编程之C#类型 中,我们学习了C#类型的的基础知识,而类正是类型的一种. 目录 区分类和类型 什么是类? 什么是类型? 追问 实操 总结 区分类和类型 在 C# 中,类是类型的一种。C# 是一种面向对象的编程…

js 数组内置的方法

JavaScript中数组内置了许多有用的方法,可以方便地操作和处理数组。以下是一些常用的数组方法: push():向数组末尾添加一个或多个元素,并返回新数组的长度。pop():移除数组末尾的元素,并返回被移除的元素。…

uniapp如何调用ANDROID原生函数

在 UniApp 中调用 Android 原生函数,通常需要使用 UniApp 的插件系统。以下是调用 Android 原生函数的一般步骤: 安装插件:首先,确保你已经安装了对应的插件。你可以在 UniApp 插件市场 中搜索并安装你需要的插件。对于 Android 原…

利用XSS漏洞打cookie

目录 1、为什么要打cookie? 2、怎样利用XSS来打cookie? 3、利用Bluelotus_xssReceiver平台来打cookie 4、利用beef-xss平台来打cookie 上一篇给大家介绍了xss漏洞的基础知识,在本篇章将会介绍和演示一下利用xss漏洞打cookie的演示&#x…

复习回顾、静态、继承、引用类型使用

今日内容 复习回顾 定义类。一个Java文件可以定义多个类。但是只有一个类是用public修饰,public修饰的类名必须称为Java文件名。类中有且仅有5大成分(五大金刚) 成员变量Field:描述类或者对象的属性信息的。成员方法Method&#…

DAY8--learning english

一、积累 1.haunt Why Ghost dont haunt chinese. 为什么鬼不会出现在中国人旁边? 2.confess i have a confession to make ... I actally a blind. 我要坦白一件事……我其实是个盲人。 3.brake Press S button to brake, or to reverse if the vehicle has stopped, 按住…

Spring MVC中的常用注解及其用法

文章目录 一、建立连接二、接收请求2.1请求中带有一个参数2.2请求中带有多个参数2.3用对象接收请求中的参数2.4对请求中的参数进行重命名2.5请求参数中带有数组2.6请求参数中带有集合2.7json字符串和Java对象互转2.8前端传递json数据给后端、json数据在请求正文中、后端接收jso…

【时事篇-04】兔子繁殖问题(斐波那契数列)

兔子繁殖问题monthinput("请输入月份:") if month.isdigit():monthint(month)a0b1for i in range(month-1):a,bb,abprint("%d月份以后兔子有%d对"%(month,b)) else:print("输入有误请重新输入")

android.os.NetworkOnMainThreadException

问题 android.os.NetworkOnMainThreadException详细问题 核心代码如下: import android.os.Bundle;import androidx.appcompat.app.AppCompatActivity;import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import ja…

30 3D导航栏

效果演示 实现了一个导航栏&#xff0c;其中包含了五个图标&#xff0c;每个图标都有一个悬浮的文字标签&#xff0c;当鼠标悬停在图标上时&#xff0c;文字标签会旋转并向上移动&#xff0c;同时底部会出现一个阴影效果。整个导航栏的背景颜色为浅灰色。 Code <ul><…

python 字典的基础及应用

当前版本&#xff1a; Python 3.8.4 简介 字典是一种无序的、可变的、键值对的数据结构。通常用于存储键值对&#xff0c;其中键是唯一的&#xff0c;值可以是任何类型的对象。它可以快速查找和访问数据&#xff0c;关联相互有关的信息&#xff0c;灵活地添加、修改和删除数据…

QT+OSG/osgEarth编译之七十六:glsl+Qt编译(一套代码、一套框架,跨平台编译,版本:OSG-3.6.5插件库osgdb_glsl)

目录 1、osgdb_glsl介绍 2、文件分析 3、pro文件 4、编译实践 1、osgdb_glsl介绍 通过osgdb_glsl,osg能方便地读取glsl着色语言,从而为三维场景的渲染提供支撑。 GLSL(OpenGL Shadi

Day03

今日任务 链表理论基础203.移除链表元素707.设计链表206.反转链表 链表理论基础 1&#xff09;单链表 单链表中的指针域只能指向节点的下一个节点 2&#xff09;双链表 双链表&#xff1a;每一个节点有两个指针域&#xff0c;一个指向下一个节点&#xff0c;一个指向上一个…

k8s云原生环境搭建笔记——第二篇

目录 1、使用普通方式安装prometheus和grafana1.1、安装kube-state-metrics容器1.1.1、下载并修改yaml文件1.1.2、导入kube-state-metrics镜像1.1.3、执行yaml文件目录 1.2、安装node-exploer1.2.1、创建名称空间prometheus1.2.2、执行yaml 1.3、安装prometheus1.3.1、创建集群…

QT上位机开发(动画效果)

【 声明&#xff1a;版权所有&#xff0c;欢迎转载&#xff0c;请勿用于商业用途。 联系信箱&#xff1a;feixiaoxing 163.com】 不管是仿真&#xff0c;还是对真实环境的一比一模拟&#xff0c;动画都是非常好的一种呈现方式。目前在qt上面&#xff0c;实现动画主要有两种方法…

js(JavaScript)数据结构之堆(Heap)

什么是数据结构&#xff1f; 下面是维基百科的解释&#xff1a; 数据结构是计算机存储、组织数据的方式。数据结构意味着接口或封装&#xff1a;一个数据结构可被视为两个函数之间的接口&#xff0c;或者是由数据类型联合组成的存储内容的访问方法封装。 我们每天的编码中都会…