java学习笔记8--接口总结

生活中的接口:

什么是接口?

一个Java接口是一些方法特征的集合,但没有方法的实现。

在类中实现接口可以使用关键字implements,其基本格式如下:

[修饰符] class <类名> [extends 父类名] [implements 接口列表]{
}
修饰符:可选参数,用于指定类的访问权限,可选值为public、abstract和final。

类名:必选参数,用于指定类的名称,类名必须是合法的Java标识符。一般情况下,要求首字母大写。

extends 父类名可选参数,用于指定要定义的类继承于哪个父类。当使用extends关键字时,父类名为必选参数。

implements 接口列表:可选参数,用于指定该类实现的是哪些接口。当使用implements关键字时,接口列表为必选参数。当接口列表中存在多个接口名时,各个接口名之间使用逗号分隔。

实现上面例子中的接口:

public interface PCI {  //java接口,相当于主板上的PCI插槽的规范public void start();public void stop();
}

Java接口中定义的方法在不同的地方被实现,可以具有完全不同的行为:

//声卡、网卡都实现了PCI插槽的规范,但行为完全不同 
class SoundCard implements PCI {    public void start() {System.out.println("SoundCard start...");}public void stop() {System.out.println("Sound stop!");}
}
class NetworkCard implements PCI {public void start() {System.out.println("NetworkCard send...");}public void stop() {System.out.println("Send stop!");}
}

可以使用Java接口标识类型。运行时,根据实际创建的对象类型调用相应的方法实现:

public class javatest {public static void main(String[] args) {PCI nc = new NetworkCard();PCI sc = new SoundCard();nc.start();sc.start();}
}

运行结果:

NetworkCard send...
SoundCard start...

为什么需要Java接口?

例子:为学校各中心开发这样一个小系统,包含类型:教员、中心、打印机,具体要求如下:

1、教员、以及中心都具有方法:输出详细信息

2、中心具有属性:打印机,能够通过中心的打印机打印教员或中心的详细信息

3、系统要具备良好的可扩展性与可维护性

先看方案1:

public class Teacher {//输出教员的详细信息public String detail() {return “I am a teacher!";}
}
public class Printer {public void print(String content) {System.out.println("start printing:");              System.out.println(content);}
}
public class ggSchool {private Printer printer = new Printer();//输出学校的详细信息public String detail() {return “this is ggSchool";}//使用打印机打印教员信息public void print(Teacher t){printer.print(t.detail());}//使用打印机打印学院信息public void print(ggSchool s){printer.print(s.detail());}
}

那么,问题来了:

每增加一种新类型,都需要增加相应的print方法,程序的可扩展性及可维护性极差,这不符合系统的要求

先看方案2(使用接口):

教师、中心都存在一个共同的方法特征:detail,它们对detail方法有各自不同的实现——这完全符合Java接口的定义

代码如下:

public interface Introduceable {public String detail();
}
public class Teacher implements Introduceable {//输出教员的详细信息public String detail() {return “I am a teacher!";}
}
public class ggSchool implements Introduceable {private Printer printer = new Printer();//输出学校的详细信息public String detail() {returnthis is ggSchool";}public void print(Introduceable intro) {    //使用print方法时,参数可以是任何Introduceable接口的实现类的对象,//不必再为不同的类型建立不同的print方法了printer.print(intro.detail());}
}
public class Printer {public void print(String content) {System.out.println("start printing:");              System.out.println(content);}
}

通过Java接口,我们同样可以享受到多态性的好处,大大提高了程序的可扩展性及可维护性 

什么是面向接口编程?

开发系统时,主体构架使用接口,接口构成系统的骨架,这样就可以通过更换接口的实现类来更换系统的实现

升级上面的系统,要求:

打印机有多种类型,比如:黑白打印机、彩色打印机等

学院可能配备其中任意一款打印机,负责打印教员、或者学院的详细信息

系统要具备良好的可扩展性与可维护性

第一步:抽象出Java接口

1、分析:

黑白、彩色打印机都存在一个共同的方法特征:print

黑白、彩色打印机对print方法有各自不同的实现

2、结论:

抽象出Java接口PrinterFace,在其中定义方法print

3、具体实现:

public interface PrinterFace {public void print(String content);
}
第二步:实现Java接口

1、分析:

已经抽象出Java接口PrinterFace,并在其中定义了print方法黑白、彩色打印机对print方法有各自不同的实现

2、结论:黑白、彩色打印机都实现PrinterFace接口,各自实现print方法

3、具体实现:

public class ColorPrinter implements PrinterFace {public void print(String content) {System.out.println("彩色打印:");System.out.println(content);}
}
public class BlackPrinter implements PrinterFace {public void print(String content) {System.out.println("黑白打印:");System.out.println(content);}
}

第三步:使用Java接口

1、分析:主体构架使用接口, 让接口构成系统的骨架

2、结论:更换实现接口的类就可以更换系统的实现

3、具体实现:

public class ggSchool implements Introduceable{private PrinterFace printer;  //打印机public void setPrinter(PrinterFace p) {this.printer = p;}public String detail() {return "this is ggSchool!";}public void print(Introduceable intro){printer.print(intro.detail());}
}
public class Test {public static void main(String[] args) {// 创建学院实例ggSchool school=new ggSchool();//为该学院配备黑白打印机school.setPrinter(new BlackPrinter());school.print(school); //为该学院配备彩色打印机school.setPrinter(new ColorPrinter());school.print(school);}
}

抽象类与接口

抽象类的子类必须覆盖所有的抽象方法后才能被实例化,否则这个子类还是个抽象类。

如果一个抽象类中的所有方法都是抽象的,就可以将这个类用另外一种方式来定义,也就是接口定义。

抽象方法只需声明,不需实现。

接口是抽象方法和常量值的定义的集合。

从本质上讲,接口是一种特殊的抽象类。这种抽象类中包含常量和方法的定义,而没有变量和方法的实现。例如

注意:在接口的定义中,所有的成员都是public访问类型的,而不论是否用public关键字修饰;接口里的变量都是用public static final标识的,所以,接口中定义的变量就是全局静

态常量。

我们可以定义一个新的接口,用extends关键字去继承一个已有的接口。注意:只能接口继承接口,类不能继承接口。

一个类只能用implements关键字去实现一个接口中的所有方法

一个类可以在继承一个父类的同时,实现一个或多个接口,extends关键字必须位于implements关键字之前,如我们可以这样定义:

class classA {//...
}
public interface Interface1{//...
}
public interface Interface2{//...
}
class classB extends classA implements Interface1 Interface2{//...
}

抽象类和接口的区别

1.语法层面上的区别

  1)抽象类可以提供成员方法的实现细节,而接口中只能存在public abstract 方法;

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

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

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

2.设计层面上的区别

  1)抽象类是对一种事物的抽象,即对类抽象,而接口是对行为的抽象。抽 象类是对整个类整体进行抽象,包括属性、行为,但是接口却是对类局部(行为)进行抽象。举个简单的例子,飞机和鸟是不同类的事物,但是它们都有一个共性, 就是都会飞。那么在设计的时候,可以将飞机设计为一个类Airplane,将鸟设计为一个类Bird,但是不能将 飞行 这个特性也设计为类,因此它只是一个行为特性,并不是对一类事物的抽象描述。此时可以将 飞行 设计为一个接口Fly,包含方法fly( ),然后Airplane和Bird分别根据自己的需要实现Fly这个接口。然后至于有不同种类的飞机,比如战斗机、民用飞机等直接继承Airplane 即可,对于鸟也是类似的,不同种类的鸟直接继承Bird类即可。从这里可以看出,继承是一个 "是不是"的关系,而接口实现则是 "有没有"的关系。如果一个类继承了某个抽象类,则子类必定是抽象类的种类,而接口实现则是有没有、具备不具备的关系,比如鸟是否能飞(或者是否具备飞行这个特点),能飞行则可以实现这个接口,不能飞行就不实现这个接口。

  2)设计层面不同,抽象类作为很多子类的父类,它是一种模板式设计。而接口是一种行为规范,它是一种辐射式设计。什 么是模板式设计?最简单例子,大家都用过ppt里面的模板,如果用模板A设计了ppt B和ppt C,ppt B和ppt C公共的部分就是模板A了,如果它们的公共部分需要改动,则只需要改动模板A就可以了,不需要重新对ppt B和ppt C进行改动。而辐射式设计,比如某个电梯都装了某种报警器,一旦要更新报警器,就必须全部更新。也就是说对于抽象类,如果需要添加新的方法,可以直接在抽 象类中添加具体的实现,子类可以不进行变更;而对于接口则不行,如果接口进行了变更,则所有实现这个接口的类都必须进行相应的改动。

下面看一个网上流传最广泛的例子:门和警报的例子:门都有open( )和close( )两个动作,此时我们可以定义通过抽象类和接口来定义这个抽象概念:

abstract class Door {public abstract void open();public abstract void close();
}

或者:

interface Door {public abstract void open();public abstract void close();
}

但是现在如果我们需要门具有报警alarm( )的功能,那么该如何实现?下面提供两种思路:

1)将这三个功能都放在抽象类里面,但是这样一来所有继承于这个抽象类的子类都具备了报警功能,但是有的门并不一定具备报警功能;

2)将这三个功能都放在接口里,需要用到报警功能的类就需要实现这个接口中的open( )和close( ),也许这个类根本就不具备open( )和close( )这两个功能,比如火灾报警器。

从这里可以看出, Door的open() 、close()和alarm()根本就属于两个不同范畴内的行为,open()和close()属于门本身固有的行为特性,而alarm()属于延伸的 附加行为。因此最好的解决办法是单独将报警设计为一个接口,包含alarm()行为,Door设计为单独的一个抽象类,包含open和close两种行 为。再设计一个报警门继承Door类和实现Alarm接口。

interface Alram {void alarm();
}abstract class Door {void open();void close();
}class AlarmDoor extends Door implements Alarm {void oepn() {//....}void close() {//....}void alarm() {//....}
}

抽象类和接口在Java中的应用

例子:假设有若干 (如1000)个Circle,Rectangle以及若干个其他形状,希望计算它们的总面积,直截了当的做法是将它们分别放到多个数组中,分别循环求出 各形状的面积,然后累加,这种做法是不漂亮的。如果还有其它形状:triangle,ellipses等,上述方法显得“累赘”。希望有一种统一的表示, 例如用一个数组shape[],接受所有的形状,然后用:

 for (i=0; i<shape.length; i++)area_total += shape[i].area();

用抽象类实现多种形状面积的累加:

首先看看Circle和Rectangle两个类,如何完成相关参数的计算 :

class Circle {public float r; Circle(float r) {this.r = r;      }public float area() {return 3.14 * r * r;}
}
class Rectangle {public float width, height; Rectangle (float w, float h) {width = w; height = h;}public float area() {return width * height;}
}

现在要利用抽象类实现多种形状面积的累加,确保每种形状分别用不同的方法来计算它们的面积和周长。因此,超类Shape包含抽象方法 computeArea,然后在不同的子类中实现和覆盖这个方法,同时添加toString方法来显示几何形状的一些基本属性。现在声明了1000个 Shape对象的数组,然后循环1000次随机产生1000个平面图形对象,形状为圆、矩形、正方形三种之一。

abstract class Shape {abstract float computeArea();
}
class Circle extends Shape {public float r;public Circle(float r) {this.r = r;}public float computeArea() {return (float)3.14 * r * r;}
}
class Rectangle extends Shape {public float width, height; Rectangle (float w, float h) {width = w; //这里不需"this"height = h;}public float computeArea() {return width * height;}
}

用接口实现多种形状面积的累加:

用接口的方式实现多种形状面积的累加,需要将用抽象类表示的Shape类改成接口。由于接口的语法定义要求,我们要把原来抽象类中的成员变量去掉,成员方法改成抽象方法computeArea(),该方法返回一个double类型。所以,这个接口定义为:

public interface Shape2 {  public abstract double computeArea();
}

接口实现如下:

interface Shape2
{  public double computeArea();
}
class Circle2 implements Shape2
{protected double radius;public Circle2(double _radius) {radius = _radius;}public double computeArea() { return Math.PI * radius * radius; }
}
class Rect2 implements Shape2
{  protected double width, height;public Rect2(double w, double h) {  width = w;height = h;}public double computeArea() {  return width * height; }
}

用一个object数组实现多种形状面积的累加:

定义一个数组,它可以同时存储矩形、圆和正方形,每个Java类都是由Object扩展而来的。因此,所有的类都属于Object类型,我们可以创建一个Object类型的数组来存储任何类型的对象,也就可以存储矩形、圆和正方形对象

完整代码如下:

package javatest;
import java.util.*;
import java.io.*;interface Shape2 {  public double computeArea();
}
class Circle2 implements Shape2 {protected double radius;public Circle2(double _radius) {radius = _radius;}public double computeArea() { return Math.PI * radius * radius; }
}
class Rect2 implements Shape2 {  protected double width, height;public Rect2(double w, double h) {  width = w;height = h;}public double computeArea() {  return width * height; }
}
public class javatest {  public static void main(String args[ ]) { Shape2 s[] = { new Circle2(4),  new Rect2(4, 4), new Circle2(10),  new Rect2(20, 2), new Rect2(8, 10)};double total = 0;for(int i = 0; i < s.length; i++)total = total + s[i].computeArea();System.out.println("totalArea = " + (int)total);}
}

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

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

相关文章

.NET自定义认证虽然简单,但好用

前言有这样一种场景&#xff0c;就是新项目已经集成了认证中心&#xff0c;或者是都用了统一的认证方式(比如现在常用的JWT)&#xff0c;这样对于项目之间的对接就显得比较方便&#xff0c;至少在认证这块还是能减少一些工作量的。但当上线的老项目需要对接新项目时&#xff0c…

C语言试题187之实现strspn函数功能

📃个人主页:个人主页 🔥系列专栏:C语言试题200例 💬推荐一款刷算法、笔试、面经、拿大公司offer神器👉 点击跳转进入网站 ✅作者简介:大家好,我是码莎拉蒂,CSDN博客专家(全站排名Top 50),阿里云博客专家、51CTO博客专家、华为云享专家 1、题目 题目: 实现st…

一张图对比腾讯、阿里、百度的薪资职级

作为中国互联网三大巨头的腾讯、阿里、百度&#xff0c;他们的职级薪资福利等等等一直都是个谜&#xff0c;不为外界所知。今天&#xff0c;我就来为大家全面揭晓—— Here we go&#xff5e; 公司总部 - 腾讯&#xff1a;总部在深圳南山科技园&#xff0c;CBD地段&#xff1…

旺财速啃H5框架之Bootstrap(五)

在上一篇<<旺财速啃H5框架之Bootstrap&#xff08;四&#xff09;>>做了基本的框架&#xff0c;<<旺财速啃H5框架之Bootstrap&#xff08;二&#xff09;>>篇里也大体认识了bootstrap.css样式&#xff0c;下面我们来学习常见的CSS操控内容篇幅。。。。…

【专升本计算机】最新甘肃省专升本考试C语言部分复习题带答案

最新甘肃省专升本考试C语言部分复习题带答案 考点1.1-1.2 1、 C 语言源程序文件经过 C 编译器编译之后生成一个后缀为( )的文件 A. .c B. .obj C. .exe D. .bas 2、 C 语言源程序文件经过 C 编译器连接之后生成一个后缀为( )的文件 A. .c B. .obj C. .exe D. .bas 3、完成 …

浮点数一些设计原理

摘要&#xff1a;本篇文章会讲述浮点数的设计原理&#xff0c;比如如何存储二进制的问题&#xff0c;从而帮助我们更好的编码。 __1. deading code __ console.log(1.0-0.9 0.1); //输出 false console.log(1.0-0.9, 0.1); //输出 0.09999999999999998 0.1 //所以判断浮点运算…

Atitit. http 代理原理  atiHttpProxy  大木马

Atitit. http 代理原理 atiHttpProxy 大木马 1. 面这张图可以清晰地阐明HttpProxy的实现原理&#xff1a;1 2. 代理服务器用途1 3. 其中流程具体如下&#xff1a;2 4. 设计规划3 5. 结束语4 1. 面这张图可以清晰地阐明HttpProxy的实现原理&#xff1a; 2. 代理服务器用途 代…

[转]一文揭秘阿里、腾讯、百度的薪资职级

上周&#xff0c;阿里巴巴董事长兼CEO逍遥子发布内部邮件&#xff0c;宣布了阿里巴巴新一轮组织部晋升名单&#xff0c;涉及所有晋升到P10、P11、P12的高P的人员。其中晋升到M7/ P12的高级管理者包括&#xff1a;淘宝、天猫、阿里妈妈事业群总裁蒋凡、阿里本地生活服务公司CEO王…

C语言试题188之实现strcspn函数功能

📃个人主页:个人主页 🔥系列专栏:C语言试题200例 💬推荐一款刷算法、笔试、面经、拿大公司offer神器👉 点击跳转进入网站 ✅作者简介:大家好,我是码莎拉蒂,CSDN博客专家(全站排名Top 50),阿里云博客专家、51CTO博客专家、华为云享专家 1、题目 题目: 实现st…

【ArcGIS微课1000例】0014:ArcGIS中如何将kml(kmz)文件转shp,并进行投影转换?

KML(Keyhole Markup Language,Keyhole 标记语言)最初是由Google 旗下的Keyhole 公司开发和维护的一种基于XML 的标记语言,利用XML 语法格式描述地理空间数据(如点、线、面、多边形和模型等),适合网络环境下的地理信息协作与共享。2008 年4月,KML的最新版本2.2 被OGC 宣布为开…

写一键部署bash脚本

因为我开源的一键部署应用到linux服务器的AntDeploy&#xff0c; 在linux部署是需要安装一个agent服务(systemctl服务)如果是手动第一次安装的话 需要敲下载 wget解压 tar修改配置文件的token复制到指定安装目录设置权限设置systemd设置systemctl清除临时文件至少这8中类型的命…

UITableView的使用及代理方法

在App开放中我们经常会使用到UITabbleView&#xff0c;常用于数据展示。那么使用时不得不引入两个代理方法<UITableViewDataSource,UITableViewDelegate>。 下面我们来简单的创建一个TableView并介绍下其基本属性。 property (nonatomic,strong) UITableView * myTable; …

Java集合和泛型练习及面试题——博客园:师妹开讲啦

给定一段JAVA代码如下&#xff1a;要打印出list中存储的内容&#xff0c;以下语句正确的是&#xff08; B &#xff09; ArrayList list new ArrayList( ) list.add(“a”) list.add(“b”) Iterator it list.iterator( ) A.while(it. Next( ) )   system.out.prin…

对于经常需要truncate的表进行固定统计信息

为什么80%的码农都做不了架构师&#xff1f;>>> 大家做过统计的一些存储过程可能会知道&#xff0c;我们经常有这类表&#xff0c;要先truncate它&#xff0c;执行插入&#xff0c;再在执行相关sql&#xff0c;这就会导致有一个时间误差&#xff0c;如果在truncate…

ArcGIS实验教程——实验四十一:ArcGIS区域分析统计直方图(土地利用--坡度分级柱状统计图的制作)

文章目录 一、任务描述二、实验数据三、实验过程一、任务描述 在实际工作中,通常需要统计不同类型的土地利用数据与坡度的关系。本实验中以土地利用landuse和数字高程模型dem数据为例,基于ArcGIS平台,统计了村庄、风景名胜、林地、草地、旱地等多种类型土地利用数据所占用的…

[转]图片格式WEBP全面解析

前言 不管是 PC 还是移动端&#xff0c;图片一直是流量大头&#xff0c;以苹果公司 Retina 产品为代表的高 PPI 屏对图片的质量提出了更高的要求&#xff0c;如何保证在图片的精细度不降低的前提下缩小图片体积&#xff0c;成为了一个有价值且值得探索的事情。 但如今对于 JP…

C语言试题189之编写一个程序,按照下图中的样子创建数据结构,最后三个对象都是动态分配的结构。第一个对象则可能是一个静态的指向结构的指针

📃个人主页:个人主页 🔥系列专栏:C语言试题200例 💬推荐一款刷算法、笔试、面经、拿大公司offer神器👉 点击跳转进入网站 ✅作者简介:大家好,我是码莎拉蒂,CSDN博客专家(全站排名Top 50),阿里云博客专家、51CTO博客专家、华为云享专家 1、题目 题目: 编写一…

基于.NetCore开发博客项目 StarBlog - (15) 生成随机尺寸图片

系列文章基于.NetCore开发博客项目 StarBlog - (1) 为什么需要自己写一个博客&#xff1f;基于.NetCore开发博客项目 StarBlog - (2) 环境准备和创建项目基于.NetCore开发博客项目 StarBlog - (3) 模型设计基于.NetCore开发博客项目 StarBlog - (4) markdown博客批量导入基于.N…

【初探移动前端开发03】jQuery Mobile(上)

前言到目前为止&#xff0c;我打了几天酱油了&#xff0c;这几天落实了工作&#xff0c;并且看了一部电视连续剧&#xff08;陈道明-手机&#xff09;&#xff0c;我很少看连续剧了&#xff0c;但是手机质量很高啊&#xff0c;各位可以看看。我们今天先学习一下jquery mobile的…

Git Bash的一些命令和配置

查看git版本号&#xff1a; git --version 如果是第一次使用Git&#xff0c;你需要设置署名和邮箱&#xff1a; $ git config --global user.name "用户名" $ git config --global user.email "电子邮箱" 检查你的设置 $ git config --list 或单独检查一项…