文章目录
- 1. 相关概念
- 2. 接口的特点
- 3. 应用举例
- 3.1. 特点:接口中的成员变量和方法的默认修饰
- 3.2. 特点:一个类可以实现多个无关的接口
- 3.3. 特点:接口可以继承接口
- 3.4. 特点:实现接口的类中必须提供接口中所有方法的具体实现内容,方可实例化。
- 3.5. 特点:语法格式要先写 extends ,后写 implements
- 4. 接口和抽象类的区别
1. 相关概念
为什么要有接口?
有时必须从几个类中派生出一个子类,继承它们所有的属性和方法。但是, Java 不支持多重继承。有了接口,就可以得到多重继承的效果。
接口的定义:
(1)接口 (interface) 是抽象方法和常量值的定义的集合。
(2)从本质上讲,接口是一种特殊的抽象类,这种抽象类中只包含常量和方法的定义,而没有变量和方法的实现。
(3)一个类可以实现多个接口,接口也可以继承其它接口。
实现接口类:
class SubClass implements InterfaceA{ }
2. 接口的特点
(1)用 interface 来定义。
(2)接口中的所有成员变量都默认是由 public static final 修饰的。
(3)接口中的所有方法都默认是由 public abstract 修饰的。
(4)一个类可以实现多个无关的接口
(5)接口没有构造器。
(6)接口采用多层继承机制。
(7)实现接口的类中必须提供接口中所有方法的具体实现内容,方可实例化。否则,仍为抽象类。
(8)接口的主要用途就是被实现类实现。(面向接口编程)
(9)与继承关系类似,接口与实现类之间存在多态性
(10)定义 Java 类的语法格式:先写 extends ,后写 implements
3. 应用举例
3.1. 特点:接口中的成员变量和方法的默认修饰
对应特点(2)(3):
(2)接口中的所有成员变量都默认是由 public static final 修饰的。
(3)接口中的所有方法都默认是由 public abstract 修饰的。
接口定义举例:
public interface Runner {
int ID = 1;
void start();
public void run();
void stop();
}
因为接口中的所有成员变量都默认是由 public static final 修饰的,上面代码相当于:
public interface Runner {
public static final int ID = 1;
public abstract void start();
public abstract void run();
public abstract void stop();
}
3.2. 特点:一个类可以实现多个无关的接口
对应特点(4):
(4)一个类可以实现多个无关的接口
举例:
TestIn接口:
package day09;
public interface TestIn {
int ID = 1;//等同public static final int ID = 1;
void test();//等同public abstract void test();
}
TestIn1接口:
package day09;
public interface TestIn1 {
void test1();
}
实现接口:类实现
多个接口
package day09;
/**
* 子类继承父类,只能继承一个父类
* 类可以'实现'多个接口,(用','分隔)
* @author 14532
*
*/
public class TestImpl implements TestIn, TestIn1 {//实现两个接口
@Override
public void test() {
}
@Override
public void test1() {
}
}
3.3. 特点:接口可以继承接口
对应特点(6):
(6)接口采用多层继承机制。
如2.2中的例子:
package day09;
public interface TestIn2 extends TestIn1 {//接口可以继承接口
}
3.4. 特点:实现接口的类中必须提供接口中所有方法的具体实现内容,方可实例化。
对应特点(7):
(7)实现接口的类中必须提供接口中所有方法的具体实现内容,方可实例化。否则,仍为抽象类。
上图所示就没有提供接口中所有方法的具体实现内容,所以会报错,修改方法:将其改成抽象类。如下
package day09;
/**
* 如果类没有实现接口所有方法,这个类就要定义抽象类
* @author 14532
*
*/
public abstract class TestImpl1 implements TestIn {
}
3.5. 特点:语法格式要先写 extends ,后写 implements
对应特点(10):
(10)定义 Java 类的语法格式:先写 extends ,后写 implements
package day09;
/**
* 如果一个类既继承父类,又实现接口
* 那么先继承,再实现
* @author 14532
*
*/
public class TestImpl2 extends Person implements TestIn, TestIn1{
@Override
public void test() {//Person中有Test()方法
}
@Override
public void test1() {
}
}
4. 接口和抽象类的区别
问题:接口和抽象类很相似,好像接口能做的事 用抽象类也能做,干嘛还要用接口呢?
假设:人类是由猴子进化来的,假如要是穿越回到过去,改变了猴子(猴子多出一只眼睛),对现在的人类会造成什么影响?
从这个假设上可以看出,父类需要是稳定的抽象类,如果父类经常在变化,那么基于这个父类的子类、子类的子类,…,这些子类都要受到影响。
但有时我们又需要给父类增加一些方法,那么就不能直接在父类上下手,只能新建一个接口,在接口上扩展方法,其他需要这些方法的子类自行去实现接口。
举例:
解决方法:
代码实现:
Person抽象类:
package day09;
public abstract class Person1 {
int age;
String name;
int sex;
public abstract void showInfo();
}
Cooking接口:
package day09;
/**
* 厨艺的接口
* @author 14532
*
*/
public interface Cooking {
void fry();//炒菜
}
Sing接口:
package day09;
/**
* 歌唱的接口
* @author 14532
*
*/
public interface Sing {
void singing();//歌唱
}
SCTeacher类:
package day09;
/**
* 描述会唱歌的厨子是一个老师的类
* @author 14532
*
*/
public class SCTeacher extends Person1 implements Cooking,Sing{
String course;//教的科目
public void setInfo() {
super.age = 27;
super.name = "张三";
super.sex = 1;
this.course = "数学";
}
@Override
public void showInfo() {
System.out.println("会唱歌的厨子的老师的信息是:");
System.out.println(super.age);
System.out.println(super.name);
System.out.println(super.sex);
System.out.println(this.course);
}
@Override
public void fry() {
System.out.println(super.name + "老师拿手的厨艺是炒菜");
}
@Override
public void singing() {
System.out.println(super.name + "老师擅长美声唱法");
}
}
Test.java:
package day09;
public class Test {
public static void main(String[] args) {
SCTeacher sct = new SCTeacher();
sct.setInfo();
sct.showInfo();
sct.fry();
sct.singing();
}
}
运行结果:
(9)与继承关系类似,接口与实现类之间存在多态性
修改上面Test.java:
package day09;
public class Test {
public static void main(String[] args) {
Cooking c = new SCTeacher();
c.fry();
Sing s = new SCTeacher();
s.singing();
}
}
运行结果:
总结:
抽象类是对于一类事物的高度抽象,其中既有属性也有方法。接口是对方法的抽象,也就是对一系列动作的抽象。
当需要一类事物对一类事物抽象的时候,应该是使用抽象类,好形成一个父类;当需要对一系列动作抽象,就使用接口,需要使用这些动作的类就去’实现’相应的接口即可。