Java接口学习(接口的使用、简单工厂、代理模式、接口和抽象类的区别)

前言引入

官方解释:Java接口是一系列方法的声明,是一些方法特征的集合,一个接口只有方法的特征没有方法的实现,因此这些方法可以在不同的地方被不同的类实现,而这些实现可以具有不同的行为(功能)。

我的理解:接口可以理解为一种特殊的抽象类,里面全部是由全局常量和公共的抽象方法所组成。接口是解决Java无法使用多继承的一种手段,可以实现多个接口的实现,但是接口在实际中更多的作用是制定标准的。或者我们可以直接把接口理解为100%的抽象类,接口中的方法必须全部是抽象方法。

一、接口的基本概念与主要特点;
二、接口的使用;
三、接口应用:简单工厂设计模式、代理设计模式简单实现。

一、接口的基本概念与主要特点

  • 如果一个类中只是由抽象方法和全局变量所组成,那么在这种情况下不会定义为抽象类,而会定义为接口,接口严格来讲是一个抽象类,而且这个类里面只有抽象方法和全局变量,没有构造方法。

1.1 接口特点

就像一个类一样,一个接口也能够拥有方法和属性,但是在接口中声明的方法默认是抽象的。(即只有方法标识符,而没有方法体)。

  • 接口不能实例化,可以按照多态的方式来实例化;
  • 接口没有构造方法;
  • 接口指明了一个类必须要做什么和不能做什么,相当于类的行为的规划;
  • 一个接口就是描述一种能力,比如 “Animal” 也可以作为一个接口,并且任何实现“Animal”接口的类都必须有能力实现 “奔跑”这个动作(或者implement run()方法),所以接口的作用就是告诉类,你要实现我这种接口代表的功能,你就必须实现某些方法,我才能承认你确实拥有该接口代表的某种能力;
  • 如果一个类实现了一个接口中要求的所有的方法,然而没有提供方法体而仅仅只有方法标识,那么这个类一定是一个抽象类。(牢记:抽象方法只能存在于抽象类或者接口中,但抽象类中却能存在非抽象方法,即有方法体的方法。接口是百分之百的抽象类

一个JAVA库中接口的例子是:Iterator 接口,这个接口代表了“能够进行迭代遍历”这种能力,任何类只要实现了这个 “ Iterator” 接口的话,这个类也具备了 “迭代遍历” 这种能力,那么就可以用来进行元素遍历操作了。

1.2 为什么要用接口

  1. 接口被用来描述一种抽象,表达的一种 “ has - a” 关系,方便以后功能的扩展。
  2. Java可以通过实现接口来弥补单继承局限。
  3. 接口用来实现解耦,制定一种标准。
  4. 接口定义的变量一定是public static final 的,实现 此接口的类都可以使用这个变量。

二、接口的使用

2.1 接口的定义

要定义一个接口使用 interface 关键字完成。

interface A{ // 定义接口public static final String MSG="hello";//	抽象方法public abstract void print();
}

由于接口里面存在有抽象方法,所以接口对象不能用关键字new进行实例化的操作。先说几个接口使用的限制:

  • 接口必须要有子类实现,此时一个子类可以使用implement关键字实现多个接口;
  • 接口的子类(如果不是抽象类),必须要覆写接口中的全部抽象方法;
  • 接口中的对象可以利用子类对象的向上转型进行实例化的操作。

范例:实现接口

interface A {  // 定义了接口public static final String MSG = "hello";// 抽象方法public abstract void print();
}
interface B {public abstract void get();
}
class X implements A,B { // 实现多个接口public void get() {System.out.println("B接口的抽象方法");}public void print() {System.out.println("A接口的抽象方法");}
}
public class TestDemo {public static void main(String args[]){X x = new C();//实例化子类对象A a = x;B b = x;//	A a = new X();//向上转型//	B b = new X();//向上转型a.print();b.get();}
}

以上的代码实例化了 “x” 对象,由于 X 是 A 和 B 的子类,那么 X 类对象可以变为 A 接口或 B 接口类的对象。

在定义上 A 和 B 接口没有任何的直接联系,但是这两个接口却同时拥有一个子类: X 子类,不要被类型和名称所迷惑,因为最终实例化的 X 的子类,而这个子类属于 B 类的对象,所以以上的代码行的通,代码编写上并不是很友好。

  • 子类除了可以实现接口,还可能去继承抽象类,所以说一个子类又要继承抽象类,还要实现接口的话,先使用extends继承,而后使用implements实现。

2.2 子类继承和接口实现使用

代码示例(即有继承关系又有接口实现)

  interface A { // 定义了接口public static final String MSG = "hello";// 抽象方法public abstract void print();}interface B {public abstract void get();}abstract class C { // 定义一个抽象类public abstract void change();}class X extends C implements A,B {//先继承,再实现接口public void get() {System.out.println("B接口的抽象方法");}public void print() {System.out.println("A接口的抽象方法");}public void change(){System.out.println("C类的抽象方法");}}

对接口而言,发现里面的组成是抽象方法和全局变量,所以很多的时候有些人为了简略不会写 abstract 和 public static final,并且在方法上是否编写 public 结果都是一样的,因为在接口里面只能够使用一种访问权限——public。以下两个接口的定义效果是一样的:

interface A{public static final String MSG="HELLO";public void fun();
}
// 另一种定义方式 ,常量的话 我们 一般 写成  public static final String MSG = “Hello”;	
Interface A{String MSG=”HELLO”;void fun();
}

一个抽象类可以继承一个抽象类,一个接口可以使用extends关键字同时继承多个接口,接口不可以继承抽象类。

2.3 接口的多继承

范例:接口的多继承

interface A {public void funA();
}
interface B {public void funB();
}
interface C extends A,B {public void funC();
}
class X implements C {public void funA() {    } // 覆写全部的方法public void funB() {	}public void funC() {	}
}

从继承关系上讲接口比抽象类的优势明显:

  • 一个抽象类只能继承一个抽象类,而接口没有这个限制;
  • 一个子类只能够继承一个抽象类,而却可以实现多个接口。

在java中,接口解决了单继承的局限性问题。 虽然从接口本身的概念来讲只能够由抽象方法和全局变量所组成,但是所有的内部结构不受这些要求的限制,也就是说在接口中可以定义普通内部类、抽象内部类、内部接口。

2.4 在接口中定义抽象类和 static 接口

范例:在接口里定义抽象类

interface A{public void funA();// 独立的class文件,abstract class B{// 在接口中的abstract可以不用写,但在抽象类中的抽象方法必须要写abstractpublic abstract void funB();}interface Entry { // 接口中定义接口 ,Map.Entry  HashMap 源码   Collection 中的 Iterator 接口}
}
class X implements A { // X 实现了A接口public void funA() {System.out.println("Hello World");}class Y extends B { // 内部类 Y继承了抽象类 B 实现了  funB() 方法public void funB () {System.out.println("hello C");}	}
}

在接口中定义static接口

 interface A {public void funA();// static声明的内部接口为外部接口,static声明的内部类为外部类static interface B{ // 外部接口,public void funB();}}class X implements A.B{ // 实现时使用“类名.内部接口”public void funB() {}	

先期总结:接口在实际的开发中三大核心作用:

  • 定义不同层之间的操作标准;
  • 表示一种操作的能力;
  • 表示将服务端的远程方法视图暴露给客户。

2.5 接口中的实际应用——标准

电脑上可以使用U盘、Mp3、打印机,这些设备都是连接到USB设备上的。

在这里插入图片描述

  • 所有的代码如果要进行开发,一定要首先开发出USB接口标准,因为有了标准后电脑才可以去使用这些标准,设备厂商才可以设计USB设备。

范例:定义USB标准(标准可以连接不同层的操作)

// 标准可以连接不同层的操作
interface USB { // 定义标准一定是接口public void start();public void stop();
}  

范例:定义电脑
不管以后有多少个设备,只要它是 USB 标准的实现子类,它都可以在电脑上使用。

class Computer {public void plugin(USB usb){//插入usb.start();usb.stop();}
}

范例:定义U盘

class Flash implements USB {public void start(){System.out.println("U盘开始使用");}public void stop(){System.out.println("u盘停止使用");}
}

范例:定义打印机

class Print implements USB {public void start(){System.out.println("打印机开始工作");}public void stop(){System.out.println("打印机停止工作");}
}

按照这样的方式,准备好多个子类都可以在电脑的plugin()方法上使用

interface USB{//定义标准一定是接口public void start();public void stop();
}
class Computer {public void plugin(USB usb){//插入usb.start();usb.stop();}
}
class Flash implements USB{public void start(){System.out.println("U盘开始使用");}public void stop(){System.out.println("u盘停止使用");}
}
class Print implements USB{public void start(){System.out.println("打印机开始工作");}public void stop(){System.out.println("打印机停止工作");}
}
public class TestDemo {public static void main(String args[]){Computer com = new Computer();com.plugin(new Flash());com.plugin(new Print());}
}

在现实生活中,标准的概念随处可见,而在程序里面标准就是用接口来实现的。

三、接口的应用(简单工厂和代理)

3.1 接口的应用——工厂设计模式(Factory 简单介绍)

下面观察一段程序代码

interface Fruit {public void eat();
}
class Apple implements Fruit {public void eat() {System.out.println("吃苹果");}
}
public class TestDemo {public static void main(String args[]){Fruit f = new Apple();f.eat();
}

以上的程序可以通过主方法得到Fruit接口对象,这种代码设计有问题吗?
本端程序的问题就是出现了关键字“new”。

评判一段代码是否真的好,有这么几个标准:

  • 客户端可以调用,不需要关注具体的细节;

  • 客户端之外的代码修改,不影响用户端的使用,即:用户端可以不关
    心代码是否变更。
    一个接口不可能只有一个子类,对于Fruit也有可能产生多个子类对象(Apple,Orange)。

现在每次客户端想要得到新的子类对象,都需要修改代码,如果在客户端实例化对象,那么每一要更换对象对象,都需要修改客户端上的代码,这样的做法是不友好的。

  • 现在要解决是如何得到一个Fruit接口对象,而后进行方法的调用,至于这个接口对象是被谁实例化的,不是我客户端的工作。现在最大的问题在于关键字new,这一问题可以理解为耦合度太高。耦合度太高的直接问题就是代码不方便维护,相当于A与B绑定在一起。

程序 -> JVM -> 适应不同的操作系统(A->C->B)

范例:增加一个过渡

class Factory {public static Fruit getInstance(String className){if ("apple".equals(className)) {return new Apple();} else if ("orange".equals(className)) {return new Orange();} else {return null;}}
}
public class TestDemo {public static void main(String args[]){Fruit f = Factory.getInstance("apple");f.eat();}
}
  • 现在的客户端不会看见具体的子类,因为所有的接口对象都是通过Factory类取得子类对象,则只需要修改Factory类即可,但是客户端不会发生变化。
    在这里插入图片描述

工厂类跟操作的接口类有关,也跟所有的子类有关;客户端可看见接口,还可以看见工厂,客户端使用getInstance()方法找到工厂类中定义的方法,这个方法返回接口对象,通过接口对象就可以获得接口中的操作方法。

面试题:请编写一个Factory程序

3.2 接口的应用——代理设计模式(Proxy简单介绍)

皇帝宠幸妃子的为例,具体步骤图中已经列出。
在这里插入图片描述
范例:转换为程序

interface Subject { // 整个操作的核心public void makeLove(); // 整个临幸的核心功能
}
class RealSubject implements Subject { // 一个接口两个主题 public void makeLove() {System.out.println("正在");}
}
class ProxySubject implements Subject {//内务private Subject subject;// 要接受一个真正主题的操作对象public ProxySubject(Subject subject){this.subject = subject;}public void prepare(){ // 扩展的功能System.out.println("为临幸做准备");}public void makeLove() {this.prepare();this.subject.makeLove(); // 告诉皇帝可以开始了this.end();}public void end() { // 扩展的功能System.out.println("娘娘带走,皇帝睡觉");}
}
public class TestDemo {public static void main(String args[]){Subject sub = new ProxySubject(new RealSubject());sub.makeLove();//调用的是代理操作}
}
  • 代理设计模式的核心精髓就在于一个主题操作接口(可能有多种方法),核心业务主题只完成核心功能。而代理主题负责所有与核心主题有关的辅助型操作。

在这里插入图片描述
代理模式的主要角色如下。

  • 代理主题类(Subject ):通过接口或抽象类声明真实主题和代理对象实现的业务方法。

  • 真实主题类(RealSubject):实现了抽象主题中的具体业务,是代理对象所代表的真实对象,是最终要引用的对象。

  • 代理(ProxySubject)类:提供了与真实主题相同的接口,其内部含有对真实主题的引用,它可以访问、控制或扩展真实主题的功能。

使用代理(静态代理)的目的和缺陷:

  • 可以做到在不修改目标对象的功能前提下,对目标功能扩展.

缺点:

  • 因为代理对象需要与目标对象实现一样的接口,所以会有很多代理类,类太多.同时,一旦接口增加方法,目标对象与代理对象都要维护.

面试题:请编写一个Proxy模式程序

四、抽象类与接口的区别(面试题)

抽象类和接口使用的形式上是十分相似的。

4.1 表格对比
在这里插入图片描述
4.2 文字描述

接口与抽象类的区别:

  • 抽象类是对一种事物的抽象,即对类抽象,而接口是对行为的抽象,也就是对方法的抽象。

  • 抽象类可以有具体的成员方法,而接口中只能存在抽象方法;

  • 抽象类中的成员变量可以是各种类型的,而接口中的成员变量只能是public static final类型的;

  • 接口中不能含有静态代码块以及静态方法,而抽象类可以有静态代码块和静态方法;

  • 一个类只能继承一个抽象类,而一个类却可以实现多个接口。

  • 抽象类如果需要添加新的方法,可以直接在抽象类中添加具体的实现,子类可以不进行变更;而接口进行了变更,则所有实现这个接口的类都必须进行相应的改动(功能扩展)。经过比较可以发现,抽象类中支持的功能绝对要比接口更多,但是抽象类有单继承局限性。

代码编写的习惯:

  • 在进行某些公共操作的时候一定要定义出接口;
  • 有了接口后需利用子类完善方法;
  • 如果是自己写的接口,绝对不要使用关键字new直接实例化接口子类,使用工厂类完成。

四、总结

  1. 接口的基本使用;
  2. 接口作为标准用于解耦和以及不同层之间的连接桥梁;
  3. 工厂设计模式与代理设计模式的简单介绍;
  4. 接口与抽象类定义的不同。

参考文档:https://www.cnblogs.com/qmdx00/p/7469379.html
https://blog.csdn.net/qq_19782019/article/details/80259836

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

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

相关文章

最短路径 floyd java_java实现Floyd算法求最短路径

关于无向图的最短路径问题:这个程序输出:最短路径矩阵例如:W[0][5]9 代表vo->v5的最短路径为9W:0 1 3 7 4 91 0 2 6 3 83 2 0 4 1 67 6 4 0 3 24 3 1 3 0 59 8 6 2 5 0package com.xh.Floyd;import java.util.ArrayList;public class Floyd_01 {publi…

SpringBoot 使用 log4j2

一、新建工程 选择一些基础依赖 填写工程名称和项目路径 二、工程配置 修改文件编码格式 设置Java Compiler 修改maven配置文件路径 三、pom.xml的web依赖中排除掉logging依赖&#xff0c;并且引入log4j2依赖 <dependency><groupId>org.springframework.…

springBoot 通过使用log4j2

1.排除 Spring-boot-starter 默认的日志配置 将原本的 spring-boot-starter 改为 <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter</artifactId><exclusions><exclusion><groupId>…

SpringBoot默认日志logback配置解析

SpringBoot默认日志logback配置解析 前言 今天来介绍下Spring Boot如何配置日志logback,我刚学习的时候&#xff0c;是带着下面几个问题来查资料的&#xff0c;你呢 如何引入日志&#xff1f;日志输出格式以及输出方式如何配置&#xff1f;代码中如何使用&#xff1f; 正文…

SpringBoot查看和修改依赖的版本

springBoot依赖管理&#xff1a; 1、引入父项目的作用是实现对所有依赖的管理。 <parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>2.3.4.RELEASE</version> &l…

在IDEA中解决jar包冲突的神操作-必看

在开发过程中&#xff0c;经常会遇到导入jar包后jar包冲突的情况&#xff0c;大家也都知道&#xff0c;解决jar包冲突通常都比较麻烦&#xff0c;要找到多余的依赖&#xff0c;把低版本的依赖去掉。而大家通常能搜到IDEA解决jar包冲突的方法&#xff0c;应该是这样的&#xff1…

MySQL保存或更新 saveOrUpdate

1. 引子 在项目开发过程中&#xff0c;有一些数据在写入时候&#xff0c;若已经存在&#xff0c;则覆盖即可。这样可以防止多次重复写入唯一键冲突报错。下面先给出两个MyBatis配置文件中使用saveOrUpdate的示例 <!-- 单条数据保存 --> <insert id"saveOrUpdat…

分布式事务六种解决方案

前言 事务想必大家并不陌生&#xff0c;至于什么是 ACID&#xff0c;也是老生常谈了。不过为了保证文章的完整性确保所有人都听得懂&#xff0c;我还是得先说说 ACID&#xff0c;然后再来介绍下什么是分布式事务和常见的分布式事务包括 2PC、3PC、TCC、本地消息表、消息事务、…

Minor GC、Major GC和Full GC之间的区别

概念&#xff1a; ● 新生代 GC&#xff08;Minor GC&#xff09;&#xff1a;从年轻代空间&#xff08;包括 Eden 和 Survivor 区域&#xff09;回收内存被称为 Minor GC,因为 Java 对象大多都具备朝生夕灭的特性&#xff0c;所以 Minor GC 非常频繁&#xff0c;一般回收速度也…

SpringBoot——实现WebService接口服务端以及客户端开发

文章目录一、服务端代码开发1、pom依赖2、接口类3、接口实现类4、webservice配置文件2、客户端开发&#xff08;1&#xff09;pom依赖&#xff08;2&#xff09;封装客户端方法clientUtil&#xff08;3&#xff09;调用接口类&#xff08;4&#xff09;运行结果我们经常需要在两…

springboot集成webService开发详解

webService优缺点 webService优点 WebService是一种跨编程语言和跨操作系统平台的远程调用技术远程调用技术&#xff1a;不用担心防火墙的问题 webService缺点 服务端接口方为webservice则客户端也必须使用webservice&#xff0c;双方保持一致因为webservice使用xml传输数据…

WebService就是这么简单

WebService介绍 首先我们来谈一下为什么需要学习webService这样的一个技术吧…. 问题一 如果我们的网站需要提供一个天气预报这样一个需求的话&#xff0c;那我们该怎么做&#xff1f;&#xff1f;&#xff1f;&#xff1f;&#xff1f; 天气预报这么一个功能并不是简单的J…

python使用xlrd读取xlsx文件_$ 用python处理Excel文档(1)——用xlrd模块读取xls/xlsx文档...

本文主要介绍xlrd模块读取Excel文档的基本用法&#xff0c;并以一个GDP数据的文档为例来进行操作。1. 准备工作&#xff1a;1. 安装xlrd&#xff1a;pip install xlrd2. 准备数据集&#xff1a;从网上找到的1952~2012年中国国内GDP的数据&#xff0c;数据结构如下&#xff1a;2…

WebService技术详解CXF

WebService WebService简介 Web Service技术&#xff0c; 能使得运行在不同机器上的不同应用无须借助附加的、专门的第三方软件或硬件&#xff0c; 就可相互交换数据或集成。依据Web Service规范实施的应用之间&#xff0c; 无论它们所使用的语言、 平台或内部协议是什么&…

Java webservice详解

文章目录1 webservice概述2 webservice核心要素2.1 SOAP2.2 WSDL3 webservice的使用场景4 webservice的结构5 Java中的webservice5.1 webservice服务端5.2 webservice客户端6 WDSL文件说明7 webservice 请求与响应监控8 webservice 在Tomcat中发布9 在Spring中使用webservice1 …

hibernate mysql cascade_Hibernate第五篇【inverse、cascade属性详解】

前言上一篇博文已经讲解了一对多和多对一之间的关系了&#xff0c;一对多和多对一存在着关联关系(外键与主键的关系)。本博文主要讲解Inverse属性、cascade属性。这两个属性对关联关系都有影响Inverse属性Inverse属性&#xff1a;表示控制权是否转移..true:控制权已转移【当前一…

spring boot中打包插件spring-boot-maven-plugin和maven-jar-plugin的关联

简介 用spring boot快速开发时&#xff0c;通常用spring-boot-maven-plugin插件将springboot的应用程序打包成jar文件&#xff0c;然后通过java -jar运行&#xff0c;很方便。但是如果是部署到服务器上&#xff0c;每次更改代码后替换的包都比较大&#xff0c;至少30MB以上&am…

Maven父子结构的项目依赖使用以及打包依赖_微服务项目(maven父子级项目)怎么打包

Maven父子结构的项目依赖使用以及打包依赖 1&#xff1a;在父子结构项目中&#xff0c;如果要是用其他模块的类。在当前项目中的pom中 加入 其他模块的配置 <dependency><groupId>com.spring.mySpring</groupId><artifactId>mySpring-utils</artif…

搭建一个完整的微服务项目

一.项目技术架构 1.技术栈 前台技术 Node.js、Npm、Vue.js、WebPack、Vue Cli、Element UI 后台架构 微服务架构&#xff1a;按照功能拆分N多个服务&#xff0c;每个服务可以独立技术选型,独立开发,独立部署,独立运维.&#xff0c;单个服务使用基于ssm的springboot&#xff0…

java 雅思_基于JAVA的雅思考试管理系统的设计与实现(SSH,MySQL)(含录像)

基于JAVA的雅思考试管理系统的设计与实现(SSH,MySQL)(含录像)(任务书,毕业论文12000字,程序代码,MySQL数据库)本文分析了基于JAVA的雅思考试管理系统的设计与实现技术&#xff0c;结合实际提出了本系统的总体结构设计和主要模块的功能实现。本系统分为二个子系统:管理员子系统&…