接口与多态
接口
接口总览
定义
接囗就是多个类的公共规范。 接口是一种引用数据类型,最重要的内容就是其中的:抽象方法。 定义接口的格式: public interface接口名称() 接口内容备注:换成了关键字interface之后,编译生成的字节码文件仍然是:.java-->.class。 Java 7,接口中包含的内容有:1.常量2.抽象方法 Java8,还可以额外包含有:3.默认方法4.静态方法 JavoT9,还可以额外包含有:5.私有方法
接口中定义抽象方法
- 抽象方法固有修饰词public abstract,但是可以选择性省略不写
- 方法三要素可以根据需要自行选择
接口的调用
- 接口中含有抽象方法,所以可以看作一个抽象类,必须经过是实现来调用
public 实现类 implements 接口类{
}
//和抽象不同的是,抽象类使用extends,实现类使用implements。
- 接口中的抽象类必须全部被覆盖重写,否则含有抽象方法,是一个抽象类
- 接口的调用必须通过创建实现类对象,通过实现类来调用。
- 为方便见名知意,一般推荐实现类的命名格式为“接口类名+impl”
接口的升级
default方法
- 为方便以后接口升级,同时使对系统的影响最小,jdk8引入了可以带方法体的默认方法
定义格式:
//public 可以省略不写,但default必须写
public default 返回值类型 方法名称(参数列表){
}
默认方法的使用
- 默认方法可以直接在创建的实现类中进行调用
- 默认方法也可以重写
- 若可以找到重写后的默认方法,则直接调用重写后的默认方法,若找不到,则向上一级进行寻找
static方法
- 为方便实现类中数据的共享,jdk8中加入static方法
定义格式:
public static 返回值类型 方法名称(参数列表){
}
注意事项:
- 只能通过接口类名调用接口中的静态方法
- 不能通过接口的实现类调用接口的静态方法
接口中的private方法
- 为解决接口中代码重复的问题,把相同代码抽取出来形成一个共用方法,同时为了防止实现类中直接调用此方法,Jdk9中引入了private方法
普通私有方法
- 为解决多个默认方法中重复代码的问题
定义格式:
private 返回值类型 方法名称(参数列表){
}
静态私有方法
- 为解决静态方法中重复代码的问题
定义格式:
private static 返回值类型 方法名称 (参数列表){
}
接口中的成员常量与长远变量
- 接口中定义的成员变量的值不可变,故接口中的成员变量为常量
定义格式:
public static final 参数类型 常量名称=数据值
//常量名称推荐完全使用大写字母,并用下划线进行分割
//final修饰的关键字一旦定义不可改变
//public static final可以省略不写
//接口当中的常量必须进行赋值,一旦赋值不可改变,默认值为0
类与接口的继承与实现
- 类与类之间是单继承
public class 返回值类型 方法名称 extends 父类
-
类与接口之间是多实现
public class 返回值类型 方法名称 implements 接口1,接口2
-
接口与接口之间是多继承
public interface 接口名 extends 接口1, 接口2{ }
注意事项
-
接口是没有静态代码块或者构造方法的
-
一个类的直接父类是唯一的,但是一个类可以同时实现多个接口。
格式:
public class InterfaceImpl extends 父类 implements InterfaceA,InterfaceB{
//覆盖重写所有抽象方法
}
-
如果实现类所实现的多个接口当中,存在重复的抽象方法,那么只需要覆盖重写一次即可。
-
如果实现类没有覆盖重写所有接口当中的所有抽象方法,那么实现类就必须是一个抽象类。
-
如果实现类锁实现的多个接口当中,存在重复的默认方法,那么实现类一定要对冲突的默认方法进行覆盖重写。
-
一个类如果直接父类当中的方法,和接口当中的默认方法产生了冲突,优先用父类当中的方法。
多态
定义
- 同一行为的不同表现形式
格式:
父类类型 变量名 = new 子类对象;
接口名称 对象名称=new 实现类名称
多态中访问成员变量的方法
- 直接访问:等号左边是谁,则优先使用谁,没有则向上找
- 间接访问:通过成员方法进行访问,成员方法属于谁,则访问时,没有则向上找
多态中访问成员方法的方法
- 当使用多态方式调用方法时,首先检查父类中是否有该方法,如果没有,则编译错误;如果有,执行的是子类重写 后方法。
访问成员方法与成员变量的区别
- 成员变量:编译看左,运行看左
- 成员方法:编译看左,运行看右
多态的引用类型转换
向上转型
多态本身是子类类型向父类类型向上转换的过程,是默认执行的,代码与多态写法相同
格式定义:
父类类型 变量名 = new 子类类型();
向下转型
由于向上转型后只能调用父类中使用的方法,无法调用子类中比父类多写入的方法,所以需要向下转型
父类类型向子类类型向下转换的过程,这个过程是强制的
格式定义:
子类类型 变量名 = (子类类型) 父类变量名;
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
}
}
}