内部类
在类里面定义的类称之为内部类(Inner Class),内部类是外部类的一个成员。内部类里面和其他类的定义是一样的,内部类里面也可以定义成员变量和成员函数。内部类必须创建外部类对象才能使用。
成员内部类:
- 内部类的访问外部类规则:
- 内部类可以直接访问外部类中的成员,包括私有成员。
- 之所以可以直接访问外部类中的成员,是因为内部类中持有了一个外部类的引用,格式 外部类名.this
- 之所以可以直接访问外部类中的成员,是因为内部类中持有了一个外部类的引用,格式 外部类名.this
- 在外部其他类中,对静态内部类的非静态成员的访问
- new Outer.Inner() .成员名
- 内部类可以直接访问外部类中的成员,包括私有成员。
- 外部类是否能访问内部类?
- 外部类不能访问内部类成员,因为在使用外部类时有可能还没有创建内部类对象。即使创建了,一个外部类对象也可能对应多个内部类对象。
-
如果一定要在外部类中使用内部类成员,那么需要创建内部类对象,通过对象来访问。
内部类中不能定义静态成员。但是静态内部类中可以定义静态成员。
- 外部类不能访问内部类成员,因为在使用外部类时有可能还没有创建内部类对象。即使创建了,一个外部类对象也可能对应多个内部类对象。
- 如果在外部类中定义的有成员变量,在内部类中也定义有同名的成员变量和局部变量,该如何操作这三类数据?
- 操作外部类的成员变量:操作Outer.this.成员变量名
- 操作内部类的成员变量:操作this.成员变量名
- 操作局部成员变量:直接操作成员变量名
- 如何建立内部类对象:
- 当内部类定义在外部类的成员位置上,而且非私有,可以在外部其他类中直接建立内部类对象;
- 外部类名.内部类名变量名 变量名 = new 外部类名().new 内部类名();
- 注:其中new 外部类名()可以用外部类的一个对象代替。总之内部类必须创建外部类对象才能使用。
- 内部类的特点:
- 当内部类在外部类的成员位置上,就可以被成员修饰符所修饰。
- 比如,private:将内部类在外部类中进行封装
- static:该内部类就具有静态的特性。但是只能直接访问外部类的静态成员。
- 当内部类在外部类的成员位置上,就可以被成员修饰符所修饰。
- 内部类什么时候定义?
- 当描述事物时,事物的内部还有事物,该事物用内部类来描述。并且一般内部类需要封装在外部类里面。
- 示例(演示以上第三点的内容)
class Outer { private int x = 3; class Inner//内部类 { int x = 4; void setOutX(int x)//设置外部类成员x的值, { Outer.this.x = x;//操作外部类成员变量用 Outer。this。成员变量名 } void setInX(int x)//设置内部类成员x的值, { this.x = x; //操作内部类成员变量用 this.成员变量名 } void getOutX()//获取外部类中x的值, { //操作外部类成员变量用 Outer。this。成员变量名 System.out.println("Outer x = "+Outer.this.x); } void getInX()//获取外部类中x的值, { //操作内部类成员变量用 this.成员变量名 System.out.println("Inner x = "+this.x); } } } class InnerClassDemo { public static void main(String[] args) { Outer out = new Outer(); Outer.Inner in = out.new Inner(); in.setOutX(22); //设置外部类成员变量的x的值,然后打印输出 in.getOutX(); in.setInX(33); //设置内部类成员变量x的值,然后打印输出。 in.getInX(); } }
局部内部类(
方法中的内部类):
- 定义在方法中的类只能在方法中使用,而且使用的代码只能在声明的代码下面。
- 方法中定义的内部类不能访问方法中定义的局部变量,除非这个局部变量被声明为final的。
- 方法中的内部类创建的对象有可能生命周期比这个局部变量长,例如这个对象被作为返回值返回,那么方法运行结束之后还可以访问这个对象。这时变量被销毁了,对象还在,如果在对象的某个方法内访问这个变量就访问不到了。但是被final修饰的变量会一直存储在内存中,方法运行结束之后不被销毁。
- 方法中的内部类创建的对象有可能生命周期比这个局部变量长,例如这个对象被作为返回值返回,那么方法运行结束之后还可以访问这个对象。这时变量被销毁了,对象还在,如果在对象的某个方法内访问这个变量就访问不到了。但是被final修饰的变量会一直存储在内存中,方法运行结束之后不被销毁。
匿名内部类:
实际就是内部类的简写格式,就是一个匿名子类对象。
- 定义内部类的前提:
- 必须继承一个类或者一个接口。
- 内部类的创建方法:
-
使用 new 父类名(){类定义} 形式声明,先创建一个指定类的子类,然后根据这个类创建一个对象。
-
- 内部类在什么时候创建?
- 如果一个类只使用一次,那么可以定义为匿名内部类。
- 代码示例(演示内部类的建立以及调用方法)
abstract class AbsDemo //定义一个被内部类继承的抽象类 { abstract void show(); } class Outer //外部类 { int x = 3; public void function() { new AbsDemo() //建立匿名内部类并调用show()方法 { int num = 9; void show() { System.out.println("num==="+num); } }.show(); } } class InnerClassDemo4 { public static void main(String[] args) { new Outer().function(); } }