文章目录
接口
接口基本概述及格式
接口概述
接口,是Java语言中一种引用类型,是方法的集合,如果说类的内部封装了成员变量,构造方法和成员方法,那么接口的内部主要就是封装了方法,包含抽象方法、默认方法和静态方法、私有方法
接口定义格式
接口用关键字
interface
修饰
public interface 接口名{}
接口的使用
接口是不能创建对象的,必须有实现类才能使用,类实现接口用
implements
表示
public class 类名 implements 接口名 {}
注意:接口的实现类必须重写接口中所有的抽象方法,要么该类是一个抽象类
接口成员的特点
成员变量
只能是常量,默认修饰符:public static final
成员方法
只能是抽象方法,默认修饰符:public abstract
构造方法
没有,因为接口主要是扩展功能的,而没有具体存在
接口默认方法的定义和使用
默认方法:使用
default
修饰,不可省略,供子类调用或子类重写
-
默认方法定义格式
public default 返回值类型 方法的名称(参数列表){ 方法体; }
-
默认方法的好处
实现类可以不用重写默认方法,默认方法可以用于接口升级
接口静态方法的定义和使用
静态方法:使用
static
修饰,供接口直接调用。
静态与.class文件相关,只能使用接口名调用,不可以通过实现类的类名或者实现类的对象调用
- 静态方法定义格式
public static 返回值类型 方法名称(参数列表){ 方法体 }
继承父类并实现多个接口
在继承体系中,一个类只能继承一个父类,而对于接口而言,一个类是可以实现多个接口的,这叫做接口的多实现,并且,一个类能继承一个父类,同时实现多个接口。
多实现格式
class 类名 [extends 父类名] implements 接口名1,接口名2,接口名3... {
// 重写接口中抽象方法【必须】
// 重写接口中默认方法【不重名时可选】
}
注意事项
接口中,有多个抽象方法时,实现类必须重写所有的抽象方法。如果抽象方法有重名的,只需要重写一次即可
如果实现类继承了父类,这个父类是一个抽象类时,我们还需要再重写抽象类中的所有抽象方法
接口之间的多继承
一个接口能继承另一个或者多个接口,这和类之间的继承比较相似,接口的继承使用
extends
关键字,子接口继承父接口的方法。如果父接口中的默认方法有重名的,那么子接口需要重写一次。
注意:接口多继承之后,如果想使用,我们还必须定义实现类,才能使用
类与类的关系
类与类:
继承关系,只能单继承,不能多继承,可以多层继承。
接口与接口:
继承关系,可以单继承也可以多继承。public interface Sister extends Father,Mother
类与接口:
实现关系,可以单实现,也可以多实现。 public class Son extends Object implements Father,Mother
并且还可以在继承一个类的同时实现多个接口。
抽象类和接口的区别
A:成员区别
抽象类:
成员变量:可以变量,也可以常量
构造方法:有
抽象类不能实现化
成员方法:可以抽象,也可以非抽象
接口:
成员变量:只可以静态常量 可以省略 public static final
构造方法:无
接口不能实例化
成员方法:可以抽象 可以省略public abstract
有默认方法
静态方法
B:关系区别
类与类
继承,单继承, 多层继承
类与接口
实现,单实现,多实现
接口与接口
继承,单继承,多继承
C:设计理念区别
抽象类【共性功能】。
接口【扩展功能】。
多态
什么是多态
多态是继封装,继承之后,面向对象的第三大特征。
定义:同一个事物,在不同时刻体现的状态不一样
多态的前提
要有继承或实现关系
要有方法的重写
要有父类的引用指向子类对象 fu f = new Zi();
多态格式
-
普通多态的格式
父类 对象 = new 子类();
-
抽象类多态的格式
抽象类 对象名 = new 抽象类子类();
-
接口多态的格式
接口 对象名 = new 接口实现类();
多态中的成员访问特点
成员变量
编译看左边(父类),运行看左边(父类)
成员方法
编译看左边(父类),运行看右边(子类)
多态的好处和弊端
多态的弊端
不能使用子类的特有成员
多态的好处
提高程序的扩展性。定义方法时,使用父类型作为参数,在使用的时候,使用具体的子类型参与操作
多态中的转型
为什么要用转型
当使用多态方式调用方法时,首先检查父类中是否有该方法,如果没有,则编译错误。也就是说,不能调用子类拥有,而父类没有的方法。所以,想要调用子类特有的方法,必须做向下转型。
向上转型
多态本身是子类类型向父类类型向上转换的过程,这个过程是默认的。
// 向上转型
父类类型 变量名 = new 子类类型();
如:Animal a = new Cat();
向下转型
父类类型向子类类型向下转换的过程,这个过程是强制的。
一个已经向上转型的子类对象,将父类引用转为子类引用,可以使用强制转换类型,便是向下转型。
// 向下转型
子类类型 变量名 = (子类类型) 父类变量名;
如:Cat c = (Cat) a;
转型的异常
问题描述
转型的过程中,一不小心就会遇到这样的问题
public class Test {
public static void main(String[] args) {
// 向上转型
Animal a = new Cat();
a.eat(); // 调用的是 Cat 的 eat
// 向下转型
Cat c = (Cat)a;
c.catchMouse();//调用自己的方法
System.out.println("================");
// 向下转型
Dog d = (Dog)a; //引用的父类,是多态cat类,并不是dog
d.watchHouse(); // 调用的是 Dog 的 watchHouse 【运行报错】
}
}
这段代码可以通过编译,但是运行时,却报出了ClassCastException
类型转换异常!这是因为,明明创建了Cat类型对象,运行时,当然不能转换成Dog对象的。这两个类型并没有任何继承关系,不符合类型转换的定义。
为了避免ClassCastException
的发生,Java提供了instanceof
关键字,给引用变量做类型的校验。
instanceof使用格式
变量名 instanceof 数据类型
如果变量属于该数据类型,返回true。
如果变量不属于该数据类型,返回false。
public class Test {
public static void main(String[] args) {
// 向上转型
Animal a = new Cat();
a.eat(); // 调用的是 Cat 的 eat
// 向下转型
if (a instanceof Cat){
Cat c = (Cat)a;
c.catchMouse(); // 调用的是 Cat 的 catchMouse
} else if (a instanceof Dog){
Dog d = (Dog)a;
d.watchHouse(); // 调用的是 Dog 的 watchHouse
}
}
}