首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >【13】JAVASE-面向对象-接口【从零开始学JAVA】

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

作者头像
用户4919348
发布于 2024-05-25 06:04:16
发布于 2024-05-25 06:04:16
13900
代码可运行
举报
文章被收录于专栏:波波烤鸭波波烤鸭
运行总次数:0
代码可运行

Java零基础系列课程-JavaSE基础篇

Lecture:波哥

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

七、接口

1.生活中的接口

生活中的接口的特点:

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

2.Java中的接口

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

语法规则

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
关键字 接口名{
    常量;
    抽象方法;
}

interface 接口名{
    ....
}

案例代码:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
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.接口的特点

3.1 接口使用interface关键字
3.2 接口由常量和抽象方法组成

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

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

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

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

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

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

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
/**
 * 创建的Person类实现 InterfaceDemo01接口
 * 
 * @author dpb
 *
 */
 class Person implements InterfaceDemo01{

	@Override
	public void eat() {
		System.out.println("Person ... eat");
		
	}
	
}

接口实现类的特点:

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

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

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
/**
  * 子类不想实现父接口中定义的抽象方法那么可以定义本身为一个接口,
  * 然后通过 extends 继承父接口的所有的抽象方法和常量
  * @author dpb
  *
  */
 interface Student extends InterfaceDemo01{
	 
 }
 
 abstract class User implements InterfaceDemo01{
	 
 }
3.4 接口可以多实现

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

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
package com.bobo.oop02;

public interface Person {
	
	public void sleep();

}
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
package com.bobo.oop02;

public interface Police extends Person {

	public void zhuxiaotou();
}
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
package com.bobo.oop02;

public interface Student extends Person{

	public void study();
}
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
package com.bobo.oop02;

public class User implements Student,Police{

	@Override
	public void sleep() {
		// TODO Auto-generated method stub
		
	}

	@Override
	public void zhuxiaotou() {
		// TODO Auto-generated method stub
		
	}

	@Override
	public 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,照相机,手机对象,让人使用这些对象

案例代码

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
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{

	@Override
	public void dailup() {
		System.out.println("电话拨号...");
	}

}

// 定义一个Dvd类有播放功能。 
public class Dvd implements IPlay{

	
	@Override
	public void play() {
		System.out.println("DVD播放功能");
		
	}

}

// 定义一个照相机类 Camera, 有照相功能。
public class Camera implements ITakePhone{

	@Override
	public void takePhone() {
		// TODO Auto-generated method stub
		System.out.println("照相机拍照...");
	}

}

// 定义一个手机类 Mobile, 有拨号,拍照,播放功能。 
public class Mobile implements IMobile{

	@Override
	public void dailup() {
		System.out.println("手机拨号");
		
	}

	@Override
	public void play() {
		// TODO Auto-generated method stub
		System.out.println("手机播放");
	}

	@Override
	public void takePhone() {
		// TODO Auto-generated method stub
		System.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 {

	@Override
	public void use(IDailup dailup) {
		dailup.dailup();
		
	}

	@Override
	public void use(IPlay play) {
		play.play();
		
	}

	@Override
	public void use(ITakePhone takePhone) {
		takePhone.takePhone();
		
	}

	@Override
	public 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();
		// Dvd
		IPlay 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 引用类型

普通类

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

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
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");
	}
}

抽象类

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

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
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 stub
				System.out.println("好好学习,天天向上....run");
			}
		};
		// 抽象类不能被实例化的原因是因为有没有被实现的抽象方法
		// 那么既然是这样的话。那么我们就来实现抽象类中的抽象方法即可
		// AbsStudent1 s1 = new AbsStudent1(){};
		p.run(stu2);
		
		p.run(new AbsStudent(){
			
			public void study() {
				// TODO Auto-generated method stub
				System.out.println("好好学习,天天向上....run 666");
			}
		});
	}

}

/**
 * 定义了一个抽象类
 * @author dpb
 *
 */
abstract class AbsStudent{
	public abstract void study();
}

abstract class AbsStudent1{
	
}

class Student extends AbsStudent{

	@Override
	public 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");
	}
}

接口

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

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
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(){

			@Override
			public void study() {
				// TODO Auto-generated method stub
				System.out.println("好好学习,天天向上....接口");
			}
			
		};
		p.run(stu2);
		p.run(new IStudent(){

			@Override
			public void study() {
				// TODO Auto-generated method stub
				System.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 引用类型

普通类

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

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
package com.bobo.oop07;

public class OOPDemo01 {

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		Student 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;
	}
}

抽象类

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

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
package com.bobo.oop08;

public class OOPDemo01 {

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		Student 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的问题,也就是强制类型转换的问题。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
package com.bobo.oop09;

public class OOPDemo01 {

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		Student 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(){};
	}
}

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

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
interface IPerson{
	IPerson sleep();
	IPerson run();
	IPerson eat();
}

class Person implements IPerson{

	@Override
	public IPerson sleep() {
		// TODO Auto-generated method stub
		return this;
	}

	@Override
	public IPerson run() {
		// TODO Auto-generated method stub
		return this;
	}

	@Override
	public IPerson eat() {
		// TODO Auto-generated method stub
		return this;
	}
	
}

	public static void main(String[] args) {
		IPerson p1 = s.study();
		// 链式调用
		IPerson p5 = p1.eat().sleep().run().eat().run().sleep();
	}
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2024-05-24,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
Python3 与 C# 基础语法对比(Function专栏)
汇总系列:https://www.cnblogs.com/dunitian/p/4822808.html#ai
逸鹏
2018/06/13
6540
Python3 与 C# 基础语法对比(Function专栏)
Python3 与 C# 基础语法对比(String专栏-新排版)
在线编程:https://mybinder.org/v2/gh/lotapp/BaseCode/master
逸鹏
2018/07/23
1.8K0
Python3 与 C# 基础语法对比(String专栏-新排版)
Python3 与 C# 基础语法对比(新排版)
VSCode设置python3的开发环境(linux下默认是python2)https://www.cnblogs.com/dotnetcrazy/p/9095793.html
逸鹏
2018/07/23
1.4K0
Python3 与 C# 基础语法对比(新排版)
Python基础笔记3
要调用一个函数,需要知道函数的名称和参数,比如求绝对值的函数abs,只有一个参数。可以直接从Python的官方网站查看文档:
py3study
2020/01/03
4600
python基础教程:函数(2)
上一节我们学习了函数的定义和调用,理解了基本的函数知识。本节进一步学习函数相关的更多内容,深入了解函数,包括:默认参数、关键字参数、位置参数、变量的作用域等等。
一墨编程学习
2019/05/15
7780
Python学习笔记一(基础知识)
本文是小编自己学习Python的学习笔记,本着简介方便的原则,记录Python的主要基础知识点,以便学习和回顾。
全栈程序员站长
2022/07/05
3410
Python3 与 C# 扩展之~基础衍生
在线编程: https://mybinder.org/v2/gh/lotapp/BaseCode/master
逸鹏
2018/07/08
2K0
Python3 与 C# 扩展之~基础衍生
Python 函数(一)
函数是组织好的,可重复使用的,用来实现单一,或相关联功能的代码段;通过函数,可以对特定功能的代码进行封装,实现代码的复用。
AiDBA宝典
2022/02/22
5920
【Python从入门到精通】(十一)Python的函数的方方面面【收藏下来保证有用!!!】
您好,我是码农飞哥,感谢您阅读本文,欢迎一键三连哦。本文主要介绍Python的函数,函数的定义,使用,可变参数等等都有详细介绍。 干货满满,建议收藏,需要用到时常看看。小伙伴们如有问题及需要,欢迎踊跃留言哦~ ~ ~。
码农飞哥
2021/08/18
5360
【AICAMP —— Python】入门系列!(3. Python函数编程)
Python与其它编程语言一样,可以直接调用我们写好的函数,或者已经实现的函数。如我们可以使用系统自带的函数,求一个数的绝对值,使用abs函数,对其传入参数,得到输出。
灿视学长
2021/05/28
5760
7-函数
当存在多个默认参数的时候,调用的时候,既可以按顺序提供默认参数,比如调用enroll('Bob', 'M', 7),意思是,除了name,gender这两个参数外,最后1个参数应用在参数age上,city参数由于没有提供,仍然使用默认值。
用户3106371
2019/03/11
8490
7-函数
Python基础入门_4函数
第四篇内容,这次介绍下函数的基本用法,包括函数的定义、参数的类型、匿名函数、变量作用域以及从模块导入函数的方法,目录如下所示:
kbsc13
2019/08/16
1.2K0
Python基础语法
https://www.liaoxuefeng.com/wiki/0014316089557264a6b348958f449949df42a6d3a2e542c000
六月的雨
2020/03/27
4520
Python3 与 C# 扩展之~装饰器专栏
终于期末考试结束了,聪明的小明同学现在当然是美滋滋的过暑假了,左手一只瓜,右手一本书~正在给老乡小张同学拓展他研究多日的知识点
逸鹏
2018/07/23
1.1K0
Python3 与 C# 基础语法对比(List、Tuple、Dict、Set专栏-新排版)
在线预览:http://github.lesschina.com/python/base/pop/3.listtupledict_set.html
逸鹏
2018/07/23
3.4K0
Python3 与 C# 基础语法对比(List、Tuple、Dict、Set专栏-新排版)
浅析Python函数的参数
Python的函数定义非常简单,但灵活度却非常大。除了正常定义的必选参数外,还可以使用默认参数、可变参数和关键字参数,使得函数定义出来的接口,不但能处理复杂的参数,还可以简化调用者的代码。
Go进阶者
2021/03/08
6760
浅析Python函数的参数
Python 函数
定义函数 在 Python 中,定义一个函数要使用 def 语句,依次写出函数名、括号、括号中的参数和冒号:,然后,在缩进块中编写函数体,函数的返回值用 return 语句返回。 我们以自定义一个求绝对值的 my_abs 函数为例: 12345 def my_abs(x): if x >= 0: return x else: return -x 如果没有 return 语句,函数执行完毕后也会返回结果,只是结果为 None。 return None 可以简写为
一份执着✘
2018/06/04
1.5K0
Python 基础知识学习
这里只列举一些Python与Java和JavaScript不一样的地方,如果你有任何语言基础,相信看完这篇文章就可以轻松写Python程序。
李振
2021/11/26
5790
Python 基础知识学习
Python学习笔记(二)·函数
当代码出现有规律的重复的时候,你就需要当心了,每次写3.14 * x * x不仅很麻烦,而且,如果要把3.14改成3.14159265359的时候,得全部替换。
公爵
2022/09/28
1.9K0
Python学习笔记(二)·函数
写给.NET开发者看的Python3上手指南系列(1):Python3与C# 基础语法对比
由于 Python 在数据科学和机器学习、深度学习中有广泛应用,作为.NET开发者,大家将来或许需要将 Python 构建的项迁移到 ML.NET或TensorFlow.NET 上来,于是快速掌握 Python 有利于快速把握项目并提供迁移效率。
Enjoy233
2019/10/22
1.7K0
写给.NET开发者看的Python3上手指南系列(1):Python3与C# 基础语法对比
相关推荐
Python3 与 C# 基础语法对比(Function专栏)
更多 >
交个朋友
加入腾讯云官网粉丝站
双11活动抢先看 更有社群专属礼券掉落
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档