【JAVA入门】Day15 - 接口

【JAVA入门】Day15 - 接口


文章目录

  • 【JAVA入门】Day15 - 接口
    • 一、接口是对“行为”的抽象
    • 二、接口的定义和使用
    • 三、接口中成员的特点
    • 四、接口和类之间的关系
    • 五、接口中新增的方法
      • 5.1 JDK8开始接口中新增的方法
        • 5.1.1 接口中的默认方法
        • 5.1.2 接口中的静态方法
      • 5.2 JDK9 开始接口中新增的方法
        • 5.2.1 在接口中定义私有方法
    • 六、接口的应用
    • 七、适配器设计模式


        为什么有接口?
        众所周知,继承是将子类中的共性抽象提炼到父类中,获取整个体系的共性以节省代码,但是,也存在这样一种情况:某一共性,绝大部分子类都有,但唯独极少部分子类未拥有此特性,那么如果把这个共性写进父类,继承下来,对这些少数子类而言就是不合理的了。
        比如:猫和狗都会游泳,但兔子不会,这个时候如果在父类中定义“游泳”的方法,兔子继承是不合理的,但如果猫和狗分别写自己的游泳方法,又有可能发生两个方法书写的格式、命名不一致的情况。因此我们需要定义一个新概念,来约束这两个子类中“游泳”方法的书写规范。此时,我们就可以定义一个“游泳”的接口,在接口里定义抽象方法 swim(),然后让猫和狗与这个接口连接,保证了代码的统一
         综上所述,接口就是一种规则,当我们需要给多个类同时定义规则时,就需要用到接口

一、接口是对“行为”的抽象

        接口不代表一类事物,接口代表的是一种规则,因此接口可以作为参数传递给方法。
        “不论来搬家的是货拉,三轮,哪怕是人力,只要他能实现搬家,他就有用”。

搬家(车的对象);
搬家(搬家公司);
public interface 运输 {...
}
public void 搬家(运输的接口 c) {...
}

二、接口的定义和使用

  • 接口用关键字 interface 来定义。
public interface 接口名 {}
  • 接口不能实例化,也就是说接口不能用来创建对象。
  • 接口和类之间是实现关系,通过 implements 关键字表示。
public class 类名 implements 接口名 {}
  • 接口的子类(实现类)要么重写接口中的所有抽象方法,要么本身也是一个抽象类。
  • 接口和类的实现关系,可以单实现,也可以多实现
public class 类名 implements 接口名1 , 接口名2 {}
  • 实现类可以在继承一个类的同时实现多个接口。
public class 类名 extends 父类 implements 接口名1 , 接口名2 {}

练习:编写带有接口和抽象类的标准 Javabean 类。

 青蛙		属性:名字,年龄		行为:吃虫子,蛙泳狗			属性:名字,年龄		行为:吃骨头,狗刨兔子		属性:名字,年龄		行为:吃胡萝卜

先写父类,因为三个字类吃的东西不同,可以把 eat() 定义为抽象方法:

package oopInterface;public abstract class Animal {private String name;private int age;public Animal() {}public Animal(String name, int age) {this.name = name;this.age = age;}public String getName() {return name;}public void setName(String name) {this.name = name;}public int getAge() {return age;}public void setAge(int age) {this.age = age;}public abstract void eat();
}

写接口Swim:

package oopInterface;public interface Swim {public abstract void swim();
}

写青蛙类,注意继承父类重写父类的抽象方法,注意实现游泳接口:

package oopInterface;public class Frog extends Animal implements Swim {public Frog() {super();}public Frog(String name, int age) {super(name, age);}@Overridepublic void swim() {System.out.println("青蛙在蛙泳。");}@Overridepublic void eat() {System.out.println("青蛙在吃虫子。");}
}

写狗类,注意继承父类重写父类的抽象方法,实现游泳接口:

package oopInterface;public class Dog extends Animal implements Swim {public Dog(){super();}public Dog(String name, int age) {super(name,age);}@Overridepublic void swim() {System.out.println("狗在狗刨。");}@Overridepublic void eat() {System.out.println("狗在吃骨头。");}
}

写兔子类,注意只需要继承父类重写抽象方法,不需要实现游泳接口(不会游泳):

package oopInterface;public class Rabbit extends Animal {public Rabbit() {}public Rabbit(String name, int age) {super(name, age);}@Overridepublic void eat() {System.out.println("兔子在吃胡萝卜。");}
}

写测试类。

package oopInterface;public class Test {public static void main(String[] args) {Frog f = new Frog("小绿",23);f.eat();f.swim();System.out.println(f.getName() + ", " + f.getAge());Dog d = new Dog("大D", 24);d.eat();d.swim();System.out.println(d.getName() + ", " + d.getAge());Rabbit r = new Rabbit("兔子", 30);r.eat();System.out.println(r.getName() + ", " + r.getAge());}
}

三、接口中成员的特点

  • 成员变量:接口中的成员变量只能是常量,默认使用 public static final 修饰(就是不写也自动认为是这样)。
  • 构造方法:接口没有构造方法。
  • 成员方法:JDK7以前只能是抽象方法,默认修饰符为 public abstract;JDK8以后,接口中可以定义有方法体的方法;JDK9以后,接口中可以定义私有方法。

四、接口和类之间的关系

  • 类和类的关系:继承关系——只能单继承,不能多继承,但可以多层继承。
  • 类和接口的关系:实现关系——可以单实现,也可以多实现,还可以在继承一个类的同时实现多个接口。
  • 接口和接口的关系:继承关系——可以单继承,也可以多继承。

注意:
1.类在实现接口时,要么实现接口中所有的抽象方法,要么这个类本身也是一个抽象类。
2.类可以多实现接口,如果多实现,需要把所有要实现接口的抽象方法都实现。
3.接口可以多继承,如果一个子接口继承了多个接口,然后被一个实现类实现,那么这个实现类就要把这个子接口和他的所有父接口中的所有抽象方法全部实现。

练习:编写带有接口和抽象类的标准Javabean类。

乒乓球运动员:姓名,年龄,学打乒乓球,说英语
篮球运动员:姓名,年龄,学打篮球
乒乓球教练:姓名,年龄,教打乒乓球,说英语
篮球教练:姓名,年龄,教打篮球
//Person类
package oopInterExp;//因为直接创建顶层父类人的对象是没有意义的
//所以将其写为抽象类
public abstract class Person {private String name;private int age;public Person(String name, int age) {this.name = name;this.age = age;}public Person() {}public String getName() {return name;}public void setName(String name) {this.name = name;}public int getAge() {return age;}public void setAge(int age) {this.age = age;}
}
//Sporter类继承Person
package oopInterExp;public abstract class Sporter extends Person {public Sporter(String name, int age) {super(name, age);}public Sporter() {}public abstract void learn();
}
//Coach类继承Person
package oopInterExp;public abstract class Coach extends Person {public Coach() {}public Coach(String name, int age) {super(name, age);}public abstract void teach();
}
//SpeakEnglish接口
package oopInterExp;public interface SpeakEnglishInter {public abstract void speakEnglish();
}
//PingPongSporter继承Sporter,实现SpeakEnglish
package oopInterExp;public class PingPongSporter extends Sporter implements SpeakEnglishInter {public PingPongSporter(String name, int age) {super(name, age);}public PingPongSporter() {}@Overridepublic void learn() {System.out.println("学习乒乓球。");}@Overridepublic void speakEnglish() {System.out.println("乒乓球运动员在说英语。");}
}
//PingPongCoach继承Coach,实现SpeakEnglish
package oopInterExp;public class PingPongCoach extends Coach implements SpeakEnglishInter {public PingPongCoach() {}public PingPongCoach(String name, int age) {super(name, age);}@Overridepublic void teach() {System.out.println("教乒乓球。");}@Overridepublic void speakEnglish() {System.out.println("乒乓球教练在说英语。");}
}
//BasketballSporter继承Sporter
package oopInterExp;public class BasketballSporter extends Sporter {public BasketballSporter(String name, int age) {super(name, age);}public BasketballSporter() {}public void learn() {System.out.println("学篮球。");}
}
//BasketballCoach继承Coach
package oopInterExp;public class BasketballCoach extends Coach {public BasketballCoach() {}public BasketballCoach(String name, int age) {super(name, age);}public void teach() {System.out.println("教篮球。");}
}

五、接口中新增的方法

5.1 JDK8开始接口中新增的方法

        JDK7 以前,接口中只能定义抽象方法。
        JDK8新增的特性是:接口中可以定义有方法体的方法(可以定义默认方法或静态方法)。
        JDK9新增的特性是:接口中可以定义私有方法。

5.1.1 接口中的默认方法

        接口中定义有方法体的方法,主要是为了接口升级考虑的,接口不可能是一成不变的,需要往里面添加新的方法来升级,如果这些方法都是抽象方法,此时,实现类中就需要同时也实现这些方法,非常麻烦且不容易同步;倘若升级使用的是有方法体的方法,那么实现类就不需要额外进行修改了,如果需要修改,也可以利用重写进行修改。

  • 在接口中定义默认方法,需要使用关键字 default 修饰。
  • 格式:public default 返回值类型 方法名(参数列表) { }
  • 范例:public default void show() { }
  • 默认方法不是抽象方法,不强制需要被重写。但是如果被重写,重写的时候要去掉 default 关键字。
  • public 可以省略,但是 default 不可以省略。
  • 如果实现了多个接口,多个接口中存在相同名字的默认方法,那么子类就必须对该方法进行重写了(不重写会引起冲突)。

接口Inter1:

package oopInterface5;public interface Inter1 {public abstract void method();public default void default_method() {System.out.println("Inter1接口中的默认方法");}
}

接口Inter2:

package oopInterface5;public interface Inter2 {public default void default_method() {System.out.println("Inter2接口中的默认方法");}
}

两个默认方法同名,如果实现类同时实现这俩接口,一定需要重写这个默认方法!

package oopInterface5;public class InterImpl implements Inter1, Inter2 {@Overridepublic void method() {System.out.println("抽象方法的实现");}@Overridepublic void default_method() {System.out.println("重写接口中的默认方法");}
}

测试类:

package oopInterface5;public class Test {public static void main(String[] args) {InterImpl ii = new InterImpl();ii.method();				//抽象方法的实现ii.default_method();		//重写接口中的默认方法}
}
5.1.2 接口中的静态方法

        JDK8 以后允许在接口中定义静态方法,需要用 static 修饰。
        接口中静态方法的定义格式为:

  • public static 返回值类型 方法名(参数列表) { }
  • 范例:public static void show() { }

        接口中静态方法的注意事项:

  • 静态方法只能通过接口名调用,不能通过实现类名或对象名调用。
  • public 可以省略,static 不能省略。

写一个接口:

package oopInterface6;public interface Inter {public abstract void method();public static void static_method() {System.out.println("接口中的静态方法");}
}

写一个实现类,类里面还有一个静态方法,与接口里面的方法同名,但这不是重写,因为静态方法是不能被重写的:

package oopInterface6;public class InteImpl implements Inter {@Overridepublic void method() {System.out.println("重写接口中的抽象方法");}//这不叫重写public static void static_method() {System.out.println("我不是重写的Inter接口中的静态方法");}
}

但其实,二者是不同的方法。

package oopInterface6;public class Test {public static void main(String[] args) {InteImpl ii = new InteImpl();ii.method();						  //重写接口中的抽象方法Inter.static_method();               //调用接口中的静态方法InteImpl.static_method();           //调用实现类中的一个同名的静态方法}
}

5.2 JDK9 开始接口中新增的方法

5.2.1 在接口中定义私有方法
  • 格式1:private 返回值类型 方法名(参数列表) { }
  • 范例1:private void show() { }
  • 用法:给默认方法服务。
package oopInterface7;public interface InterA {public default void show1() {System.out.println("show1开始执行");show3();}public default void show2() {System.out.println("show2开始执行");show3();}//普通的私有方法,给默认方法服务的private void show3() {System.out.println("记录程序在运行过程中的各种细节,这里有100行代码。");}
}
  • 格式2:private static 返回值类型 方法名(参数列表) { }
  • 范例2:private static void method() { }
  • 用法:给静态方法服务。
package oopInterface7;public interface InterB {public static void show1() {System.out.println("show1开始执行");show3();}public static void show2() {System.out.println("show2开始执行");show3();}//普通的私有方法,给静态方法服务的private static void show3() {System.out.println("记录程序在运行过程中的各种细节,这里有100行代码。");}
}

六、接口的应用

1.接口代表规则,是行为的抽象。想要让哪个类拥有一个行为,就让这个类实现对应的接口就可以了。
2.当一个方法的参数是接口时,可以传递接口所有实现类的对象,这种方式称之为接口多态。

七、适配器设计模式

  • 设计模式(Design Pattern) 是一套被反复使用、多数人知晓的、经过分类编目的、代码设计经验的总结。使用设计模式是为了可重用代码、让代码更容易被他人理解、保证代码可靠性、程序的重用性。

        适配器可以用来简化代码,避免因为接口中抽象方法过多,而我们只需要使用其中一部分的时候造成的不便。
        书写步骤一般为:
1.编写中间类XXXAdapter,实现对应的接口。
2.对接口中的抽象方法进行空实现。
3.让真正的实现类继承中间类,并重写需要用的方法。
4.为了避免其他类去创建适配器类的对象,中间的适配器类用 abstract 修饰。

接口:

package AdapterDesignPattern;public interface Inter {public abstract void method1();public abstract void method2();public abstract void method3();public abstract void method4();public abstract void method5();
}

适配器类:

package AdapterDesignPattern;public abstract class InterAdapter implements Inter {@Overridepublic void method1() {}@Overridepublic void method2() {}@Overridepublic void method3() {}@Overridepublic void method4() {}@Overridepublic void method5() {}
}

实现类:

package AdapterDesignPattern;public class InterImpl extends InterAdapter {//我需要用到哪个方法,就重写哪个方法就可以了@Overridepublic void method5() {System.out.println("只要用第五个方法");}
}

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

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

相关文章

Pandas实战指南:any()函数深度解析与高效应用

Pandas实战指南:any()函数深度解析与高效应用 引言 在数据分析和处理过程中,经常需要快速检查数据集中是否存在满足特定条件的元素。Pandas库中的any()函数正是这样一个强大的工具,它可以帮助我们沿着指定的轴检查是否至少有一个元素满足某…

Transformer重要论文与书籍 - Transformer教程

近年来,人工智能领域中的Transformer模型无疑成为了炙手可热的研究对象。从自然语言处理(NLP)到计算机视觉,Transformer展现出了前所未有的强大能力。今天,我们将探讨Tra在当今的人工智能和机器学习领域,Tr…

路由守卫中使用next()跳转到指定路径时会无限循环

路由守卫钩子介绍 const router new VueRouter({ ... }) // 导航路由变化时触发路由守卫钩子 router.beforeEach((to, from, next) > {// ... }) to: Route: 即将要进入的目标路由对象(到哪去)from: Route: 当前导航正要离开的路由(从哪来)next: Function(必须&#xff0…

axios使用sm2加密数据后请求参数多了双引号解决方法

axios使用sm2加密数据后请求参数多了双引号解决 背景问题描述解决过程 背景 因项目安全要求,需对传给后端的入参加密,将请求参数加密后再传给后端 前期将axios降低到1.6.7后解决了问题,但最近axios有漏洞,安全要求对版本升级&…

从零开始[进阶版]深入学习图像分类:使用Python和TensorFlow

引言 图像分类是计算机视觉中的一个核心任务,广泛应用于人脸识别、自动驾驶、医疗影像分析等领域。在本篇文章中,我们将深入探讨图像分类的原理和实现,使用Python和TensorFlow搭建一个完整的图像分类系统。本文不仅适合初学者,也…

【Qt 初识 Test】用图形化和代码的方式实现简单的Qt程序

文章目录 1. 通过图形化的方式实现🍎2. 通过代码的方式实现 1. 通过图形化的方式实现🍎 在界面创建出一个控件,显示 hello world,通过拖拽的方式实现; widget.ui文件如下:🔍 生成的 ui_widget.…

生物环保技术有哪些缺点或者局限性呢

生物环保技术,作为一种利用生物学原理和技术来处理环境污染的方法,虽然具有绿色环保、高效节能等优点,但也存在一些缺点和局限性。以下是对这些缺点和局限性的详细分析: 一、受环境因素影响大 生物环保技术的效果往往受到环境因…

数据结构第18节 散列表 - 应用

散列表(Hash Table),也被称为哈希表,是一种数据结构,它通过使用哈希函数将键映射到数组的某个位置来实现快速查找。散列表通常提供平均时间复杂度为O(1)的查找、插入和删除操作,这使得它们在处理大量数据时…

【mybatis】mybatisX插件概述

一、主要功能 智能补全与提示 MyBatisX 可以智能地提示和补全 SQL 语句中的关键字、表名、列名等信息,从而显著提高开发效率。代码生成器 虽然 MyBatisX 本身可能不直接提供一个完整的、独立的代码生成器,但它可能集成了或支持与其他代码生成工具&#…

卤味江湖中,周黑鸭究竟该抓住什么赛点?

近年来,卤味江湖的决斗从未停止。 随着休闲卤味、佐餐卤味等细分赛道逐渐形成,“卤味三巨头”(周黑鸭、绝味食品、煌上煌)的牌桌上有了更多新对手,赛道变挤了,“周黑鸭们”也到了转型关键期。 这个夏天&a…

MySQL字符串相关数据处理函数

目录 1. 转大小写 2. 截取字符串 sunstr 3. 获取字符长度 4. 字符串拼接 concat 5. 去掉空白 trim 1. 转大小写 转大写:upper() 转小写:lower() 虽然MySQL不严格区分大小写,但是我们还是需要掌握这种大小写的操作以方便学习其他…

python的入门知识(下)

目录 学习内容数字字符串、列表和元组映射和集合类型 学习内容 数字 长整型(Long Integer): 在Python中,整数没有大小限制,但是可以用大写或小写的L来表示长整型,尽管这不是Python 3推荐的做法。 复数(Co…

Nessus相关

tenable 1 安装nessus scanner 1 )安装nessus scanner: 方法一 curl -H X-Key: xxxxx https://cloud.tenable.com/install/scanner?namescanner-name&groupsscanner-group | bash方法二: **# for ubuntu, its https://www.tenable.com/downloads/api/v1/pu…

【JavaScript脚本宇宙】JavaScript 库概览:数字、货币值、日期时间处理一网打尽

简化数据处理:掌握六大 JavaScript 库的核心功能和使用技巧 前言 在现代的软件开发中,处理数字、货币和日期时间是非常常见的需求。为了简化这些任务,开发人员可以使用各种 JavaScript 库来轻松地进行数字格式化、货币计算和日期时间操作。…

Google登录时人机身份验证的图片类型和通过的经验建议,以及一些常见问题

很多朋友在登录谷歌账号时,都遇到过要求人机身份验证的步骤,而且有一些时候人机身份验证这个步骤很让人纠结,甚至压根就出不来具体的验证图片,或者花了十几分钟、几十分钟都过不去。 所以今天GG账号服务就来为您解析一下谷歌登录…

初学SpringMVC之接收请求参数及数据回显

pom.xml 文件导入 lombok 的依赖 <dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId><version>1.18.34</version></dependency> Controller 表示这是一个控制器 RequestParam 表示从前端接收…

夏日智启:我的Datawhale AI夏令营探索之旅

前言 最近几年&#xff0c;AI&#xff08;人工智能&#xff09;的发展呈现出了前所未有的迅猛势头&#xff0c;其影响力和应用范围不断扩大&#xff0c;深刻地改变着我们的生活、工作和社会结构。尤其是AI大模型技术&#xff0c;国内外可谓是“百模大战”&#xff0c;百舸争流…

github恢复码怎么备份

https://docs.github.com/zh/authentication/securing-your-account-with-two-factor-authentication-2fa/configuring-two-factor-authentication-recovery-methods

最强文本编辑器 VIM 指令大全

Vim 是从 Vi 编辑器发展出来的一款极其强大的文本编辑器&#xff0c;它保留了 Vi 编辑器的所有功能&#xff0c;并添加了许多新特性。Vim 具有代码补全、语法高亮、错误跳转、批量化处理等编辑功能&#xff0c;还支持异常丰富的插件扩展&#xff0c;且整个编辑全程可通过键盘完…

谷歌插件之一键关闭同域名页面

欢迎来到我的博客&#xff0c;代码的世界里&#xff0c;每一行都是一个故事 &#x1f38f;&#xff1a;你只管努力&#xff0c;剩下的交给时间 &#x1f3e0; &#xff1a;小破站 谷歌插件之一键关闭同域名页面 前言项目结构mainfest.jsonbackgroud.js 项目实现效果展示展望 前…