一、内部类的分类
二、普通内部类(后面简称内部类)和嵌套类在创建时的区别
三、Java为什么引入内部类,利用内部类能解决什么问题?
四、匿名内部类中被直接使用的变量要被final关键字修饰
一、内部类的分类
内部类根据是否为static可以分为两大类:
1、内部类(普通内部类对象隐式地保存了一个引用,指向创建它的外围类对象,为了内部类可以操作外围类的数据)
2、嵌套类(当内部类是static的嵌套类时,不会具有这个引用了)
内部类又可以分为三种:
1、普通内部类 (定义在外围类的作用域下)
2、局部内部类 (与普通内部内定义的作用域不同,普通内部类一般定义在外围类的作用域,而局部内部内部类可以在方法的作用域内或一般的作用域内创建)
3、匿名内部类(没有显示声明类的名称的内部类称为匿名内部类)
二、普通内部类(后面简称内部类)和嵌套类在创建时的区别
嵌套类的创建:必须通过 new 外围类.内部类() 的方式来创建。
内部类的创建:基本是通过 外围类对象引用.new 内部类() 的方式来创建,不过在定义该内部类的外围内中如果需要创建内部类对象的话也可以通过 new 外围类.内部类() 的方式来创建。
注:为什么在内部类的外围类中创建内部类的时候也可以通过 new 外围类.内部类() 来创建那? 这是因为内部是需要其外围类的对象来创建的,所以基本上是通过 外围类对象引用.new 内部类() 的方式来创建的,
不过如果在定义该内部类的外围类中创建该内部类的话,如果能执行到该段代码的时候,说明该外围类已经存在了,所以这里就不用非得创建一个外围类的对象引用来创建内部类对象了(当然如果你愿意也可以)。像 外围类对象引用.new 内部类() 这种创建方式就是告诉编译器,该内部类是通过其外围类的对象引用创建的,因为编译器在创建内部类的时候也要求你必须创建一个该内部类的外围类的对象引用。
三、Java为什么引入内部类,利用内部类能解决什么问题?
个人简单总结一下为什么引入内部类,内部类的作用:
1、可以解决Java不允许的多重继承问题,如果某个类在功能上需要同时继承两个类的功能,那么就可以通过外围类继承一个类,然后通过内部类继承另外一个类。
2、可以解决实现两个或多个接口的时候,如果这两个接口包含了相同的方法签名时,如果子类实现了任何一个接口的该方法那么就无法实现另外一个接口的该方法,这样的话两个接口共用了同一个方法,就无法实现java中的多态(父类引用调用子类对象的效果了),所以这时候可以将另外一个接口通过内部类来实现。
有时候我们会想即使不通过内部类,如果我想让某个类同时具有两个接口的功能时,可以通过另外一个类来实现第二个接口,通过创建对象的方式来调用对应的方法也可以啊?这里需要注意的是内部具有一个非常重要的特点它具有一个默认指向外围类的引用,并且可以随意访问外围类的任何方法和属性,就相当于外围类的一个特殊方法似的,通过外围类的某个方法调用内部类对象的对应方法来修改外围类属性的方法可以完全使用着实现透明的类似多继承的功能。例如:
interface A {}
interface B {
void getMoney();
}
class OtherClass implements B {
public void getMoney() {
System.out.println("其它类实现接口方式根本无法获取到年龄和金钱属性的值");
}
}
public class TestWhyImportInnerClass implements A {
private int age;
private int money;
class InnerClass implements B {
public void getMoney() {
//内部类能获取和修改外围类的属性和变量,所以内部类相当于外围类的一些超级方法的总和
money = age * 100;
System.out.println("内部类的money:" + money);
}
}
public void getMoney() {
TestWhyImportInnerClass.InnerClass innerClass = new TestWhyImportInnerClass.InnerClass();
innerClass.getMoney();
}
public static void main(String[] args) {
TestWhyImportInnerClass test = new TestWhyImportInnerClass();
test.age = 10;
test.getMoney();
OtherClass otherClass = new OtherClass();
otherClass.getMoney();
/* 内部类的money:1000
其它类实现接口方式根本无法获取到年龄和金钱属性的值*/
}
}
四、匿名内部类中被直接使用的变量要被final关键字修饰