前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >【13】JAVASE-面向对象-接口【从零开始学JAVA】

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

作者头像
用户4919348
发布2024-05-25 14:04:16
470
发布2024-05-25 14:04:16
举报
文章被收录于专栏:波波烤鸭波波烤鸭

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

Lecture:波哥

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

七、接口

1.生活中的接口

生活中的接口的特点:

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

2.Java中的接口

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

语法规则

代码语言:javascript
复制
关键字 接口名{
    常量;
    抽象方法;
}

interface 接口名{
    ....
}

案例代码:

代码语言:javascript
复制
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
复制
/**
 * 创建的Person类实现 InterfaceDemo01接口
 * 
 * @author dpb
 *
 */
 class Person implements InterfaceDemo01{

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

接口实现类的特点:

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

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

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

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

代码语言:javascript
复制
package com.bobo.oop02;

public interface Person {
	
	public void sleep();

}
代码语言:javascript
复制
package com.bobo.oop02;

public interface Police extends Person {

	public void zhuxiaotou();
}
代码语言:javascript
复制
package com.bobo.oop02;

public interface Student extends Person{

	public void study();
}
代码语言:javascript
复制
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
复制
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
复制
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
复制
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
复制
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
复制
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
复制
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
复制
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
复制
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 删除。

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

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • Java零基础系列课程-JavaSE基础篇
  • 七、接口
    • 1.生活中的接口
      • 2.Java中的接口
        • 3.接口的特点
          • 3.1 接口使用interface关键字
          • 3.2 接口由常量和抽象方法组成
          • 3.3 接口不能实例化,得通过实现类来实现
          • 3.4 接口可以多实现
          • 3.5 接口是可以多继承的
          • 3.6 接口是一种规范,标准
          • 3.7 类和接口的关系
          • 3.8 继承和接口的使用场景
        • 4.接口和抽象类的对比
          • 5.课堂案例
            • 6. 多态的应用
              • 6.1 多态作为形参
              • 6.2 多态作为返回值
          领券
          问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档