接口允许多重继承
一个类在继承另一个类的同时,还可以实现多个接口
public class Person {
public static void main(String[] args) {
IA a1 = new AImpl();
B a2 = new AImpl();
a1.pp();
}
}
interface IA {
public void pp();
}
class B {
public void pp() {
System.out.println("this is B.pp()");
}
}
class AImpl extends B implements IA {
// AImpl类是通过继承B类实现了对接口IA中的抽象方法提供实现
}
public class Person {
public static void main(String[] args) {
IA a1 = new AImpl();
a1.pp();
IB a2 = new AImpl();
a2.pp();
}
}
interface IA {
public void pp();
}
interface IB {
public default void pp() {
System.out.println("this is B.pp()");
}
}
class AImpl implements IA,IB{
//不能因为IB中针对pp方法提供了默认实现,所以不在实现类中定义pp方
法
@Override
public void pp() {
System.out.println("添加的新的处理逻辑");
// IA.super.pp(); 因为IA接口中并没有提供pp的默认实现,所以不允许这样调用
IB.super.pp();
}
}
接口允许多重继承
interface IA1{
public void p1();
}
interface IA2{
public void p2();
}
interface IC extends IA1,IA2{
public void p3(); //继承父接口的同时也允许自定义方法
}//可以继承多个父接口,此时IC中实际有3个抽象方法
类是单根继承,不允许继承多个父类
允许一个类实现多个接口,但是每个接口的抽象方法都必须提供实现,否则是抽象类。提供的实现也可以是继承
public class A1{
public void p1(){
}
}
public class A2 extends A1 implements IA1,IA2{
public void p2(){
}
}
public abstract class A3 extends A1 implements IA1,IA2{
}//因为p2方法没有实现
接口的出现避免了单继承的局限性,这样定义C接口则拥有A+B的所有定义,可以使用A和B接口以及父类D声明变量类型,直接new T。但是约束时,用谁声明变量编译器系统识别就是谁这种类型,也就意味只能调用识别类型中的方法,不能调用其他方法
interface A{
public void p1();
}
interface B{
public void p2();
}
interface C extents A,B{
}
class D{
public void abc(){
}
}
class T extends D implements C{
public void p1(){
}
public void p2(){
}
}
D d=new T();这里只能直接调用abc方法,如果使用其他方法则需要进行类型转换
A a=new T();这里只能直接调用A接口中声明的方法p1
B b=new T();这里只能直接调用B接口中声明的方法p2
C c=new T();
声明接口的语法
访问修饰符 interface 接口名{ } 一般建议接口名称使用形容词
- 如果定义public接口,则规则和定义public类一致,要求接口名称和文件名称一致
- 外部的接口只能使用public、默认这两个范围限定词;如果定义内部接口则可以使用4大范围限定词
- 接口实际上提供了同一的操作界面(方法),如果是JDK1.8-版本则一个方法也不实现,等待某类或某几个类去实现它的方法【接口中的所有方法必须是抽象的】。如果使用的是JDK1.8+允许使用default在接口中定义默认实现,这个实现允许在实现类中重新定义覆盖
public class Test1 {
public static void main(String[] args) {
IA2 a2 = new A2Impl();
a2.pp();
}
}
interface IA2 {
default void pp(){
//通过defaul在接口中定义方法的默认实现,则在实现类中可以覆盖定义,也
可以继承使用
System.out.println("this is pp....");
this.ff();
}
void ff();
}
class A2Impl implements IA2 {
public void ff() {
System.out.println("this is ff...");
}
}
default默认方法实现使用的限制
public class Test1 {
public static void main(String[] args) {
IA2 a2 = new A2Impl();
a2.pp();
}
}
interface IA2 {
default void pp() {
System.out.println("this is No2 pp....");
}
}
interface IA3 {
default void pp() {
System.out.println("this is No3 pp");
}
}
class A2Impl implements IA2, IA3 {
//如果IA2中有一个default实现的方法和IA3中的方法一致,则
必须在实现类中重新定义
public void pp() {
IA2.super.pp();//调用IA2接口中的pp方法的默认实现
IA3.super.pp();
}
}
- 接口中没有属性,只能定义常量,它提供一些常量,实现它的类可以共享这些常量
- 接口可以给出访问控制符,用public修饰的是公共接口,到处可见;如果定义接口没有范围限定词,则只能在同包中访问
接口中只能定义常量和抽象方法
- 这是JDK1.8以前版本的规则,不是最新的
- 接口中只能定义公共的常量,接口中的属性默认是public static nal类型的,必须是public static nal类型的
interface IA{
String name="yanjun";//这里实际上是常量定义,不是属性,它的限定词是public static final
String name="yanjun",必须在声明的同时进行赋值
}
//在接口中不能定义静态块 static{}
//接口中不能定义构造器
- 接口中只能定义公共的抽象方法, 只有在JDK1.8+中可以使用default关键字定义方法实现。接口中的方法默认是public
abstract类型的,而且必须是public abstract类型的。只有在JDK1.8+中可以使用default关键字定义方法默认实现,同时允许在实现类中覆盖重新定义 - 接口不能被实例化,只能通过实现类所实现,但是可以用于声明变量的类型。
接口 变量名=new 实现接口类();
- 接口没有构造函数
- 接口中的抽象方法必须在非抽象子类中提供实现,这个实现可以是继承来的
interface IA2 {
public void pp();
}
class A2 {
public void pp() {
}
}
class B2 extends A2 implements IA2 {
// 这里的pp方法的实现是从父类中继承来的