内部类最重要的三点:
1.什么是内部类 2.内部类的分类 3.内部类意义
一.什么是内部类
概念: 把类定义在另一个类的内部,该类就被称为内部类。
如果在一个类的内部再定义一个类,此时类这个类 就称为内部类(或称为嵌套类),而类则称为外部类(或称为宿主类)
先说不是内部类的情况:
//这种不是内部类,只是在.java中创建了俩个类
public class demo1 {
public static void main(String[] args) {
}
}
class demo2{
}
这只是定义了俩个类
二.内部类的分类
内部类一般来说包括这四种:
成员内部类
静态内部类
局部内部类
匿名内部类
1.成员内部类:
成员内部类在外部类里面,它充当的是一个外部类的成员或者方法,,并且可以使用外部类的所有私有的和非私有的成员变量和方法
class Outer {
private int age = 20;
class Inner {
public void show() {
System.out.println(age);
}
}
}
class Test {
public static void main(String[] ages) {
Outer.Inner oi = new Outer().new Inner();
oi.show();
}
}
也可以使用private来 修饰内部类,这样不会让别人轻易访问到内部类.
如果想要访问只需要在外部类中定义一个public方法来间接调用
class Outer {
private class Inner {
public void show() {
System.out.println(“你好”);
}
}//使用get()获取成员内部类
public Inner getInner() {
return new Inner();
}
}
public static void main(String[] args) {
Outer outer = new Outer();
Outer.Inner inner = outer.getInner();
inner.show();
}
2.静态内部类
被static修饰的内部类称作静态内部类,它不可以使用外部类中的非静态成员成员方法和非静态成员变量
public class outer {
int mun=10;
private static int num=10;
public void eat(){
new inner();//一般在本类中使用内部类
}
//在一个类的内部定义的类叫做内部类
//静态内部类只能访问外部类的静态成员,因为外部类在加载时静态方法就加载了,而非静态的只有类加载后才可以使用
public static class inner{
public void a(){//在内部类中可以直接使用外部类中农的成员,包括私有的
System.out.println(num);
}
}
public static void main(String[] args) {
}
}
3.局部内部类
一般定义在方法中或者一个作用域中
1. 可以直接访问 外部类 的所有成员,包括 私有的;
2. 局部内部类 的地位相当于一个局部变量,因此不能添加访问修饰符 但可以使用final进行修饰;
3. 作用域 : 仅仅在定义它的方法或代码块中有效;
4. 局部内部类 访问 外部类的成员 : 直接访问即可;
5. 外部类 访问 局部内部类的成员 : 创建对象 -> 通过对象进行访问,
注意 : 需要在局部内部类的作用域中才可以;
6. 如果 外部类 和 局部内部类 的成员重名时,默认遵循就近原则,
如果就是想访问 外部类的成员时,使用 外部类名.this.成员 的方式
4.匿名内部类
2. 局部内部类 的地位相当于一个局部变量,因此不能添加访问修饰符 但可以使用final进行修饰;
3. 作用域 : 仅仅在定义它的方法或代码块中有效;
4. 局部内部类 访问 外部类的成员 : 直接访问即可;
5. 外部类 访问 局部内部类的成员 : 创建对象 -> 通过对象进行访问,
注意 : 需要在局部内部类的作用域中才可以;
6. 如果 外部类 和 局部内部类 的成员重名时,默认遵循就近原则,
如果就是想访问 外部类的成员时,使用 外部类名.this.成员 的方式
4.匿名内部类
一个没有名字的类,是内部类的简化写法 .
我们以一个Car为例吧:
public class Car {
private String name;
private int num;
public Car(String name, int num) {
this.name = name;
this.num = num;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getNum() {
return num;
}
public void setNum(int num) {
this.num = num;
}
@Override
public String toString() {
return "Car{" +
"name='" + name + '\'' +
", num=" + num +
'}';
}
}
上面是Car类的一些基本定义
创建对象后要对这集合car类对象进行排序输出,一般方法是写一个类,来继承comparable接口,然后重写这个接口里面的排序方法, 然后对car对象进行排序.
有了匿名内部类后,可以在一个类的内部对car类对象进行排序操作,并且可以简化内部类的写法
public class text {
public static void main(String[] args) {
Car car1 = new Car("宝马1",1);
Car car2 = new Car("宝马2",2);
Car car3 = new Car("宝马3",3);
Car car4 = new Car("宝马4",4);
Car[]cars = {car2,car3,car1,car4};
//Arrays.sort(cars, new compar());//这种情况是出创建了一个类继承接口来实现排序
Arrays.sort(cars, new Comparator<Car>() {
@Override
public int compare(Car o1, Car o2) {//匿名内部类
return 0;
}
});
System.out.println(Arrays.toString(cars));
三.内部类的特点
1.内部类仍然是一个独立的类,在编译之后内部类会被编译成独立
的
.class
文件,但是前面冠以外部类的类名和
$
符号。
2.
内部类不能用普通的方式访问。内部类是外部类的一个成员,因此内部
类可以自由地访问外部类的成员变量,无论是否为
private
的。
3.
内部类声明成静态的,就不能随便访问外部类的成员变量,仍然是只能
访问外部类的静态成员变量
。
四.
内部类的意义
1.封装性: 将其隐藏起来
2.多继承性:
间接实现多继承,假如定义俩个Father和Mom类,再创建一个Son类,要同时继承他们俩个类,那么就应该在Son类定义俩个内部类,分别继承Father和Mom类,来实现多继承