接口
概念:在java编程语言中是一个抽象类型,是抽象方法的集合,接口通常以interface来声明,一个类通过实现接口的方式,从而实现接口的抽象方法。
接口就是给出一些没有实现的方法,封装到一起,到某个类要使用的时候,在根据具体情况把这些方法写出来。
接口是更加抽象的抽象的类,抽象类里的方法可以有方法体,接口中所有方法都没有方法体(jdk 1.7),接口体现了程序设计的多态和高内聚低耦合的设计思想。
特别说明:jdk8.0后接口类可以有静态方法,默认方法,也就是说接口中可以有方法的具体实现。
接口与类的异同
没有构造方法,仅可以定义公共静态常量与公共抽象方法;
接口的应用
java为单继承,当父类的方法种类无法满足子类需求时,可以实现接口扩充子类能力;
接口的规范
- 任何类实现接口时,必须实现接口中所有的抽象方法,否则此类为抽象类;
- 实现接口中的抽象方法时,访问修饰符是public或默认;
public class Test02 {
public static void main(String[] args) {
Bird bird = new Bird() {
@Override
public void fly() {
}
};
bird.eat();
bird.fly();
Dog dog = new Dog();
dog.fly();
dog.eat();
}
}
class Animal{
public void eat(){
System.out.println("eating.....");
}
}
interface Fly{
public void fly();
}
interface shut{
void shut();
}
abstract class Bird extends Animal implements Fly{
}
class Dog extends Animal implements Fly{
@Override
public void fly() {
}
}
接口的注意事项
- 接口不能被实例化;
- 接口中所有方法是public方法,接口中抽象方法,可以不用abstract修饰,不能有方法体,抽象类中方法可以有方法体;
- 一个普通类实现接口,就必须将该接口中的所有方法实现;
- 抽象类实现接口,可以不用实现接口中的方法;
- 一个类可以实现多个接口;
- 接口中的属性只能是final,而且是public static final修饰符。例如int a = 3‘实际上是public static final int a =3;(必须初始化);
- 接口中属性的访问形式:接口名.属性名;
- 接口中不能继承其他类,但是可以继承多个别的接口(例如:interface A extends B,C);
- 接口的修饰符只能是public和默认,这点和类(包括抽象类)的修饰符一样。
接口引用
同父类一样,接口也可声明为引用,并指向实现类对象。
注意:
- 仅可调用接口中所声明的方法,不可调用实现类中独有的方法;
- 可强转回实现类本身类型,进行 独有方法调用;
一个类如果实现了一个接口,但没有实现方法,必须要把该类声明为抽象类。
接口的多态
不同引用所能看到的对象范围不同,只能调用自身类型中所声明的部分。
public class TestPolymorpfic{
public static void main(string[ ] args) {
//多种不同类型的引用指向同一个对象时,表示看待对象的视角不同
Dog myDog = new DogO3(); //Dog myDog:将狗当狗看
Animal a = myDog3; //Animal 将狗当动物看
Runnable r = myDog3; //将狗当做会跑的东西看
Swrimmable s = myDog; //将狗当做会游泳的东西看
}
interface Runnable{
public abstract void run();
}
interface Swimmable{
public abstract void swim();
}
abstract class Animal{
public void eat(){};//父类方法
}
class Dog extends Animal implements Runnable , Swimmable{
public void run(){};//接口方法
public void swim(){};//接口方法
public void shout(){}//特有方法
)
接口的多态特性
- 多态参数 USB接口,可以接收手机对象又能接收相机对象,就体现了接口的多态(接口的引用可以指向实现了接口类的对象);
- 多态数组 如果手机对象除了调用接口定义的方法外,还可以调用手机特有的打电话方法;
- 多态传递 接口存在多态传递现象,B类实现A接口,C类继承B类, C c = new C(); A a = c;
接口的好处
- 程序的耦合度降低;
- 更自然使用多态;
- 设计与实现完全分离;
- 更容易搭建程序框架;
- 更容易更换具体实现;
接口VS继承类
- 继承和接口解决的问题不同
- 继承的价值在于解决代码的复用性和可维护性;
- 接口的价值在于设计。设计好各种规范,让其他类去实现这些规范(方法),即更加的灵活;
- 接口比继承更加灵活
- 继承是满足is a 的关系,接口只需满足like a 的关系;
- 接口在一定程度上实现了代码解耦(即接口规范性+动态绑定机制)
编程题目
学院和学生都拥有详细信息的描述,学院的打印机能够对于学院和学生的信息进行打印,要求完成此功能代码的编写,要求功能具备良好的可扩展性和可维护性。
public class Test01 {
public static void main(String[] args) {
College college = new College();
college.name = "Super college";
college.printInformation(college);
Student student = new Student();
student.name = "Li Hua";
student.printInformation(student);
}
}
//打印机类 将打印机类作为父类
class Print{
public void print(String information){
System.out.println(information);
}
}
//彩色打印机
class ColorPrint extends Print{
public void print(String information){
System.out.println("打印彩色的,开始打印"+information);
}
}
//黑白打印机
class BlackPrint extends Print{
public void print(String information){
System.out.println("打印黑白的,开始打印"+information);
}
}
//学院和学生没有共同的属性,将描述信息的方法做成接口中的抽象方法 当其他类描述信息实现这个方法(可扩展性)
interface introduce{
public String describe();
}
//学院类
class College implements introduce{
String name;
Print printer = new ColorPrint();
public String describe(){
return name+"的信息";
}
public void printInformation(College college){
college.printer.print(describe());
}
}
//学生类
class Student implements introduce{
String name;
Print printer = new BlackPrint();
public String describe(){
return name+"的信息";
}
public void printInformation(Student student){
student.printer.print(describe());
}
}