一、设置Animal接口与Person接口有如下继承关系:
public interface Animal {
public void eat();
}
interface Person extends Animal{
public void speak();
}
二、创建测试类如下:
public class Test01{
public static void main(String[] args) {
Animal a = new Animal(){
@Override
public void eat() {
System.out.println("动物吃东西");
}
};
Animal b = new Person() {
@Override
public void speak() {
System.out.println("人会说话");
}
@Override
public void eat() {
System.out.println("人能吃东西");
}
};
Animal c = new Person() {
@Override
public void speak() {
System.out.println("人会说话");
}
@Override
public void eat() {
System.out.println("人能吃东西");
}
public void dis() {
}
};
Person p = null;
Person p1 = null;
Person p2 = null;
try{
p = (Person)a;
}catch (Exception e){
e.printStackTrace();
System.out.println("p错误");
}
try{
p1 = (Person)b;
}catch(Exception e){
e.printStackTrace();
System.out.println("p1错误");
}
try{
p2 = (Person)c;
}catch(Exception e){
e.printStackTrace();
System.out.println("p2错误");
}
}
}
控制台输出:
java.lang.ClassCastException: com.bjpowernode.HttpServletDemo.Test01$1 cannot be cast to com.bjpowernode.HttpServletDemo.Person
at com.bjpowernode.HttpServletDemo.Test01.main(Test01.java:39)
p错误
三、总结
Animal a = new Animal(){
@Override
public void eat() {
System.out.println("动物吃东西");
}
};Person p = (Person)a;//编译通过,运行失败
首先a的编译时类型为Animal类型,运行时类型为匿名内部类实现Animal接口。上述代码块说明,即便Person接口继承了Animal接口,也不能将Animal的实现类向下转型为Person类型,原因可以理解为Animal的实现类即a的运行时类型只重写了Animal的eat()方法,而Person中还可能有其他扩展的抽象方法,假设能将a向下转型为Person类型,则此时a的编译时类型为Person,而运行时类型仍然为原来的匿名内部类,就会出现编译时类型的方法数大于运行时类型的方法数,这显然是不被允许的:当调用一个运行时类型没有重写的方法,显然会发生错误!!!
Animal b = new Person() {
@Override
public void speak() {
System.out.println("人会说话");
}@Override
public void eat() {
System.out.println("人能吃东西");
}
};Person p = (Person)a;//编译通过,运行通过
上述代码中运行时类型为Person的变量则可以向下转型为Person类型:编译时方法数等于运行时方法数.
Animal c = new Person() { @Override public void speak() { System.out.println("人会说话"); } @Override public void eat() { System.out.println("人能吃东西"); } public void dis() { } };Person p = (Person)c;//编译通过,运行通过
上述代码中c在实现Person接口时扩展了一个新方法,而Person接口中没有这个抽象方法,但c仍然可以向下转型为Person类型:编译时方法数小于运行时方法数.