接口(可多接口)


接口(可多接口)

接口代表某个确切的功能,即只包含方法的定义,甚至都不是一个类。

接口包含了一系列方法的定义,类可以实现这个接口,表示类支持接口代表的功能

定义

接口用 interface 定义:

public interface Study{
	void study();    //实际上是public abstract void study();但是由于接口中只能定义访问权限
									// 为public的抽象方法,因此可以省略
}

此时,想要实现该接口的类就要在定义中重写study抽象方法了,当然也可以在定义中写上接口的默认实现(default)(Java8之后),这样在子类中可以选择不重写方法

接口中不能包含成员变量和成员方法,但可以存在静态变量和静态方法

在定义接口中的静态变量时,不必显示地给出,其默认类型为 public static final 型,这意味着该变量不能再次被赋值

默认方法(Java8)

定义格式:

public default 返回值类型 方法名(参数列表){}

注意事项:

  • 默认方法不是抽象方法,所以不强制被重写。但是如果被重写,重写时去掉default关键字
  • public可以省略,default不能省略
  • 如果实现了多个接口,多个接口中存在相同名字的默认方法,子类就必须对该方法进行重写

例如:

public interface Study{
	void study();
	
	default void test(){
		System.out.println("默认实现");//**注:默认实现不能是Object中已有的方法,但是可以重写**
	}
}

静态方法(Java8)

定义格式:

public static 返回值类型 方法名(参数列表){}

注意事项:

  • 静态方法只能通过接口名调用,不能通过实现类名或者对象名调用
  • public 可以省略, static不能省略
  • 如果接口中的静态方法与类中的静态方法名相同,由于静态方法不在虚方法表中,因此两个方法不是重写关系,想要调用只要 类名 / 接口名 + 方法名() 即可

私有方法(Java9)

Java9后,允许接口中定义其private方法供内部使用:

public interface Study{
	default void study(){
		sout("默认实现");
		inner();
	}
	
	private void inner(){
		sout("一系列内部实现");
	}
}

包括静态方法在内,也可以使用private访问权限进行声明

在外面使用接口对应的对象时,跟类一样无法访问到私有成员。

成员的特点

成员变量

只能是常量(默认修饰符:public static final)

构造方法

没有

成员方法

只能是抽象方法(默认修饰符:public abstract)

  • Java7 以前:接口中只能定义抽象方法
  • Java8:接口中可以定义有方法体的方法
  • Java9:接口中可以定义私有方法

实现

类可以通过 implements 关键字来实现所需接口:

public class Student extends Person implements Study{

	@Override
	public void study(){
		System.out.println("我会学习!");
	}
}

注:在重写中使用接口的默认实现: 接口名.super.函数名()

如,在Student.java中:

public class Student extends Person implements Study{
    public Student(String name,int age,String sex){ super(name,age,sex); }

    @Override
    public void study(){
        Study.super.test();
        System.out.println("我会学习!");
    }
}

多个接口

public class Student extends Person implements Study,Walk,Eat{//多个接口用逗号隔开
	
}

使用

在Main方法中,可以直接通过接口名来定义一个变量:

Study student=new Student("小明",18,"男");
//此时student实质上还是Student类的引用,可以通过强制类型转换为Student类型

此时定义的变量只能使用接口中定义的方法:

student.study();

使用clone方法(clone为浅拷贝)

clone是Object类中的方法,但子类要使用该方法时必须要提供 Cloneable 的接口,即:

public class Student extends Person implements Clonable{}

此时,子类中重写的Cloneable方法,只需要把它的访问权限从protected改为public(否则外面不能用):

public class Student extends Person implements Cloneable{

	@Override
	public Object clone() throws CloneNotSupportedException{
			return super.clone();
		}
}

Main中实现:

public class Main{
	public static void main(String[] args) throws CloneNotSupportException{
			Student stu=new Student("小明",18,"男");
			Student clone = (Student) stu.clone();  //强制类型转换
		}
}

即使clone为stu的克隆,在执行stu==clone时返回的也是false(因为是不同对象)

继承

接口也存在继承,同样使用 extends 关键字

需要注意的是,接口可以 多继承 ,即extends后面可以跟多个接口,其效果就是子接口包括父接口的所有方法

并且,当子接口和父接口存在同名方法时,子接口方法会覆盖父接口方法

特殊情况

当父类中存在子类所接接口中的同名方法时,且该接口存在默认实现,那么类的对象在调用该方法时执行的是父类中的方法

多态

当一个方法的参数是接口时,可以传递接口所有实现类的对象,这种方式称之为接口多态


Author: havenochoice
Reprint policy: All articles in this blog are used except for special statements CC BY 4.0 reprint policy. If reproduced, please indicate source havenochoice !
评论
  TOC