参考博客:
Java内部类详解。 java提高篇(八)----详解内部类。 Java内部类的定义和使用 - 易小怪兽_iKing。
1. 内部类基础
内部类:将一个类定义在另一个类里面或者一个方法里面;
成员内部类、局部内部类、匿名内部类、静态内部类
1.1 成员内部类 : 位于另一个类的内部
class Circle {
private double radius = 0;
public static int count =1;
public Circle(double radius) {
this.radius = radius;
}
class Draw { //内部类
public void drawSahpe() {
System.out.println(radius); //外部类的private成员
System.out.println(count); //外部类的静态成员
}
}
}
1) 成员内部类可以无条件访问外部类的所有成员属性和成员方法(包括private成员和静态成员)。
2) 当成员内部类和外部类有同名的成员变量或者方法时,默认访问内部类的成员。如果要访问外部类的同名成员,则:
外部类.this.成员变量
外部类.this.成员方法
3) 在外部类中要访问内部类的成员,必须先创建一个成员内部类的对象,再通过指向这个对象的引用来访问
4) 创建成员内部类的对象,前提:存在一个外部类的对象
public class Test {
public static void main(String[] args) {
//第一种方式:
Outter outter = new Outter();
Outter.Inner inner = outter.new Inner(); //必须通过Outter对象来创建
//第二种方式:
Outter.Inner inner1 = outter.getInnerInstance();
}
}
class Outter {
private Inner inner = null;
public Outter() {
getInnerInstance().Inner_f(); //必须先创建成员内部类的对象,再进行访问内部类的成员
}
public Inner getInnerInstance() {
if(inner == null)
inner = new Inner();
return inner;
}
class Inner {
public Inner_f() {
}
}
}
2. 局部内部类
定义在一个方法或者一个作用域里面的类,访问仅限于方法内或者该作用域内。局部内部类就像是方法里面的一个局部变量一样,是不能有public、protected、private以及static修饰符的。
class People{
public People() {
}
}
class Man{
public Man(){
}
public People getWoman(){
class Woman extends People{ //局部内部类
int age =0;
}
return new Woman();
}
}
3. 匿名内部类
在做Swing编程中,用这种方式来绑定事件button2.addActionListener(
new ActionListener(){ // 匿名内部类是没有访问修饰符的
public void actionPerformed(ActionEvent e) {
System.out.println("你按了按钮二");
}
});
1) 这个内部类是没有名字的。。所以 匿名内部类是没有构造方法的;
2) 匿名内部类是没有访问修饰符的;
public class OuterClass {
public InnerClass getInnerClass(final int num,String str2){ // 形参需要被匿名内部类使用,这个形参为final
return new InnerClass(){
int number = num + 3;
public int getNumber(){
return number;
}
}; /* 注意:分号不能省 */
}
public static void main(String[] args) {
OuterClass out = new OuterClass();
InnerClass inner = out.getInnerClass(2, "chenssy");
System.out.println(inner.getNumber());
}
}
interface InnerClass { // 接口
int getNumber();
}
----------------
Output: 5
3) 形参需要被匿名内部类使用,这个形参为
final;
4) 一个类用于继承其他类或是实现接口,并不需要增加额外的方法,只是对继承方法的事先或是覆盖。
4. 静态内部类
1) 多了一个关键字static。静态内部类是不需要依赖于外部类的;2) 它不能使用任何外围类的 非static 成员变量和方法,
public class OuterClass {
private String sex;
public static String name = "chenssy";
/** 静态内部类 */
static class InnerClass1{
public static String _name1 = "chenssy_static"; /* 在静态内部类中可以存在静态成员 */
public void display(){
System.out.println("OutClass name :" + name); //静态内部类只能访问外围类的 静态 成员变量和方法
}
}
/** 非静态内部类 */
class InnerClass2{
public String _name2 = "chenssy_inner"; // 非静态内部类中不能存在静态成员
public void display(){
System.out.println("OuterClass name:" + name);
} // 非静态内部类中可以调用外围类的任何成员,不管是静态的还是非静态的
}
/** 外围类方法 */
public void display(){
System.out.println(InnerClass1._name1); // /* 外围类访问静态内部类:内部类. */
new InnerClass1().display(); /* 静态内部类 可以直接创建实例不需要依赖于外围类 */
OuterClass.InnerClass2 inner2 = new OuterClass().new InnerClass2(); /* 非静态内部的创建需要依赖于外围类 */
System.out.println(inner2._name2); /* 方位非静态内部类的成员需要使用非静态内部类的实例 */
inner2.display();
}
public static void main(String[] args) {
OuterClass outer = new OuterClass();
outer.display();
}
}
----------------
Output:
chenssy_static
OutClass name :chenssy
chenssy_inner
OuterClass name:chenssy
内部类总结:
1. 内部类作为外部类的一个特殊的成员来看待,因此它有类成员的封闭等级:private ,protected,默认(friendly),public 它有类成员的修饰符: static,final,abstract;
2. 非静态内部类nested inner class,内部类隐含有一个外部类的指针this,因此,它可以访问外部类的一切资源(当然包括private)外部类访问内部类的成员,先要取得内部类的对象,并且取决于内部类成员的封装等级。非静态内部类不能包含任何static成员;
3. 静态内部类:static inner class,不再包含外部类的this指针,并且在外部类装载时初始化. 静态内部类只能访问外部类static成员. 外部类访问静态内部类的成员:static成员:类名.成员;非static成员:对象.成员
4. 对于方法中的内部类或块中内部类只能访问块中或方法中的final变量。