先说结论:压根是不矛盾的,因为他压根不是你看到的哪个new实例化!
在学习抽象类和接口的时候明确说明了,接口和抽象类是不能实例化的!但是在学习匿名内部类时,就看到他的格式可能就会一脸懵逼.
new 类名或接口名(){
重写方法;
};
先看一段代码
/*
1、计算器接口具有work方法,功能是运算,有一个手机类Cellphone, 定义方法testWork测试计算功能,<调用计算接口的work功能>
2、要求调用Cellphone对象 的testWork方法,使用上 匿名内部类
*/
public class homework04__ {
public static void main(String[] args) { //匿名类做实参使用
Cellphone3 cellphone3 = new Cellphone3();
cellphone3.testWork(
new Calculator() {
@Override
public double work(double num1, double num2) {
return num1 + num2;
}
},5,5
);
}
}
interface Calculator{
double work(double num1,double num2);
}
class Cellphone3{
public void testWork(Calculator calculator,double num1,double num2){
double res = calculator.work(num1,num2);
System.out.println(res);
System.out.println(calculator instanceof Calculator);
}
}
//案列2 注意有代码省略!!! 这是一个外部类!!!
abstract class Animal{
abstract void eat();
}
//第三个匿名内部类
Animal dog = new Animal(){
@Override
void eat() {
System.out.println("小狗吃骨头");
}
};
System.out.println(dog.getClass());
dog.eat();
//远行结果
class com.hspedu.innerclass.Outer04$3
小狗吃骨头
我们要解释这个问题就需要弄明白二点
1、我们这个Animal dog = new Animal()
编译类型是谁?远行类型是谁?<你可能就会想,编译看左边,远行看右边>
编译类型:Animal
远行类型:Animal <错误的!>
那这时候问题来了?抽象类他能实例化吗....很明显他不能啊!他没哪个能力啊!
所以我们用getClass方法一探究竟!
getClass() 返回此 Object 的运行时类 |
原因:
2、其实压根就不是你肉眼看到的玩法,使用javap进行一个反编译:
Compiled from "AnonymousInnerClass.java"
class com.xx.innerclass.Outer04$3 extends com.xx.innerclass.Animal {
final com.hspedu.innerclass.Outer04 this$0;
com.hspedu.innerclass.Outer04$3(com.hspedu.innerclass.Outer04);
void eat();
}
Compiled from "homework04__.java"
final class com.xx.homework.homework04__$1 implements com.xx.homework.Calculator {
com.hspedu.homework.homework04__$1();
public double work(double, double);
}
系统分配的匿名对象 实现/继承 接口/抽象类 >>> 在将匿名对象作为远行类型
补充:匿名对象并不是“真正的匿名”而是由底层去分配
分配:类名$1 Outer04$1 (外部类) 我们无法手动new