开发工具与关键技术: 内部类
作者:邓崇富
撰写时间:2019 年 5 月 5 日
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
成员内部类:
在一个类中使用内部类,可以在内部类中直接存取其所在类的私有成员变量。
成员内部类的语法如下:
public class Test1 {//外部类
private class Test2{//内部类
}
}
下面来看下面的实例,创建一个Test1类,再在Test1类中创建一个Test2内部类和方法,在主方法中创建Test1类的实例化对象和do1方法。
public class Test1 {// 外部类
// 在外部类实例化内部类对象引用
Test2 in = new Test2();
//外部类的方法
public void dos() {
// 在外部类方法中调用内部类的方法
in.does();
}
private class Test2 {// 内部类
Test2() { // 内部类的构造器
}
// 内部类成员方法
public void does() {
}
int x = 0; // 定义内部类的成员变量
}
public Test2 do1(){//外部类方法,返回值为内部类引用
in.x = 4; //外部类可以直接访问内部类成员变量
return new Test2();//返回内部类引用
}
public static void main(String[] args) {
Test1 test1 = new Test1();
//内部类的对象实例化操作必须在外部类或外部类的非静态方法中实现
Test1.Test2 in = test1.do1();
Test1.Test2 in1 = test1.new Test2();
}
}
在内部类中可以随意使用外部类的成员变量以及成员方法,尽管这些类的成员被修饰为private。上面的例子中能够充分说明了内部类的使用,尽管成员变量i以及成员方法f()都在外部类中被private修饰,但是在内部类中可以直接使用外部类中的成员。
内部类的实例一定要绑定在外部类的实例上,如果从外部类中初始化一个内部类对象,那么内部类对象就会绑定在外部类对象上。内部类初始化方式以其他类初始化相同,都市使用new关键字。
使用this关键字获取内部类与内部类的引用
如果在外部类中定义的成员变量与内部类的成员变量名称相同,可以使用this关键字来引用。
创建一个OuterClass类,在类中定义成员变量x,再定义一个内部类InnerClass,在内部类中也定义个x变量,并在内部类中的does()方法中分别操作两个x变量。
代码如下:
public class OuterClass {//外部类
private int x;
private class InnerClass {//内部类
private int x = 9;
public void does(int x) {
x++; // 调用的是形参x
this.x++; // 调用内部类的变量x
OuterClass.this.x++;// 调用外部类的变量x
}
}
}
局部内部类
内部类不仅可以在类中进行定义,还可以在类的局部位置定义,如在类的方法或任意的作用域中均可以定义内部类。
代码如下:
interface OutInterface {// 定义一个接口
}
class OuterClass {
// does()方法参数为final类型
public OutInterface2 does(final String x) {
// 在does()方法中定义一个内部类
class InnerClass2 implements OutInterface {
InnerClass2(String s) {
s = x;
System.out.println(s);
}
}
return new InnerClass2("does");
}
}
静态内部类
在内部类前添加修饰符static,这个内部类就变为静态类了。一个静态内部类中可以声明static成员,但是在非静态内部类中不可以声明静态成员。静态内部类有一个最大的特点,就是不可以使用外部类的非静态成员。
可以这样认为,普通的内部类对象隐式地在外部保存了一个引用,指向创建它的外部类对象,但是如果内部类被定义为static,就会有更多的限制,静态内部类具有两个特点:
- 如果创建静态内部类的对象,不需要其外部类的对象。
- 不能从静态内部类的对象中访问非静态外部类的对象。
在定义一个静态内部类时,也可以在静态内部类中添加主方法。
代码如下:
public class StaticClass {
int x = 100;
static class Inner{
public void doInner(){
//调用外部类的成员变量x(不能从静态内部类的对象中访问非静态外部类的对象)
//System.out.println("外部类"+x);
}
//主方法
public static void main(String[] args) {
System.out.println("a");
}
}
}
在上面的例子中,内部类的doInner()方法中调用成员变量x,由于Inner被修饰为static形式,而成员变量x却是非static类型的,所在doInner()方法不能调用x变量。
内部类的继承
内部类和其他普通类一样可以被继承,但是继承内部类比继承普通类复杂,需要设置专门的语法来完成。
在下面的例子中,创建OutputInnerClass类,使OutputInnerClass类继承ClassA类中的内部类ClassB。
public class OutputInnerClass extends ClassA.ClassB {//继承内部类ClassB
public OutputInnerClass(ClassA a){
a.super();
}
}
class ClassA{
class ClassB{
}
}
在某个类继承内部类时,必须硬性给予这个类一个带参数的构造方法,并且该构造该方法的参数为需要继承内部类的外部类的引用,同时在构造方法体中使用a.super()语句,这样才为继承提供了必要的对象引用。