Java(19)接口
接口
接口(interface)
是一种特殊的类,是抽象方法和常量值的定义的集合,没有变量和方法的实现。
接口中的所有成员变量都默认是public static final
修饰的,所有方法都默认是public abstract
修饰的,跟抽象类一样,接口没有构造器。
package day01;
public interface Test01{ //注意这里不是class是interface
int a=10;//等同于public static final int a=10;
void run();//等同于public abstract void run();
public Test01(){};//报错:Interface abstract methods cannot have body
}
class MainClass{
public static void main(String[] args) {
System.out.println(Test01.a);
//可以看到,不需要new一个对象出来即可访问a,Test01接口中的a确实被static修饰了
}
}
用一个具体的类实现接口,使用implements
关键字,且该类需实现继承的接口的所有抽象方法。如果实现接口的类中没有实现接口中的全部方法,必须将此类定义为抽象类。
package day01;
public interface Test01{
int a=10;//等同于public static final int a=10;
void run();//等同于public abstract void run();
//public Test01(){};//报错:Interface abstract methods cannot have body
}
class P implements Test01{
@Override
public void run() {
System.out.println("实现继承的接口的抽象方法");
}
}
在Java中,一个类不可以继承自多个类,但是一个类可以实现多个接口。
package day01;
public interface Test01{ //接口1
int a=10;
void run();
}
interface Test02{ //接口2
void eat();
}
class P implements Test01,Test02{ //可以看到这里实现了两个接口
@Override
public void run() {
System.out.println("实现继承的接口Test01的抽象方法");
}
@Override
public void eat() {
System.out.println("实现继承的接口Test02的抽象方法");
}
}
class MainClass{
public static void main(String[] args) {
System.out.println(P.a);
P b=new P();
b.eat();
b.run();
}
}
/*运行结果为:
10
实现继承的接口Test02的抽象方法
实现继承的接口Test01的抽象方法
*/
接口可以继承接口,用于接口的扩展。
package day01;
public interface Test01{
void run();
}
interface TS extends Test01{ //接口TS继承接口Test01
void eat();
}
class Demo implements TS{ //可以看到类Demo实现接口TS时,要同时重写抽象方法eat(),run()
@Override
public void run() {}
@Override
public void eat() {}
}
如果一个类既继承类,又实现接口,则需要先继承后实现,更改顺序会报错。
package day01;
public interface Test01{
void run();
}
interface Test02{
void eat();
}
class Father{
public void fun(){
System.out.println("父类方法");
}
}
class Son extends Father implements Test01,Test02{ //先继承后实现,更改顺序会编译报错
@Override
public void run() {
System.out.println("儿子跑步很慢");
}
@Override
public void eat() {
System.out.println("儿子吃饭用筷子很厉害");
}
}
class RunClass{
public static void main(String[] args) {
Son s=new Son();
s.eat();
s.run();
s.fun();
}
}
/*运行结果为:
儿子吃饭用筷子很厉害
儿子跑步很慢
父类方法
*/
抽象类中可以有普通的方法,不一定是抽象方法,而在接口中,方法类型只支持抽象方法和default
方法。default
方法的目的是要给接口新增一个新方法时,如果新增的是default
方法,那么子类就不需要全部重写修改。
public interface Test01{
default void fun(){
System.out.println("这是一个接口里面的default方法");
}
void sing();
}
抽象类和接口这么像,为什么使用接口?接口是一种规范,软件开发大多是一种协作性工作,接口在开发过程可以快速分离工作内容。
想想,如果想要给一个已经被继承过的抽象类添加抽象方法,则需要让其所有子类重写其新增的抽象方法。相对于在抽象类中新增抽象方法,新建接口然后谁需要谁就实现会更方便,。如下:
package day01;
interface Sing{ //唱歌接口
void sing();
}
interface Dance{ //跳舞接口
void dance();
}
interface Basketball{ //篮球接口
void basketball();
}
interface Rap{ //rap接口
void rap();
}
class CaiXunKun implements Sing,Dance{ //可以看到,通过建立多个接口,如果有需要时再实现就可以了
@Override
public void sing() {
System.out.println("蔡徐坤唱歌");
}
@Override
public void dance() {
System.out.println("蔡徐坤跳舞");
}
}
接口也具有多态性,支持向上转型。
package day01;
interface If01 {
void emm();
}
interface If02{
void aaa();
}
class Ok implements If01,If02{
@Override
public void emm() {
System.out.println("emmmmm");
}
@Override
public void aaa() {
System.out.println("aaaaaaa");
}
}
public class Test01{
public static void main(String[] args) {
If01 g=new Ok();
g.emm(); //此行不报错
//g.aaa();此行报错,已经向上转型,g不具有aaa()方法
}
}