7.19

在Java中,可以将一个类定义在另一个类里面或者一个方法里面,这样的类称为内部类。广泛意义上的内部类一般来说包括这四种:成员内部类、局部内部类、匿名内部类和静态内部类。下面就先来了解一下这四种内部类的用法。

一、内部类基础:
1、成员内部类:
成员内部类看起来像是外部类的一个成员,所以内部类可以拥有private、public等访问权限修饰;当然,也可以用static来修饰。成员内部类分为:

静态成员内部类:使用static修饰类;
非静态成员内部类:未用static修饰类,在没有说明是静态成员内部类时,默认成员内部类指的就是非静态成员内部类;
注:只有成员内部类才能加static变成静态内部类。

1.1)静态内部类:

使用static修饰的内部类我们称之为静态内部类,我们要知道只要是static修饰的类那它一定是内部类,不可能是外部类。静态内部类与非静态内部类之间存在一个最大的区别,非静态内部类在编译完成之后会隐含地保存着一个引用,该引用是指向创建它的外围类的对象,但是静态内部类却没有。没有这个引用就意味着:

它的创建是不需要依赖于外围类的对象
它不能使用任何外围类的非static成员变量和方法(因为在没有外部类的对象的情况下,可以创建静态内部类的对象,如果允许访问外部类的非static成员就会产生矛盾,因为外部类的非static成员必须依附于具体的对象)
静态内部类内允许有static属性、方法;
class OutClass {
static class InnerClass {
static String test = "test";
int a = 1;
static void fun1() {}
void fun2() {}
}
}
1.2)非静态成员内部类:

public class Circle {
private double radius = 0.0;
public static int count = 1;
public Circle(double radius) {
this.radius = radius;
}

public class Draw {//内部类
public void drawSahpe() {
System.out.println(radius);//外部类的private成员
System.out.prinlt(count);//外部类的静态成员
}
}
}
1)成员内部类访问外部类的信息:

类Draw像是类Circle的一个成员,Circle称为外部类。成员内部类可以无条件访问外部类的所有成员属性和成员方法(包括private成员和静态成员)。

注:当成员内部类拥有和外部类同名的成员变量或者方法时,会发生隐藏现象,即默认情况下访问的是成员内部类的成员。如果要访问外部类的同名成员,需要以下面的形式进行访问:

外部类.this.成员变量
外部类.this.成员方法
2)创建内部类对象:

成员内部类是依附外部类而存在的,所以要创建成员内部类的对象,前提是必须存在一个外部类的对象。通常有如下两种方法:

public class OutClass {

private InnerClass getInner() {
return new InnerClass();
}

public class InnerClass{}

public static void main(String... str) {
OutClass out = new OutClass();

InnerClass inner1 = out.getInner();
InnerClass inner2 = out.new InnerCLass();
}
}
3)外部类访问成员内部类信息:

同样,外部类也可以访问内部类的所有成员变量和方法(包括private),但外部类想访问成员内部类的成员,必须先创建一个成员内部类的对象,再通过指向这个对象的引用来访问:

public class OutClass {
public static int count = 12;
private double radius;

public OutClass(double radius) {
this.radius = radius;
}

public class InnerClass {//内部类
public String name = "test";
public void test() {
System.out.println(count);//访问外部类成员
System.out.println(radius);//访问外部类成员
}
}
public static void main() {
OutClass out = new OutClass(1.2);

InnerClass inner = out.new InnerClass();
inner.test();//内部类方法
inner.name = "my test";//内部类属性
}
}
4)成员内部类中不能存在任何static的变量和方法:

对于成员内部内并不是完全不能出现static字段的,如果你是使用final和static同时修饰一个属性字段,并且这个字段是基本类型或者String类型的,那么是可以编译通过的。原因:

非静态成员内部类要依赖外部类,所以不能有static变量;
在类加载那一章我们了解到,对于final static的变量是存放在常量池中的,不涉及到类的加载;



posted @   new菜鸟  阅读(51)  评论(0编辑  收藏  举报
努力加载评论中...
点击右上角即可分享
微信分享提示