匿名对象
概念
- 匿名对象:没有名字的类就
使用场景
- 作为参数传递
ArrayList<Student> list = new ArrayList<Student>(); list.add(new Student("tom",13));
- 对象的方法只调用一次
new Student("tom",13).eat();
内部类
概念
- 内部类:类里边的类
成员内部类
- 定义在成员位置的类
- 成员内部类可以直接使用外部类中的数据
- 格式:
public class Outer{ class Inner{ public void show(){ System.out.println("使用内部类的方法"); } } 调用成员内部类的方法: Outer.Inner inner = new Outer.new Inner(); inner.show
局部内部类
- 定义在局部位置的类
- 格式
public class Outer{ public void show() { final int num = 666; class Inner { public void func() { System.out.println(num); } } new Inner().func(); } }
- 为什么内部类使用局部变量的时候要用final修饰?
– 因为new Inner()当方法show()执行完毕后有可能还在内存中,但是这个对象中的是func()方法使用局部变量num,如果局部变量num没有被final修饰,那么方法执行完就没了,这样就引用了一个不存在的变量,程序就会报错。所以我们要使用fianl延长num变量的生命周期。
使用内部类的场景
- 如果A类只在B类中使用到,那么我们就可以把A类定义成B类的内部类。
匿名内部类
- 接口
public interface Ai { void speak(); }
- 匿名内部类的使用
pulic class Test{ public static void main(String[] args){ /*格式:new 类名/接口名(){重写父类或者父接口中的方法{}表示类, 因为没有类名,并且这个类定义在类里边,所以称之为匿名内部类这个 类的本质是实现了Interesting接口的子类,所以要重写接口中的方法 */ new Ai() { public void speak(){ System.out.println("China is No.1"); } }.speak();
- 使用场景one
– 接口的方法中调用了一次,那么我们就没有必要在重新创建一个类,这个时候直接使用匿名内部类就可以了(参照匿名内部类的使用) - 使用场景two
– 如果在调用方法的时候用接口接受数据,我们可以直接传入一个匿名内部类对象,这样就省去了新建类的麻烦。//格式 public static void show(接口类 inter){ inter.speak(); } //定义接口 public interface Ai { void speak(); } //主方法 public static void main(String[] args) { show(new Ai(){ //调用show方法 public void speak(){ //匿名内部类 System.out.println("chinese is No.1"); } }); } public static void show(Ai ai){ 定义show方法 ai只能使用接口里的方法 ai.speak(); }
个人总结
- 匿名内部类:实现接口,抽象类和普通类的匿名内部类都可以,但是接口和抽象类的方法都必须重写。
- 实用的只有匿名内部类(或者是有抽象方法的抽象类),主要是为了调用(重写了的抽象方法)父类的方法
- 内部类能被private修饰?不能
- 成员内部类能用private修饰的成员变量吗?可以
局部内部类的疑问:
1.定义在方法内的类,方法内创建对象然后调用内部类的方法,实例化对象必须在方法内,内部类外(假如定义在内部类里,那么实例化的时候,进入一个死循环类)
2.匿名内部类的定义 本质是实现了父类接口的子类对象
3.内部类里可以用private修饰成员内容(反正只能通过内部类直接调用,所以权限修饰符对内部类的成员变量没有要求)
匿名内部类的问题
1、为什么不能具有静态成员域和成员函数、静态代码块、static final修饰的引用类型、静态内部类?
答:和实名内部类类似,“静态”意味着与实例对象无关就可以访问,从匿名内部类的使用我们可以看到,其一定会实例化一个对象,此时使用“静态”便毫无意义。static final修饰引用类型的目的:1、不需要实例对象就可访问,2、不希望指针指向改变,匿名内部类的使用方式使1变得毫无意义,所以规定不能用static final修饰引用类型,由于匿名内部类没有名字,想要使用静态内部类必须通过一个匿名内部类的实例对象,与“静态”定义矛盾。
2、为什么不能有自定义构造函数?
答:从class文件中,我们可以看到匿名内部类其实含有编译器自动加上的构造函数,且JVM只调用该构造函数,自定义构造函数无效,另外,匿名内部类名字都没有怎么定义构造函数(滑稽.jpg)?
3、为什么匿名内部类不能有类修饰符?
emmmm,加类修饰符可能与有效域冲突,例如加public,但匿名内部类只在当前作用域或是当前行有效,且这些类修饰符本来就是规定访问范围的,但匿名内部类访问范围已经规定。
4、为什么可以有static final修饰的具有字面量的变量?
其实对于匿名内部类来说,static final与final修饰的具有字面量的变量效果一样,只是初始化时机不一样,保存位置不一样,对于性能没有太多影响,所以保留。