接口是功能的集合,同样可看做是一种数据类型,是比抽象类更为抽象的”类”。
接口只描述所应该具备的方法,并没有具体实现,具体的实现由接口的实现类(相当于接口的子类)来完成。这样将功能的定义与实现分离,优化了程序设计。
请记住:一切事物均有功能,即一切事物均有接口
与定义类的class不同,接口定义时需要使用interface关键字。定义接口所在的仍为.java文件,虽然声明时使用的为interface关键字的编译后仍然会产生.class文件。这点可以让我们将接口看做是一种只包含了功能声明的特殊类。定义格式:
public interface 接口名{
抽象方法1;
抽象方法2;
}
接口中的方法均为公共访问的抽象方法,接口中无法定义普通的成员变量//不能写属性
类与接口的关系为实现关系,即类实现接口。实现的动作类似继承,只是关键字不同,实现使用implements。其他类(实现类)实现接口后,就相当于声明:”我应该具备这个接口中的功能”。实现类仍然需要重写方法以实现具体的功能,格式为:
class 类 implements 接口{
重写接口中方法
}
在类实现接口后,该类就会将接口中的抽象方法继承过来,此时该类需要重写该抽象方法,完成具体的逻辑。接口中定义功能,当需要具有该功能时,可以让类实现该接口,只声明了应该具备该方法,是功能的声明。在具体实现类中重写方法,实现功能,是方法的具体实现。于是,通过以上两个动作将功能的声明与实现便分开了。(此时请重新思考:类是现实事物的描述,接口是功能的集合。)
接口特点:
①接口里的属性必须为常量,不能改变,修饰符必须是final static,②接口里的方法用public abstract修饰,3接口不能new实例,得让子类覆盖掉接口的所有抽象方法后创建,否则不覆盖仍然是个抽象类
接口可以多实现,但类不能多继承
1、接口多实现就是为了解决多继承的弊端,比如
interface Fu1{
voidshow1();//没有抽象方法啊?
}
interface Fu2{
voidshow2();
}
class Zi implements Fu1,Fu2{ // 多实现。同时实现多个接口。
publicvoid show1(){}
publicvoid show2(){}
}
怎么解决多继承的弊端呢?
弊端:多继承时,当多个父类中有相同功能时,子类调用会产生不确定性。其实核心原因就是在于多继承父类中功能有主体,而导致调用运行时,不确定运行哪个主体内容。
为什么多实现能解决了呢?
因为接口中的功能都没有方法体,由子类来明确,并且类可以继承类也可以实现接口,可以避免但继承的尴尬
接口多继承
interface Fu1{
voidshow();
}
interface Fu2{
voidshow1();
}
interface Fu3{
voidshow2();
}
interface Zi extends Fu1,Fu2,Fu3{
voidshow3();
}
抽象跟接口的区别
1、抽象是将一类的共性功能行为抽出,例如:狗类共性(有眼睛,能吼叫)
2、接口是将具有某一类行为的特性行为,例如:缉毒犬,不仅有共性也有特性(有眼睛,能吼叫,能缉毒)
二、多态
现实事物经常会体现出多种形态,如学生,学生是人的一种,则一个具体的同学张三既是学生也是人,即出现两种形态。Java作为面向对象的语言,同样可以描述一个事物的多种形态。如Student类继承了Person类,一个Student的对象便既是Student,又是Person。
多态的定义格式:就是父类的引用变量指向子类对象
父类类型 变量名 = new 子类类型();
变量名.方法名();
1.普通类多态定义的格式
父类 变量名 = new 子类();
如: class Fu {}
class Ziextends Fu {}
//类的多态使用
Fu f = new Zi();
2.抽象类多态定义的格式
抽象类 变量名 = new 抽象类子类();
如: abstractclass Fu {
public abstract void method();
}
class Zi extends Fu {
public void method(){
System.out.println(“重写父类抽象方法”);
}
}
//类的多态使用
Fu fu= new Zi();
3.接口多态定义的格式
接口 变量名 = new 接口实现类();
如:interface Fu {
public abstract voidmethod();
}
class Zi implements Fu {
public void method(){
System.out.println(“重写接口抽象方法”);
}
}
Fu fu = new Zi() //接口的多态使用
多态向上转型跟向下转型
向上转型:父类引用创建子类对象,父类 fu=new 子类();
向下转型:将父类对象转为子类对象,子类 zi=new 父类();