内部类概述:
把类定义在其他类的内部,这个类就被称为内部类。
举例:在类A中定义了一个类B,类B就是内部类。
class Outer{
class Inner{ //Inner就是内部类
........
}
}
内部的访问特点:
A:内部类可以直接访问外部类的成员,包括私有。
B:外部类要访问内部类的成员,必须创建对象。
class Outer{
private int num = 10;
class Inner{
public void show(){
System.out.println(num); //内部类可以直接访问外部类的成员,包括私有。
}
}
public void method(){
Inner i = new Inner();
i.show(); //外部类要访问内部类的成员,必须要创建对象。
}
}
内部类的位置:
成员内部类:在成员位置定义的内部类
class Outer{
private int num = 10;
class Inner{
.......
}
public void method(){
........
}
}
局部内部类:在局部位置定义,在成员方法内定义的。
class Outer{
private int num = 10;
public void method(){
class Inner{
...........
}
}
}
成员内部类
访问成员内部类的成员:
1.直接在外部访问。不常见,因为不安全。
外部类名.内部类名 对象名 = 外部类对象.内部类对象
class Outer{
private int num = 10;
class Inner{
public void show(){
System.out.println(num);
}
}
}
class InnerclassDemo{
public static void main(String[] args){
Outer.Inner oi = new Outer().new Inner();
oi.show();
}
}
- 使用private关键字修饰内部类。常见。为了保证数据安全性。
class Body{
private class Heart{
public void operator(){
System.out.println("心脏搭桥");
}
}
public void method(){
if(是外科医生){
Heart h = new Heart();
h.operator();
}
}
}
.....
Body b = new Body();
b.method();
- 内部类看做是外部类的成员,所以可以用static修饰。为了方便访问数据。
class Outer{
private static int num = 10; //静态内部类访问的外部数据必须用static修饰。
public static class Inner{
public void show(){
System.out.println(num);
}
public static void show2(){
System.out.println(num);
}
}
}
......
//外部类名.内部类名 对象名 = new 外部类名.内部类名();
Outer.Inner oi = new Outer.Inner();
oi.show();
oi.show2();
Outer.Inner.show2(); //show2的另一种调用
面试题:
分别输出30,20,10
class Outer{
public int num = 10;
class Inner{
public int num = 20;
public void show(){
int num = 30;
System.out.println(num); //就近原则,打印30
System.out.println(this.num); //this表示当前类的引用。当前类是Inner。 20
System.out.println(new Outer().num); //创建Outer对象访问。
System.out.println(Outer.this.num); //通过外部类名限定this对象。outer.this
}
}
}
内部类和外部类没有继承关系。
局部内部类
class Outer{
private int num = 10;
public void method(){
//int num2 = 20;
final int num2 = 20; //局部变量必须被final修饰,才可以被内部类访问。
class Inner{
public void show(){
System.out.println(num); //可以直接访问外部类的成员
System.out.println(num2); //访问的局部变量必须被final修饰。加了final修饰之后,直接被替换为常量。
}
}
Inner i = new Inner(); //在局部位置,创建内部类对象,
i.show(); //通过对象调用内部类方法。
}
}
.........
Outer o = new Outer();
o.method();
局部变量是随着方法的调用而调用,随着方法调用完毕而消失。而堆内存的内容并不会立即消失,所以,加final修饰。加final修饰后,这个变量就成了常量,既然是常量,所以虽然成员变量消失了,但是在内存存储的数据是20而不是num2。
匿名内部类
匿名内部类是内部类的简化写法。