什么是内部类
把类定义在另一个类的内部,该类就被称为内部类。
如果在类 Outer 的内部再定义一个类 Inner,此时类 Inner 就称为内部类(或称为嵌套类),而类 Outer 则称为外部类(或称为宿主类)。
这里纠正一个误区,如下图代码
public class Inner {
}
class Demo{
}
这并不是内部类,这个只是在同一个 . java文件中创建了两个类。
内部类一般来说包括这四种:成员内部类、静态内部类、局部内部类、匿名内部类。
成员内部类
成员内部类就是位于外部类成员位置的类
特点:可以使用外部类中所有的成员变量和成员方法(包括private的)
public class Outer {//外部类
private int age=20;
class Inner{//内部类
public void show(){
System.out.println(age);//可以使用外部类的方法和变量
}
}
}
public class Text {
public static void main(String[] args) {
Outer.Inner in=new Outer().new Inner();//通过外部类才能引出内部类
in.show();
}
}
静态内部类
这种被 static 所修饰的内部类,按位置分,属于成员内部类,但也可以称作静态内部类,也常叫做嵌套内部类.不能使用外部类的非static成员变量和成员方法
public class Outer {
private int age=20;
private static int num=100;
/*public Inner creat(){
return new Inner();
}*/
static class Inner{//静态内部类
public void show(){
//System.out.println(age);
System.out.println(num);//不能调用非静态的外部类成员
}
}
}
public class Text {
public static void main(String[] args) {
Outer.Inner inner=new Outer.Inner();
inner.show();
}
}
private修饰内部类;
如果我们的内部类不想轻易被任何人访问,可以选择使用private修饰内部类,这样我们就无法通过创建对象的方法来访问,想要访问只需要在外部类中定义一个public修饰的方法,间接调用。这样做的好处就是,我们可以在这个public方法中增加一些判断语句,起到数据安全的作用。
public class Outer {
private int age=20;
private static int num=100;
private Inner creat(){
return new Inner();
}
private class Inner{//如果内部类由private修饰,那么外部无法直接访问到此类。
public void show(){
System.out.println(age);
}
}
public static void main(String[] args) {
Outer outer=new Outer();
Outer.Inner inner=outer.creat();//通过创建外部类对象,在调用外部类的创建内部类的方法,才能调用内部类。
inner.show();
}
}
局部内部类
局部内部类——就是定义在一个方法或者一个作用域里面的类。
特点:主要是作用域发生了变化,只能在自身所在方法和属性中被使用。
局部内部类用的情况很少,我们只需要简单了解一下就够了。
匿名内部类
一个没有名字的类,是内部类的简化写法。
public class Car {
private int num;
private String name;
public Car(int num, String name) {
this.num = num;
this.name = name;
}
public int getNum() {
return num;
}
public void setNum(int num) {
this.num = num;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public String toString() {
return "Car{" +
"num=" + num +
", name='" + name + '\'' +
'}';
}
}
public class CarText {
public static void main(String[] args) {
Car car=new Car(111,"宝马");
Car car1=new Car(222,"宝马");
Car car2=new Car(333,"宝马");
Car car3=new Car(444,"宝马");
Car[]cars={car2,car1,car,car3};//创立一个Car类型数组,并将没有乱序的对象插入其中
Arrays.sort(cars, new Comparator<Car>() {//使用内部类的方式,创立了一个接口内部类对象。即匿名内部类
@Override
public int compare(Car o1, Car o2) {
return o1.getNum()-o2.getNum();
}
});
Arrays.sort(cars,(o1, o2) ->{//比上面匿名内部类更简洁的方法,lambda方法。两者作用一样
return o1.getNum()-o2.getNum();
});
System.out.println(Arrays.toString(cars));
}
}
内部类的特点
1. 内部类仍然是一个独立的类,在编译之后内部类会被编译成独立的.class文件,但是前面冠以外部类的类名和$符号。
2. 内部类不能用普通的方式访问。内部类是外部类的一个成员,因此内部类可以自由地访问外部类的成员变量,无论是否为 private 的。
3. 内部类声明成静态的,就不能随便访问外部类的成员变量,仍然是只能访问外部类的静态成员变量。
内部类的意义
1. 封装性:有的时候我们写的东西要对访问者权限做出一定的限制,所以便采用了内部类的方式将一些不愿意给别人看的东西隐藏起来。
2.间接性的实现多继承功能。