1 内部类的定义及使用
1.1 内部类的基本概念
内部类指的就是一个类的内部进行其他类结构的嵌套的操作语法形式。理论上一层层进行类的嵌套,但是如果嵌套的类太多,就晕了。
范例:类的嵌套
代码
class Outer { // 定义一个外部类
private String msg = "Hello World!";
class Inner { // 定义了一个内部类
public void print(){ // 定义一个普通方法
System.out.println(msg); // 调用msg属性
}
}
// 在外部类中定义一个方法,负责产生内部类对象并且调用print()方法
public void fun(){
Inner in = new Inner(); // 内部类对象
in.print(); // 内部类中提供的print()方法
}
}
public class TestDemo {
public static void main(String[] args){
Outer out = new Outer(); // 外部类对象
out.fun(); // 调用了外部类的方法
}
} // 输出结果:Hello World!
由以上程序发现:程序的结构有些混乱 ,虽然内部类破坏了程序结构从整体来讲不好,但内部类也有优点,在于外部类的私有访问。
范例:将内部类提取出来,要求实现相同功能。
- Outer和Inner是两个独立的类,Inner类需要访问Outer类中的msg属性,但Outer类中的msg属性使用了private封装,封装的属性要被外部访问,需要写getter()方法。
- Inner类中print()方法之中如果想要访问msg的内容,就要使用getMsg()方法,但是getMsg()方法是普通方法,必须通过Outer类的实例化对象访问,这是需要把主方法中的Outer对象传递到Inner类中。
代码
class Outer {
private String msg = "Hello World!";
public String getMsg(){ // 通过此方法才可以取得msg内容
return this.msg;
}
public void fun(){ // 3. 由out对象调用了fun()方法
Inner in = new Inner(this); // 4. this表示当前对象
in.print(); // 7. 调用方法
}
}
class Inner {
private Outer out; // 5. Inner.out = main.out
public Inner(Outer out){ // 6. 引用传递
this.out = out;
}
public void print(){ // 8.执行此方法
System.out.println(this.out.getMsg());
}
}
public class TestDemo {
public static void main(String[] args){
Outer out = new Outer(); // 1. 实例化Outer类对象
out.fun(); // 2. 调用Outer类方法
}
} // 输出结果:Hello World!
内部类看起来访问更简化。
1.当前内部类访问必须通过外部类方法才可完成。如果现在不想通过外部类类方法调用,想在程序外部调用,语法形式如下:
- 外部类.内部类 内部类对象 = new 外部类().new 内部类();
代码
class Outer {
private String msg = "Hello World!";
class Inner {
public void print(){ // 8.执行此方法
System.out.println(msg);
}
}
}
public class TestDemo {
public static void main(String[] args){
// 声明内部类对象
Outer.Inner in = new Outer().new Inner();
in.print();
}
} // 输出结果:Hello World!
进行外部类的实例化主要是因为此时外部类中存在普通属性,这些属性只有开辟实例化对象之后才能被外部访问。
2.如果一个内部类只想被外部类使用,即:不希望直接产生内部类的实例化对象,可以使用private定义。
代码
class Outer {
private String msg = "Hello World!";
private class Inner {
public void print(){ // 8.执行此方法
System.out.println(msg);
}
}
public void fun(){
Inner in = new Inner();
in.print();
}
}
public class TestDemo {
public static void main(String[] args){
new Outer().fun();
}
} // 输出结果:Hello World!
3.在访问的时候都需要习惯性加上this。如果要想在内部类中明确使用this,语法形式:“外部类.this.属性”,这就表示外部类当前对象的属性。
代码
class Outer {
private String msg = "Hello World!";
private class Inner {
public void print(){ // 8.执行此方法
System.out.println(Outer.this.msg);
}
}
public void fun(){
Inner in = new Inner();
in.print();
}
}
public class TestDemo {
public static void main(String[] args){
new Outer().fun();
}
} // 输出结果:Hello World!
1.2 static定义内部类
内部类中如果使用static进行定义,那么就表示其就是一个外部类的形式,但是这个“外部类”的名称就是“外部类.内部类”,该内部类只允许访问外部类中的static操作。
范例:使用static定义内部类
代码
class Outer {
private static String msg = "Hello World!";
static class Inner{
public void print(){
// 此时只能够使用外部类中的static操作,所以Strin gmsg前要加static
System.out.println(msg);
}
}
}
如果要操作这个外部类,就应该实例化对象,语法如下:
- 实例化对象:外部类.内部类 内部类对象 = new 外部类.内部类();
代码
class Outer {
private static String msg = "Hello World!";
static class Inner{
public void print(){
System.out.println(msg);
}
}
}
public class TestDemo {
public static void main(String[] args){
Outer.Inner in = new Outer.Inner();
in.print();
}
} // 输出结果:Hello World!
1.3 在方法中定义内部类
理论上内部类可以定义在类中的任意位置上,这就包括了:类中、方法中、代码块中。从实用的角度讲,在方法中定义内部类是最多的。
范例:在方法中定义内部类
代码
class Outer { // 定义了一个外部类
private String msg = "Hello World!";
public void fun(int num){
class Inner{ // 定义了一个内部类
public void print(){
System.out.println("num = " + num);
System.out.println("msg = " + msg);
}
}
new Inner().print(); // 产生了内部类的对象并且调用方法
}
}
public class TestDemo {
public static void main(String[] args){
new Outer().fun(100);
}
}
输出结果
num = 100
msg = Hello World!
此时的代码在JDK1.8之前是错误的。在JDK1.7及以前,如果一个内部类定义在了方法之中,那么该内部类如果要想访问方法中的参数,那么这个参数前必须使用final定义。而JDK1.8之后,为了推广函数式编程,所以将这一局限取消了。
2 总结
内部类特征:
- 破坏了程序结构;
- 方便进行私有属性的访问;
- 如果发现类名称上出现了“.”,应立刻想到是内部类的概念。