if (a instanceof A)表示判断:如果a是A类的一个实例。
看一个具体例子:
先定义一个父类Person类:
abstract class Person {
public abstract void say();
}
然后让Man和Woman类分别继承它,并实现其抽象方法:
class Man extends Person {
public void say() {
System.out.println("Man is saying...");
}
}
class Woman extends Person {
public void say() {
System.out.println("Woman is saying...");
}
}
下面是测试主程序:
public class Main {
public static void say(Person p) {
p.say();
}
public static void main(String[] args) {
Person p1 = new Man();
Person p2 = new Woman();
say(p1);
say(p2);
}
}
输出结果:
Man is saying…
Woman is saying…
现在,如果我们有个新需求,在Woman子类中添加了一个getAngry()方法,变成如下:
class Woman extends Person {
public void say() {
System.out.println("Woman is saying...");
}
public void getAngry() {
System.out.println("Woman gets angry...");
}
}
那么如果我们想在测试主类中的say()方法中调用这个getAngry()方法,该怎么调用呢?
如果像这样:
public static void say(Person p) {
p.say();
p.getAngry();//会报错不能编译
}
由于p被转换成了Person类型,而Person类中是没有getAngry()方法的,所以会报错。
那把p强制转换成Woman类型可以不呢?试试:
public static void say(Person p) {
p.say();
Woman w = (Woman)p;
w.getAngry();
}
编译没出错,但是运行会出错,因为我们还传入了一个p1,是一个Man对象,是不能强制转换成Woman类型的。
解决办法就是:我们判断一下say()方法传入的参数p是不是Woman类的实例,如果是的话就执行getAngry()方法,否则就不执行。
如下:
public static void say(Person p) {
p.say();
if (p instanceof Woman) {
Woman w = (Woman)p;//强制转换
w.getAngry();
}
}
运行结果:
Man is saying…
Woman is saying…
Woman gets angry…
那么,假如p是Woman的实例了,强制转换这一步还是不是必须的呢?答案是肯定的,仍然要强制转换,因为虽然p是Woman类的实例,但在传入时p是Person类型的。