内部类
优点:
1.内部类与外部类可以方便的访问彼此的私有域(包括私有方法、私有属性)。
2.内部类是另外一种封装,对外部的其他类隐藏。
3.内部类可以实现java的单继承局限。
缺点:
1.结构复杂。
分类:
- 成员内部类
- 局部内部类
- 匿名内部类
- 静态内部类(到这里就有个问题:java一般类能不能用static修饰呢?)
编译器不允许最外层的类声明为static,但是可以声明内部类为static。
一、成员内部类
我感觉这是比较常见的,类Pet像是类Person的一个成员,Person称为外部类。成员内部类可以无条件访问外部类的所有成员属性和成员方法(包括private成员和静态成员)。
class Person{
public String name;
public int age;
public Person(){}
public Person(String name, int age) {
this.name = name;
this.age = age;
}
//内部类作为外部类的成员;
public class Pet{
public String name;
public int age;
public Pet() {}
public Pet(String name, int age) {
this.name = name;
this.age = age;
}
}
}
注意:成员内部类内部不允许存在任何static变量或方法 正如成员方法中不能有任何静态属性 (成员方法与对象相关、静态属性与类有关),静态成员内部类内部方法不允许访问外部非静态成员。
内部类就相当于一个外部bai类的成员变量,du所以可以直接访问外部变量,外部类不能直接访问内部类变量,必须通过创建内部类实例的方法访问,
new InnerClass(32).m就是创建内部类实例访问内部类成员变量。
你想不通的肯定是指内部类的私有变量怎么可以被外部类访问吧,按常规,私有变量m只能在InnerClass里被访问,但你要注意,内部类就相当于一个外部类的成员变量,举个例子:
class Outer{
private int m;
private class Inner{
private int n;
private int k;
}
}
m和类Inner都是成员变量,他们之间是平等的,唯一不同的就是Inner它是包装了几个成员变量比如n,k,也就是说m、n、k是平等的,区别在于访问n k要通过Inner,就是要建立Inner实例访问n、k.
二、静态内部类
public class Outer {
//定义一个实例变量和一个静态变量
private int a;
private static int b;
//定义一个静态方法和一个非静态方法
public static void say(){}
public void test(){
//在外部类中调用内部类的属性和方法
Outer.Inner.c = 1; //可以通过静态内部类的全类名来调用静态内部类的静态属性(外部类名.静态内部类名.属性)
Outer.Inner.go(); //可以通过静态内部类的全类名来调用静态内部类的静态方法(外部类名.静态内部类名.方法)
//Outer.Inner.walk(); //不能通过类静态内部类的全类名来调用内部类的非静态属性和方法
Inner inner = new Inner();
inner.d = 1;
inner.walk(); //可以通过创建内部类实例来调用静态内部类的非静态属性和方法
}
//静态内部类
public static class Inner{
//在静态内部类中定义一个静态变量和一个实例变量
static int c;
int d;
//定义一个匿名代码块和一个静态代码块
{}
static{}
//定义一个静态方法和一个普通方法
public static void go(){}
public void walk(){
//在静态内部类中调用外部类的属性和方法
int f = b; //可以直接调用外部类的静态属性
say(); //可以直接调用外部类的静态方法
//int e = a; 直接调用外部类的非静态属性出错编译出错
//test(); 直接调用外部类的非静态方法时编译出错
Outer outer = new Outer();
int e = outer.a; //可以通过创建外部类实例来调用外部类的非静态属性
outer.test(); //可以通过创建外部类实例来调用外部类的非静态方法
}
}
}
----参考https://www.cnblogs.com/heavenplus/p/9451181.html
三、局部内部类
局部内部类是定义在一个方法或者一个作用域里面的类,它和成员内部类的区别在于局部内部类的访问仅限于方法内或者该作用域内。
注意,局部内部类就像是方法里面的一个局部变量一样,是不能有public、protected、private以及static修饰符的。
- 在方法中定义内部类:
注意:即使是方法中定义的内部类也是可以像非静态内部类访问外部类一样,用外部类对象.方法()来访问。
四、匿名内部类
匿名内部类应该是平时我们编写代码时用得最多的,在编写事件监听的代码时使用匿名内部类不但方便,而且使代码更加容易维护。
详细例子可见Java基础图形界面类内分开设置各种按钮的键盘事件时。
五、内部类的创建
4.1 在外部类外部 创建非静态内部类
语法: 外部类.内部类 内部类对象 = new 外部类().new 内部类();
举例: Outer.Inner in = new Outer().new Inner();
4.2 在外部类外部 创建静态内部类
语法: 外部类.内部类 内部类对象 = new 外部类.内部类();
举例: Outer.Inner in = new Outer.Inner();
4.3 在外部类内部创建内部类语法
在外部类内部创建内部类,就像普通对象一样直接创建:
Inner in = new Inner();
文章总结:内部类的应用:
- 每个内部类都能独立的继承一个接口的实现,所以无论外部类是否已经继承了某个(接口的)实现,对于内部类都没有影响。内部类使得多继承的解决方案变得完整,
- 方便将存在一定逻辑关系的类组织在一起,又可以对外界隐藏。
- 方便编写事件驱动程序
- 方便编写线程代码
参考:
https://www.cnblogs.com/dolphin0520/p/3811445.html(详细)
https://www.cnblogs.com/heavenplus/p/9451181.html
https://blog.youkuaiyun.com/zhao_miao/article/details/83245816