java面向对象21_接口(interface)

1.接口的概述

当抽象类中的方法都是抽象方法的时候,该抽象类可以用另外一种形式来定义和表示,那就是接口interface。接口和数组、类、抽象类是同一个层次的概念。

接口就是比“抽象类”还“抽象”的“抽象类”,可以更加规范的对子类进行约束。全面地专业地实现了:规范和具体实现的分离。

抽象类还提供某些具体实现,接口不提供任何实现,接口中所有方法都是抽象方法。接口是完全面向规范的,规定了一批类具有的公共方法规范。

从接口的实现者角度看,接口定义了可以向外部提供的服务。

从接口的调用者角度看,接口定义了实现者能提供那些服务。

接口是两个模块之间通信的标准,通信的规范。如果能把你要设计的系统之间模块之间的接口定义好,就相当于完成了系统的设计大纲,剩下的就是添砖加瓦的具体实现了。大家在工作以后,做系统时往往就是使用“面向接口”的思想来设计系统。

定义交通工具时,我定义一个抽象类Vehicle, 在定义子类Car、Plane、Train。没有问题。抽象类和子类是一种一般和特殊的关系。

接口呢,他和子类是实现规则的关系。比如:我定义一个接口Runnable,Car实现它就能在地上跑,Train实现也能在地上跑。飞机实现它也能在地上跑。就是说,如果他是交通工具,就一定能跑,一定要实现Runnable。我再定义接口:Fligntable,如果要在天上飞就一定要实现Flightable接口。

2.接口的定义

定义接口使用的关键字不是class,而是用interface来修饰。

【示例】接口的定义

interface 接口名 [extends 父接口1, 父接口2,] { 
	// 常量定义
	// 方法定义
}

定义接口所在的仍为.java 文件,虽然声明时使用的为interface 关键字的编译后仍然会产生.class 文件。这点可以让我们将接口看做是一种只包含了功能声明的特殊类。

注意:使用extends可实现接口的多继承!接口不能实例化!

接口的组成:

接口中定义的属性:都属于全局静态常量,默认由public static final 来修饰。

接口中定义的方法:在JDK1.8以前,都属于抽象方法,默认由public abstract来修饰,

​ 在JDK1.8以后,接口中还可以包含普通的静态方法和default修饰的成员方法。

【示例】接口的组成

public interface Flyable {
	// 属性:默认为全局静态属性
	/*public static final*/ double MAX_HEIGHT = 8000;
	// 方法:JDK1.8以前默认为抽象方法
	/*public abstract*/ void fly(); 
	// JDK1.8之后还可以包含静态方法和default修饰的成员方法
	public static void showInfo1() {}
	default void showInfo2() {}
}

注意:接口中不能有构造方法,因为接口中没有需要初始化的成员变量。

3.接口的实现

类与类之间是继承的关系extends,类与接口之间是实现的关系implements。

接口实现格式:

class 实现类 [extends 父类] implements 接口 {
	// 重写接口中的方法
}

在类实现接口后,该类就会将接口中的抽象方法继承过来,此时该类需要重写该抽象方法,完成具体的逻辑。

【示例】接口的实现

// 接口
interface Flyable {
	// 建议不要省略,以提高阅读性
	/*public abstract*/ void fly(); 
}
// 实现类
class Bird implements Flyable{
	public void fly() {
		System.out.println("鸟儿在天空自由的飞翔");
	}
}
// 测试类
public class Test {
	public static void main(String[] args) {
		Bird bird = new Bird();
		bird.fly();
	}
}

注意事项:

  1. 如果子类实现了接口的所有抽象方法,那么该子类可以实例化。

  2. 如果子类只实现了接口的部分抽象方法,那么子类就是一个抽象类,不能被实例化!

4.接口的多实现

了解了接口的特点后,那么想想为什么要定义接口,使用抽象类描述也没有问题,接口到底有啥用呢?接口完全支持多实现,和类的继承类似,实现类可以实现多个接口,将会获得接口中所定义的一切。

在java中,一个类只能继承一个类,但同时可以实现多个接口,既可以实现多重继承的效果和功能,也避免的多重继承的危险性。

【示例】接口的多实现案例

// 父类
class Person {
	String name;
	public void eat() {}
}
// 接口
interface Runner {
	public abstract void run();
}
interface Flyer {
	public abstract void fly();
}
// Student类,既继承Person类,又实现Runner和Flyer接口
class Student extends Person implements Runner, Flyer {
	@Override
	public void fly() {
		System.out.println("Student fly方法");
	}
	@Override
	public void run() {
		System.out.println("Student run方法");
	}
}

5.接口和抽象类区别

只有弄明白了接口和抽象类的区别,那么你才能知道什么时候该选用接口,什么时候该选用抽象类。

接口是对动作的抽象,抽象类是对根源的抽象。抽象级别(从高到低):接口 > 抽象类 > 普通类。

接口:人可以吃东西,狗也可以吃东西,我们可以把“吃东西”定义成一个接口,然后让这些类去实现它。

抽象类:人有姓名和年龄属性,也有吃饭的行为,狗也有姓名和年龄属性,也有吃饭行为,我们可以把“相同的属性和行为”定义在一个抽象类中,然后让这些类去继承这个抽象类。

相同点:

  1. 都是不断向上抽取而来的,都不能被实例化。

  2. 都包含抽象方法,但不提供具体的实现。

不同点:

  1. 抽象类需要被继承extends,而且只能单继承;

    接口需要被实现implements,而且可以多实现。

  2. 抽象类中可以定义成员变量也可以定义静态变量;

    接口中定义的变量,默认为全局静态常量(public static final来修饰)。

  3. 抽象类中可以定义构造方法,方便子类调用并给抽象类中的成员变量赋值;

    接口中不能定义构造方法,因为接口中没有成员变量需要初始化!

  4. 抽象类中可以定义普通方法,也可定义抽象方法(abstrct);

    接口JDK1.8之前,只能定义抽象方法(public abstrct),JDK1.8之后还可以定义静态方法。

  5. 抽象类的继承,描述的“is a”关系,用于定义该体系的基本共性内容;

    接口的实现,描述的“is like a”关系,用于定义体系之外的额外行为。

6.面向接口编程

面向接口编程是面向对象编程的一部分。

为什么需要面向接口编程?软件设计中最难处理的就是需求的复杂变化,需求的变化更多的体现在具体实现上。我们的编程如果围绕具体实现来展开就会陷入“复杂变化”的汪洋大海中,软件也就不能最终实现。我们必须围绕某种稳定的东西开展,才能以静制动,实现规范的高质量的项目。

接口就是规范,就是项目中最稳定的东西! 面向接口编程可以让我把握住真正核心的东西,使实现复杂的多变的需求成为可能。通过面向接口编程,而不是面向实现类编程,可以大大降低程序模块间的耦合性,提高整个系统的可扩展性和和可维护性。

面向接口编程的概念比接口本身的概念要大得多。设计难了,在你没有写实现时就要想好接口,接口一变就乱套了,设计要比实现难!接口语法本身非常简单,但是如何真正使用?才是大学问。我们需要后面在项目中反复使用,大家才能体会到。 学到此处,能了解基本概念,熟悉基本语法,就是好学生了。

ps:如需最新的免费文档资料和教学视频,请添加QQ群(627407545)领取。

发布了55 篇原创文章 · 获赞 0 · 访问量 787

猜你喜欢

转载自blog.csdn.net/zhoujunfeng121/article/details/104619464