概述
在Java中,可以将一个类定义在另一个类里面或者一个方法里边,这样的类称为内部类,广泛意义上的内部类一般包括四种:
成员内部类
该类像是外部类的一个成员,可以无条件的访问外部类的所有成员属性和成员方法(包括private成员和静态成员);
成员内部类拥有与外部类同名的成员变量时,会发生隐藏现象,即默认情况下访问的是成员内部类中的成员。如果要访问外部类中的成员,需要以下形式访问:【外部类.this.成员变量 或 外部类.this.成员方法】;
在外部类中如果要访问成员内部类的成员,必须先创建一个成员内部类的对象,再通过指向这个对象的引用来访问;
成员内部类是依附外部类而存在的,也就是说,如果要创建成员内部类的对象,前提是必须存在一个外部类的对象;
内部类可以拥有private访问权限、protected访问权限、public访问权限及包访问权限。如果成员内部类用private修饰,则只能在外部类的内部访问;如果用public修饰,则任何地方都能访问;如果用protected修饰,则只能在同一个包下或者继承外部类的情况下访问;如果是默认访问权限,则只能在同一个包下访问。外部类只能被public和包访问两种权限修饰。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53
| public class OuterClass { private String str; public static final String testStr = "琦玉";
public OuterClass(String str) { this.str = str; }
public String testArea() { return str; }
class InnerClass { private String str;
public InnerClass(String str) { this.str = str; }
public String testArea() { return str; }
private String test() { System.out.println(OuterClass.this.str); System.out.println(testStr); return OuterClass.this.testArea(); } }
public static void main(String[] args) { OuterClass outerClass = new OuterClass("外部类"); InnerClass innerClass = outerClass.new InnerClass("局部内部类"); System.out.println(outerClass.testArea()); System.out.println(innerClass.test()); System.out.println(innerClass.testArea());
} }
|
局部内部类
- 局部内部类是定义在一个方法或者一个作用域里面的类,它和成员内部类的区别在于局部内部类的访问仅限于方法内或者该作用域内;
- 局部内部类就像是方法里面的一个局部变量一样,是不能有public、protected、private以及static修饰符的。
这个局部内部类太鸡肋了,应该都不怎么使用,定义的时候和普通的class是一样的,除了不能用修饰符,还有作用域太小了吧,谁没事在代码块中定义一个局部内部类啊。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29
| public class OuterClass { public static void memberFunction() { class PartInnerClass { private static final String str = "aaa"; private String str1 = "sss";
public PartInnerClass(String str1) { this.str1 = str1; }
public String test() { return str1; } } PartInnerClass innerClass = new PartInnerClass("局部内部类"); System.out.println(innerClass.test()); }
public static void main(String[] args) { memberFunction();
} }
|
匿名内部类
因为匿名内部类为局部内部类,所以局部内部类的所有限制都对其生效。
实现方式
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| public class OuterClass { public static void main(String[] args) { Thread thread = new Thread() { private static final String str = "匿名内部类通过继承实现"; @Override public void run() { System.out.println(str); } }; thread.run();
} }
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| public class OuterClass { public static void main(String[] args) { Runnable runnable = new Runnable() { private static final String str = "匿名内部类通过接口实现"; @Override public void run() { System.out.println(str); } }; runnable.run();
} }
|
静态内部类
静态内部类如果去掉关键字static就变成了成员内部类,成员内部类是非静态内部类它可以自由的引用外部类的属性和方法,无论这些属性和方法是静态的还是非静态的。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40
| public class OuterClass { private String str;
public static final String testStr = "琦玉";
public OuterClass(String str) { this.str = str; }
private static class InnerClass { private String str;
private static final String str1 = "静态内部类的静态参数";
public InnerClass(String str) { this.str = str; }
private String test() { System.out.println(testStr); return str; } }
public static void main(String[] args) { InnerClass innerClass = new InnerClass("静态内部类"); System.out.println(innerClass.test());
} }
|
理解
这些内部类根本不用记,从名字上就可以知道意思;
成员内部类:这个就想成类的成员变量,成员变量能被各种访问符修饰,这个自然可以,成员变量依赖类的实例化,这个也依赖于外部类啊。
静态内部类:了解了成员内部类,加一个static修饰就是静态内部类了啊,就相当于普通的成员变量,加一个static修饰不就变成,类变量了,类变量,类方法不依赖类的实例变量,只能调用类中静态方法和静态变量,那么这个静态内部类也不就一样,就不依赖于外部类,直接new,只能用外部类的静态方法和静态变量。
局部内部类:局部内部类这个更加见名知意了,局部的,在一个方法中,或者代码块中,仅仅在这个中生效,就想象成方法中定义的一个局部变量,怎么可能用修饰符修饰。
匿名内部类:这个也见名知意,就是没有名字的内部类,为什么没有名字,肯定是new xxx() {} 重写方法或者实现接口中的方法,这个用的比较多应该熟悉。
- 成员内部类===》类的成员变量
- 静态内部类===》类的类变量
- 局部内部类===》方法的局部变量
- 匿名内部类===》。。。。
实际上我感觉对普通的程序员来说这些内部类就偶尔用一用匿名内部类吧,看那jdk源码中发现用了很多成员内部类,和静态内部类。我反正没怎么用过,比较low,我对内部类的理解仅此而已,仅仅是知道些特性,到底该怎么用,何时去用还差一点感觉。