前言
先声明一下,写这篇文章的目的是为了记录个人学习心得,可能存在许多不足与谬误,有劳各位指出。
首先说明多态和接口的一些特点。
一、多态性
所谓多态性,务实点概括就是父类的对象可以指向子类的引用。
格式为:
父类名称 对象名=new 子类名称();
或
接口名称 对象名=new 实现类名称();
这是一种向上转型的写法,之后可以使用父类对象调用子类中的成员方法,但仅限于子类重写父类的情况,子类特有的方法不行。
如果使用某子类特有方法,则父类对象要向下转型为原本的子类,在此之前要进行判断父类引用原本是否为该子类(可以通过a instanceof B判断,a为父类引用,B为子类)。
二、接口使用
1.不能直接使用,必须有一个实现类
格式:
public class 实现类名称 implements 接口名称{
//…
}
2.接口实现类必须覆盖重写接口中所有抽象方法;去掉abstract关键字,加上方法体大括号
3.创建实现类对象进行使用
三、代码文件
1.Sward.java
public interface Sward {
//两个抽象方法:拔剑与收剑
public abstract void out();
public abstract void back();
}
这是一个接口,表示所有类型的剑,定义两个抽象方法,分别代表拔剑与收剑两种行为。
2.SteelSward.java&SilverSward.java
//钢剑类,实现剑接口
public class SteelSward implements Sward{
//重写拔剑,拔钢剑
@Override
public void out() {
System.out.println("拔出钢剑;");
}
//重写收剑,收钢剑
@Override
public void back() {
System.out.println("收起钢剑。");
}
//钢剑特性,斩杀人类、亚人类与一般动物
public void killSteel() {
System.out.println("杀了一队守卫与一只野狗;");
}
}
//银剑类,实现剑接口
public class SilverSward implements Sward{
//重写拔剑,拔银剑
@Override
public void out() {
System.out.println("拔出银剑;");
}
//重写收剑,收银剑
@Override
public void back() {
System.out.println("收起银剑。");
}
//银剑特性,斩杀天球交会的怪物
public void killSilver() {
System.out.println("杀了几只食尸鬼和一只日间妖灵;");
}
}
钢剑类与银剑类,游戏中是巫师3的一大特色。实现了Sward接口,重写接口中的拔剑与收剑动作方法,并各自添加了自己的特性方法(钢剑惩恶,银剑除魔)。
3.Witcher.java
public class Witcher {
public void fightBegin() {
System.out.println("开始战斗!");
}
public void fightEnd() {
System.out.println("结束战斗!");
}
public void useSward(Sward sward) {
sward.out();//调用拔剑
//判断原类型
if(sward instanceof SteelSward) {
SteelSward steelSward=(SteelSward)sward;//向下转型成SteelSward
steelSward.killSteel();//调用钢剑特性
}else if(sward instanceof SilverSward) {
SilverSward silverSward=(SilverSward)sward;//向下转型成SilverSward
silverSward .killSilver();//调用银剑特性
}
sward.back();//调用收剑
}
}
Witcher类,是SteelSward类与SilverSward类的使用者。
可以看到,在useSward(Sward sward)方法中传入的参数是Sward接口引用,但实际使用中传入的参数也可以是实现类引用。如果这么写的话,则隐藏了一次向上转型,参见之后的测试部分代码。
传入的接口引用在函数体中判断类型,向下转型成具体实现类,进行其特有行为。
4.WitcherFight.java
public class WitcherFight {
public static void main(String[] args) {
Witcher geralt=new Witcher(); //创建猎魔人对象杰洛特
geralt.fightBegin(); //对象杰洛特调用开始战斗方法
Sward steelSward=new SteelSward(); //多态式写法,用接口剑类型引用指向实现类钢剑类对象
geralt.useSward(steelSward); //杰洛特使用钢剑
SilverSward silverSward=new SilverSward(); //常规写法,使用时自动转换类型
geralt.useSward(silverSward); //杰洛特使用银剑(向上转型)
geralt.fightEnd();//对象杰洛特调用结束战斗方法
}
}
用于测试,模拟猎魔人的一场战斗。
总结
成员方法的参数类型是接口类型,而使用时传入参数的是它的实现类(自动转换类型),这是向上转型的一种用法;
当要使用实现类特性方法时,将接口类型转回原本的实现类,这是向下转型的一种用法。