提到内部类我们既熟悉又陌生,我们实际开发中用到的比较少,应用的场景也比较少,但是我们看一些第三方jar时有时候会看看,故此总结一下,如不正确和不全之处希望给位大牛指出。
本文介绍的内容主要为:
1.内部类的基础
2.内部类的应用场景
内部类基础
在java中,可以将一个类定义到另一个类的和一个类的方法中,被成为内部类,内部类大体可以分为4类:成员变量内部类,局部内部类,匿名内部类和静态变量内部类,我们收先介绍一下它们的基本用法:
1.成员变量内部类
成员内部类是最普通的内部类,它的定义为位于另一个类的内部,形如下面的形式:
//类的修饰符 public abstract final final
public class InnerTest {
private InnerClass innerClass = null;
private String name;
public InnerClass getInnerInstance() {
if (innerClass == null) {
innerClass = new InnerClass();
}
return innerClass;
}
public String withOutmethod(){
System.out.println("外部类的方法");
return "1111";
}
//成员变量内部类 修饰符和成员变量类似 public private protected 等等
class InnerClass {
private String address;
public void innerMethod(){
System.out.println("内部类可以任意访问外部类的私有成员变量:"+name);
System.out.println("内部类可以任意访问外部类的方法:"+withOutmethod());
}
}
public static void main(String[] arge) {
//第一种方法
InnerTest innerTest = new InnerTest();
//内部类创建,必须先创建其对应的外部类
InnerTest.InnerClass innerClass = innerTest.new InnerClass();
//第二种
InnerClass innerClass1 = innerTest.getInnerInstance();
//外部类中如果要访问成员内部类的成员,必须先创建一个成员内部类的对象,再通过指向这个对象的引用来访问
String a=innerClass.address;
innerClass.innerMethod();
}
}
总结:内部类可以任意访问外部类的任何成员(成员变量和方法),外部类的只能创建一个成员内部类的对象以后才可以操作内部类的成员。成员变量内部类的修饰符和成员变量的修饰几乎一致。
2.局部内部类
局部内部类是定义在一个方法或者一个作用域里面的类,它和成员内部类的区别在于局部内部类的访问仅限于方法内或者该作用域内。
public class LocalInnerClass {
private int age;
public String name;
public Teacher localMethod(){
//局部内部类 不能使用任何修饰符 和 方法中的成员变量类似
class InnerClass extends Teacher {
private String address;
public void innerMethod(){
}
}
return new InnerClass();
}
}
public class Teacher {
private String name;
private String grade;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getGrade() {
return grade;
}
public void setGrade(String grade) {
this.grade = grade;
}
}
注意:局部内部类不能使用修饰符 和方法中的局部变量类似。使用局部变量的好处是局部内部类可以继承别的类,对外部类再继承别的类没有影响。(java类中是单继承,这样可以间接的实现不继承)
3.匿名内部类
就是没有名称的类,其名称由Java编译器给出,一般是形如:外部类名称+$+匿名类顺序,没有名称也就是其他地方就不能引用,不能实例化,只用一次,当然也就不能有构造器。
匿名类就是利用父类的构造函数和自身类体构造成一个类。
public class Demo {
public static void main(String[] arge) {
//1.接口实现
//接口创建 这种创建的方式需要 在{}中是实现接口中所用不完整的方法 (个人理解其实就是隐形实现接口)
Person person = new Person() {
//获取匿名内部类实例 (没有名字的内部类)
//实现接口的方法
@Override
public void say() {
System.out.println("你好java");
}
//实现接口的方法
@Override
public void eat() {
System.out.println("南方人喜欢吃海鲜");
}
};
person.say();
person.eat();
//抽象类实现
AnonymityInnerClass anonymityInnerClass=new AnonymityInnerClass(){
@Override
public void say(){
System.out.println("匿名内部类实现抽象类");
}
};
anonymityInnerClass.say();
}
}
个人认为匿名内部类是就是new是隐形自我实现不完整的方法。(对方法的扩展)
4.静态内部类
静态内部类也是定义在另一个类里面的类,只不过在类的前面多了一个关键字static。静态内部类是不需要依赖于外部类的,这点和类的静态成员属性有点类似,并且它不能使用外部类的非static成员变量或者方法,这点很好理解,因为在没有外部类的对象的情况下,可以创建静态内部类的对象,如果允许访问外部类的非static成员就会产生矛盾,因为外部类的非static成员必须依附于具体的对象
public class Test {
public static void main(String[] args) {
//静态内部类不需要再创建外部类
Outter.Inner inner = new Outter.Inner();
}
}
class Outter {
public Outter() {
}
static class Inner {
public Inner() {
}
}
}
内部类的应用场景
为什么在Java中需要内部类?总结一下主要有以下四点:
1.每个内部类都能独立的继承一个接口的实现,所以无论外部类是否已经继承了某个(接口的)实现,对于内部类都没有影响。内部类使得多继承的解决方案变得完整,
2.方便将存在一定逻辑关系的类组织在一起,又可以对外界隐藏。
3.方便编写事件驱动程序
4.方便编写线程代码
个人觉得第一点是最重要的原因之一,内部类的存在使得Java的多继承机制变得更加完善。