【13】JAVASE-面向对象-接口【从零开始学JAVA】

news/2024/9/22 23:48:04/

JavaJavaSE_0">Java零基础系列课程-JavaSE基础篇

Lecture:波哥

在这里插入图片描述

  Java 是第一大编程语言和开发平台。它有助于企业降低成本、缩短开发周期、推动创新以及改善应用服务。如今全球有数百万开发人员运行着超过 51 亿个 Java 虚拟机,Java 仍是企业和开发人员的首选开发平台。

七、接口

1.生活中的接口

生活中的接口的特点:

  1. 接口是可以扩展功能的
  2. 接口是一种规范,一种标准
  3. 接口是灵活

在这里插入图片描述

Java_28">2.Java中的接口

接口是抽象方法和常量的集合,JDK1.8之后接口中可以包含静态方法和默认方法。

语法规则

关键字 接口{常量;抽象方法;
}interface 接口{....
}

案例代码:

package com.bobo.oop01;public class OOPDemo03 {/*** 接口* @param args*/public static void main(String[] args) {// 接口是不能被实例化的// InterfaceDemo01 d = new InterfaceDemo01() ;// InterfaceDemo01.NAME = "aaa";}}
// 第一个接口案例  常量和抽象方法的集合
interface InterfaceDemo01{// 静态常量  可以省略 static和final关键字public static final String NAME= "张三";// 抽象方法 可以省略abstract关键字public  void eat();/*** 在JDK1.8之后可以在接口中声明静态方法*/public static void sleep(){System.out.println("sleep ... ");}/*** 在JDK1.8之后可以在接口中声明 default方法*/default void run(){System.out.println("run .... ");}
}

3.接口的特点

interface_93">3.1 接口使用interface关键字

3.2 接口由常量和抽象方法组成

常量:默认接口中所有的成员的变量都是省略 public static final 这几个关键字的,一般接口的成员变量都是大写的

抽象方法:默认接口中的所有成员方法都是省略 public abstract的

在这里我们建议大家在写的时候都加上

JDK1.8之后增加的 静态方法和default方法也要注意

在这里插入图片描述

3.3 接口不能实例化,得通过实现类来实现

接口中存在抽象方法,那就表明接口本身也是一个抽象类,所以肯定不能被实例化,那么此时我们只能通过接口的实现类来实现,要实现接口的实现类我们要通过 Implements 关键字来实现

/*** 创建的Person类实现 InterfaceDemo01接口* * @author dpb**/class Person implements InterfaceDemo01{@Overridepublic void eat() {System.out.println("Person ... eat");}}

接口实现类的特点:

a. 如果一个类实现了接口,那么该类就必须实现接口中定义的所有的抽象方法

b. 如果一个接口不想实现接口的方法,那么子类必须定义为一个接口或者抽象类

/*** 子类不想实现父接口中定义的抽象方法那么可以定义本身为一个接口,* 然后通过 extends 继承父接口的所有的抽象方法和常量* @author dpb**/interface Student extends InterfaceDemo01{}abstract class User implements InterfaceDemo01{}

3.4 接口可以多实现

相比较继承的单继承而言,接口在这方面就显得很灵活,支持多实现

package com.bobo.oop02;public interface Person {public void sleep();}
package com.bobo.oop02;public interface Police extends Person {public void zhuxiaotou();
}
package com.bobo.oop02;public interface Student extends Person{public void study();
}
package com.bobo.oop02;public class User implements Student,Police{@Overridepublic void sleep() {// TODO Auto-generated method stub}@Overridepublic void zhuxiaotou() {// TODO Auto-generated method stub}@Overridepublic void study() {// TODO Auto-generated method stub}}

3.5 接口是可以多继承的

此处要额外注意,在Java接口接口是可以多继承的!!!

在这里插入图片描述

3.6 接口是一种规范,标准

接口是一种规范,一种标准,同时接口也是灵活的。

3.7 类和接口的关系

类和类:单继承,不可以实现

类和接口:单继承,多实现

接口接口:多继承,不可以多现实

3.8 继承和接口的使用场景

当我们设计一个非常复杂而又无法实现的类的时候可以使用继承

当我们重新开始编写一些简单的功能或者指定一些标准的时候使用接口

开发中一般采用面向接口编程,抽象类是模板,接口是规范

4.接口和抽象类的对比

比较点抽象类接口
定义用abstract关键字来修饰的类interface关键字来修饰
组成抽象方法,普通方法,构造方法、成员变量,常量抽象方法,静态常量,JDK1.8注意
使用子类继承(extends)实现类实现(implements)
关系抽象类可以实现接口接口是不能继承抽象类的
对象都是通过对象的多态类实现的都是通过对象的多态类实现的
局限不能多继承,不能实例化可以多继承,不能实例化
选择建议选择接口,避免单继承建议选择接口,避免单继承
实际模板标准

5.课堂案例

要求如下:
(1) 所有的可以拨号的设备都应该有拨号功能 (Dailup)
(2) 所有的播放设备都可以有播放功能(Play)。
(3) 所有的照相设备都有拍照功能(takePhoto)。
(4) 定义一个电话类 Telephone,有拨号功能。
(5) 定义一个Dvd类有播放功能。
(6) 定义一个照相机类 Camera, 有照相功能。
(7) 定义一个手机类 Mobile, 有拨号,拍照,播放功能。
(8) 定义一个人类 Person, 有如下方法:
<1> 使用拨号设备 use (拨号设备)
<2> 使用拍照设备 use(拍照设备)
<3> 使用播放设备 use(播放设备)
<4> 使用拨号 播放 拍照设备 use(拨号播放拍照设备)
(9) 编写测试类Test 分别创建人,电话,Dvd,照相机,手机对象,让人使用这些对象

案例代码

public interface IDailup {/*** 拨号*/void dailup();}
public interface IPlay {/*** 播放*/void play();}public interface ITakePhone {/*** 拍照的功能*/void takePhone();}
public interface IMobile extends IDailup,IPlay,ITakePhone {}// 定义一个电话类 Telephone,有拨号功能。 
public class Telephone implements IDailup{@Overridepublic void dailup() {System.out.println("电话拨号...");}}// 定义一个Dvd类有播放功能。 
public class Dvd implements IPlay{@Overridepublic void play() {System.out.println("DVD播放功能");}}// 定义一个照相机类 Camera, 有照相功能。
public class Camera implements ITakePhone{@Overridepublic void takePhone() {// TODO Auto-generated method stubSystem.out.println("照相机拍照...");}}// 定义一个手机类 Mobile, 有拨号,拍照,播放功能。 
public class Mobile implements IMobile{@Overridepublic void dailup() {System.out.println("手机拨号");}@Overridepublic void play() {// TODO Auto-generated method stubSystem.out.println("手机播放");}@Overridepublic void takePhone() {// TODO Auto-generated method stubSystem.out.println("手机照相...");}}public interface IPerson {/*** <1> 使用拨号设备 use (拨号设备)*/void use(IDailup dailup);/*** <2> 使用拍照设备 use(拍照设备) * @param play*/void use(IPlay play);/*** <3> 使用播放设备 use(播放设备) * @param takePhone*/void use(ITakePhone takePhone);/*** <4> 使用拨号  播放  拍照设备 use(拨号播放拍照设备)* @param mobile*/void use(IMobile mobile);}public class Person implements IPerson {@Overridepublic void use(IDailup dailup) {dailup.dailup();}@Overridepublic void use(IPlay play) {play.play();}@Overridepublic void use(ITakePhone takePhone) {takePhone.takePhone();}@Overridepublic void use(IMobile mobile) {mobile.dailup();mobile.play();mobile.takePhone();}}public class OOPDemo01 {/*** 要求如下:   (1) 所有的可以拨号的设备都应该有拨号功能 (Dailup) (2) 所有的播放设备都可以有播放功能(Play)。 (3) 所有的照相设备都有拍照功能(takePhoto)。 (4) 定义一个电话类 Telephone,有拨号功能。 (5) 定义一个Dvd类有播放功能。 (6) 定义一个照相机类 Camera, 有照相功能。 (7) 定义一个手机类 Mobile, 有拨号,拍照,播放功能。 (8) 定义一个人类 Person, 有如下方法: <1> 使用拨号设备 use (拨号设备) <2> 使用拍照设备 use(拍照设备) <3> 使用播放设备 use(播放设备) <4> 使用拨号  播放  拍照设备 use(拨号播放拍照设备)(9) 编写测试类Test 分别创建人,电话,Dvd,照相机,手机对象,让人使用这些对象* @param args*/public static void main(String[] args) {IPerson person = new Person();// 电话IDailup telePhone = new Telephone();// DvdIPlay play = new Dvd();// 照相机ITakePhone takePhone = new Camera();// 手机对象IMobile mobile = new Mobile();person.use(telePhone);person.use(play);person.use(telePhone);System.out.println("----------");person.use(mobile);}}

6. 多态的应用

什么是多态:父类的引用指向了子类的实例

多态的实现方法:

  1. 使用父类作为方法的形参实现多态
  2. 使用父类作为方法的返回值实现多态

继承多态:当这个作为参数的父类是普通类或者抽象类时

接口多态:当这个作为参数的父类是一个接口时,构成接口多态

6.1 多态作为形参

6.1.1 基本数据类型

基本数据类型作为形参,就是我们讲的 值传递 这块没什么区别,也不涉及到多态

6.1.2 引用类型

普通类

​ 当一个形参希望我们传递的是一个普通类时,我们实际传递的是该类的对象/匿名对象

package com.bobo.oop04;public class OOPDemo01 {public static void main(String[] args) {Student stu = new Student();Person p = new Person();p.run(stu);System.out.println("*********");p.run(new Student());// 将匿名对象当做实参传递}}class Student{public void study(){System.out.println("好好学习,天天向上....");}
}class Person{public void run(Student stu){stu.study();System.out.println("person ... run");}
}

抽象类

​ 当一个形参希望我们传入的是一个抽象类时,我们实际上传入的是该类的子类对象/子类的匿名对象

package com.bobo.oop05;public class OOPDemo01 {public static void main(String[] args) {// 多态的体现AbsStudent stu = new Student();Person p = new Person();p.run(stu);System.out.println("*****1****");p.run(new Student());// 将匿名对象当做实参传递System.out.println("*****2****");AbsStudent stu2 = new AbsStudent(){public void study() {// TODO Auto-generated method stubSystem.out.println("好好学习,天天向上....run");}};// 抽象类不能被实例化的原因是因为有没有被实现的抽象方法// 那么既然是这样的话。那么我们就来实现抽象类中的抽象方法即可// AbsStudent1 s1 = new AbsStudent1(){};p.run(stu2);p.run(new AbsStudent(){public void study() {// TODO Auto-generated method stubSystem.out.println("好好学习,天天向上....run 666");}});}}/*** 定义了一个抽象类* @author dpb**/
abstract class AbsStudent{public abstract void study();
}abstract class AbsStudent1{}class Student extends AbsStudent{@Overridepublic void study() {System.out.println("好好学习,天天向上....");}}class Person{/*** 形参要求传递进来一个 抽象类型* * AbsStudent stu = new Student();* @param stu*/public void run(AbsStudent stu){stu.study();System.out.println("person ... run");}
}

接口

​ 当一个形参希望我们传入的是一个接口时,我们实际上传入的是该接口的实现类对象/实现类匿名对象

package com.bobo.oop06;public class OOPDemo01 {public static void main(String[] args) {IStudent stu = new Student();Person p = new Person();p.run(stu);System.out.println("*********");p.run(new Student());// 将匿名对象当做实参传递IStudent stu2 = new IStudent(){@Overridepublic void study() {// TODO Auto-generated method stubSystem.out.println("好好学习,天天向上....接口");}};p.run(stu2);p.run(new IStudent(){@Overridepublic void study() {// TODO Auto-generated method stubSystem.out.println("好好学习,天天向上....接口1");}});}}class Student implements IStudent{public void study(){System.out.println("好好学习,天天向上....");}
}interface IStudent{void study();
}class Person{public void run(IStudent stu){stu.study();System.out.println("person ... run");}
}

6.2 多态作为返回值

6.2.1 基本数据类型

基本数据类型作为返回值,就是我们讲的 值传递 这块没什么区别,也不涉及到多态

6.2.2 引用类型

普通类

​ 当一个方法的返回值是一个普通类,实际返回的就是该类的对象,我们可以使用该类的对象类接收

package com.bobo.oop07;public class OOPDemo01 {public static void main(String[] args) {// TODO Auto-generated method stubStudent s = new Student();Person p1 = s.study();Person p2 = s.eat();System.out.println(p1);System.out.println(p2);}}class Person{}class Student{public Person study(){return new Person();}public Person eat(){Person p = new Person();return p;}
}

抽象类

​ 当一个方法的返回值是一个抽象类时,实际返回的是该抽象类的子类对象,我们可以使用该抽象类接收。如果用该类的子类来接收那么就要考虑类型的强制转换问题

package com.bobo.oop08;public class OOPDemo01 {public static void main(String[] args) {// TODO Auto-generated method stubStudent s = new Student();AbsPerson p1 = s.study();AbsPerson p2 = s.eat();// 子类接收 父类的返回 那么需要强制类型转换Person p3 = (Person)s.study(); // 强制转换有可能出现 ClassCastException异常if(p2 instanceof Person){Person p4 = (Person)p2;}System.out.println(p1);System.out.println(p2);}}abstract class AbsPerson{}class Person extends AbsPerson{}class Student{public AbsPerson study(){return new Person();}public AbsPerson eat(){//AbsPerson p = new AbsPerson(){};return new AbsPerson(){};}
}

接口

​ 当一个方法的返回值是一个接口时,实际返回的是该接口的实现类对象,我们可以使用接口来接收,同样的如果我们使用实现类来接收的话,那么同样有可能出现ClassCastException的问题,也就是强制类型转换的问题。

package com.bobo.oop09;public class OOPDemo01 {public static void main(String[] args) {// TODO Auto-generated method stubStudent s = new Student();//  IPerson p1 = new Person();IPerson p1 = s.study();IPerson p2 = s.eat();// 子类接收 父类的返回 那么需要强制类型转换Person p3 = (Person)s.study(); // 强制转换有可能出现 ClassCastException异常if(p2 instanceof Person){Person p4 = (Person)p2;}System.out.println(p1);System.out.println(p2);}}interface IPerson{}class Person implements IPerson{}class Student{public IPerson study(){return new Person();}public IPerson eat(){//AbsPerson p = new AbsPerson(){};return new IPerson(){};}
}

补充:当方法的返回值类型是引用类型的时候,可以使用链式调用

interface IPerson{IPerson sleep();IPerson run();IPerson eat();
}class Person implements IPerson{@Overridepublic IPerson sleep() {// TODO Auto-generated method stubreturn this;}@Overridepublic IPerson run() {// TODO Auto-generated method stubreturn this;}@Overridepublic IPerson eat() {// TODO Auto-generated method stubreturn this;}}public static void main(String[] args) {IPerson p1 = s.study();// 链式调用IPerson p5 = p1.eat().sleep().run().eat().run().sleep();}

http://www.ppmy.cn/news/1441111.html

相关文章

HarmonyOS Next从入门到精通实战精品课

第一阶段&#xff1a;HarmonyOS Next星河版从入门到精通该阶段由HarmonyOS Next星河版本出发&#xff0c;介绍HarmonyOS Next版本应用开发基础概念&#xff0c;辅助学员快速上手新版本开发范式&#xff0c;共计42课时 第一天鸿蒙NEXT Mac版、Windows版【编辑器】和【模拟器】&a…

Postman,一个功能强大的API开发和测试工具

最近有小伙伴说在找 postman 的使用教程&#xff0c;案例等文章。 那么今天我就来写一个。 Postman 是一个功能强大的 API 开发和测试工具&#xff0c;它提供了丰富的功能&#xff0c;帮助开发人员更好地管理、测试和文档化 API。无论是单独开发还是团队协作&#xff0c;Postma…

UDP服务器的并发方案

概述&#xff1a;本文介绍udp的并发思路及代码实现 使用tcp协议可以使用listen bind accept为每一个客户端建立一个连接&#xff0c;实现并发 而udp是无连接的&#xff0c;如何响应多个客户端的请求实现并发呢&#xff1f; 最简单的办法就是模拟tcp&#xff0c;为每一个客…

K8S 哲学 - deployment -- kubectl【create 、 rollout 、edit、scale、set】

kubectl create kubectl rollout kubectl edit kubectl set kubectl scale 1、创建与配置文件解析 2、deploy 滚动更新 &#xff1a;template 里面的内容改变触发滚动更新 编辑该 deploy 的 配置文件 &#xff0c;加入一个 label 不会触发滚动更新 改变 nginx镜…

AI赋能分层模式,解构未来,智领风潮

​&#x1f308; 个人主页&#xff1a;danci_ &#x1f525; 系列专栏&#xff1a;《设计模式》 &#x1f4aa;&#x1f3fb; 制定明确可量化的目标&#xff0c;坚持默默的做事。 &#x1f680; 转载自热榜文章&#x1f525;&#xff1a;探索设计模式的魅力&#xff1a;AI赋能分…

【http】协议/域名/url/请求和响应/状态码/重定向

文章目录 0.应用层协议0.1HTTP协议 1.域名2.DNS3.访问浏览器4.URL搜索特殊字符如#&~ 5.万维网6.http请求和响应的格式6.1HTTP请求格式6.2HTTP响应格式6.3示例6.3模拟HTTP【框架】6.4查看请求或响应的工具FiddlerPostman 7.网页7.0对访问网页的认识7.1wget7.2新的认识7.3GET…

TLV61048非同步升压BOOST转换器输入电压2.6-5.5V输出电流4A输出电压最高15V

推荐原因&#xff1a; 输入电压较低&#xff0c;输出电流可达3.5A SOT23-6封装 批量价格约0.70元 TLV61048引脚 TLV61048引脚功能 7 详细说明 7.1 概述 TLV61048是一款非同步升压转换器&#xff0c;支持高达 15 V 的输出电压和输入范围从 2.61 V 到 5.5 V。该TLV61048集成了…

解决eureka服务注册名报错

解决eureka服务注册名报错 解决eureka服务注册名报错简介正文使用RestTemplate.getForObject( url&#xff0c;Class)方法中&#xff0c;url直接使用服务注册名进行拼接后无法正常远程调用。如下 报错404&#xff0c;说明没访问到我的解决方法&#xff1a;换依赖版本原来的版本…