java学习笔记-什么是接口

本文通过实例解释了面向对象编程中接口的概念,展示了如何利用接口实现多继承和多态,以及解决实际编程问题。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

接口(interface)是一个比类更加抽象的概念,没接触过面向对象编程(OOP)的人第一眼看代码通常都会懵逼。


如果说类是同一种类似事物的集合,那么接口就是拥有共同特征的一些东西的集合。这些东西可以不是同一种。


打个比方,鸟和飞机都会飞,但是它们显然不是同一种东西,鸟属于动物类的子类,飞机属于交通工具的子类,它们之间根本没任何继承关系,但是“会飞”就是个接口,可以描述它们之间的共性。


用代码描述就是这样:


interface Flyable{
	void fly();
}

class Bird extends Animal implements Flyable{
	public void fly() {
		//扇翅膀
	}
}

class Plane extends Traffic implements Flyable{
	public void fly() {
		//发动引擎
		//助推
		//滑行
		//升空
	}
}

interface可以看作一个全是抽象的类,里面只有public abstract方法,这很好理解:当你描述一个公共的特征或者一个行为时,如果它是不可见的(private)那就没有任何意义了。


为什么是abstract呢?用这个例子,“会飞”仅仅是描述了一种共性,但是具体这东西怎么飞,大家各有各的飞法,当然就只能抽象了。当你实现这个接口时,必须重写这个抽象的方法。



再举个例子,比如我家里有水果刀,可以切水果;有剪刀,可以剪纸;有开瓶器,可以开酒瓶。还有个瑞士军刀,可以做上面一切的事情。我应该怎么抽象这些东西呢?


如果不使用接口,我们就只能这样:


class Knives{
	public void chopFruits() {
		//切水果
	}
}

class Scissors{
	public void cutPaper() {
		//剪纸
	}
}

class Corkscrews{
	public void openBottle() {
		//开瓶盖
	}
}

class SwissArmyKnives extends Knives{
	@Override public void chopFruits() {
		
		//重写切水果
	}
}

public class House {

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		Knives knife = new Knives();
		knife.chopFruits();
		Scissors scissor = new Scissors();
		scissor.cutPaper();
		Corkscrews corkscrew = new Corkscrews();
		corkscrew.openBottle();
		Knives sak = new SwissArmyKnives();//多态
		sak.chopFruits(); 

	}

}


然后就发现问题了。瑞士军刀也能切水果,那么它是刀子的子类咯?然后瑞士军刀还能干别的呀?怎么办,子类再加两个新的方法:cutPaper和openBottle?


这样抽象,不觉得别扭么?假如我要修改一下剪纸这个方法传入的参数,我是不是两个地方都得改,假如忘记了改瑞士军刀的,是不是程序就挂了?要知道java不允许多继承,瑞士军刀不能既是刀子的子类又是剪刀的子类。


那么假如我抽象一个工具类,里面提供了“切水果”“剪纸”“开瓶盖”三个抽象方法,那么问题又来了,继承抽象类工具时,如果不把这三个方法都实现,就会报错!怎么办?



interface Chopable{
	void chopFruits();
}

interface Cutable{
	void cutPaper();
	
	void cutRope();  //新增一个剪绳子方法
}

interface CanOpen{
	void openBottle();
}

class Knives implements Chopable{
	public void chopFruits() {
		//切水果
	}
}

class Scissors implements Cutable{
	public void cutPaper() {
		//剪纸
	}
	
	public void cutRope() {
		
	}
}

class Corkscrews implements CanOpen{
	public void openBottle() {
		//开瓶盖
	}
}

class SwissArmyKnives implements Cutable, Chopable, CanOpen{
	@Override public void chopFruits() {
		
		//重写切水果
	}
	
	@Override public void cutPaper() {
		
		
	}
	
	@Override public void cutRope() {
		
		
	}
	
	@Override public void openBottle() {
		
		
	}	
}

public class House {

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		Chopable knife = new Knives();
		knife.chopFruits();
		Cutable scissor = new Scissors();
		scissor.cutPaper();
		CanOpen corkscrew = new Corkscrews();
		corkscrew.openBottle();
		Chopable sak = new SwissArmyKnives();//多态
		sak.chopFruits(); 
		((Cutable) sak).cutPaper();  //不推荐这么做 
		((CanOpen) sak).openBottle();//不推荐这么做 

	}

}

利用接口,我们抽象出了三种特征:“能切”“能剪”“能开瓶”

水果刀和瑞士军刀同时符合能切的特征,它们都实现了切水果功能。

瑞士军刀同时实现了这三个接口,也就是说从三个不同的角度看过去,瑞士军刀是分别拥有三种功能的东西,至于剩下部分是什么样我们并不关心,我们只是想找个顺手的工具来切水果罢了。

同样的,如果我们要给能剪接口加一个方法,比如剪书,剪绳子,剪头发,又或者是改变剪纸的传入参数(极度不推荐这么做,改动旧的方法通常会造成别人或自己的程序报错,应该重载此方法,相当于新增了一个方法)我们需要在改动接口的同时一起修改剪刀类和瑞士军刀类的实现,这样保证了接口的一致性,不会出现改了半拉漏了半拉的情况。

接口通过这种方式,实现了多继承和多态。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值