内部类(inner class)是定义在另一个类中的类。
使用内部类的原因:
- 内部类可以对同一个包中的其他类隐藏
- 内部类方法可以访问定义这个类的作用域的数据,包括原本私有的数据
语法格式如下:
class OuterClass { // 外部类
// ...
class NestedClass { // 嵌套类,或称为内部类
// ...
}
}
要访问内部类,可以通过创建外部类的对象,然后创建内部类的对象来实现。一般有静态内部类与非静态内部类
内部类的分类
-
定义在外部类局部位置上(如方法内):
1)局部内部类(有类名)
2)匿名内部类(没有类名)
-
定义在外部类的成员位置上:
1)成员内部类(没有static修饰)
2)静态内部类(使用static修饰)
一、成员内部类(非静态内部类)
非静态内部类是一个类中嵌套着另外一个类。 它有访问外部类成员的权限, 通常被称为内部类。
内部类对象的创建:因为内部类嵌套在外部类中,所以必须先创建外部类,后利用外部类对象创建内部类对象。
public class InnerClass {
public static void main(String args[])
{
OutClass myOutClass = new OutClass();
OutClass.InnerClass myInClass = myOutClass.new InnerClass();
System.out.println(myOutClass.x+myInClass.y);
}
}
class OutClass
{
int x = 10;
class InnerClass
{
int y = 5;
}
}
首先创建外部类对象,利用外部类对象再次创建内部类对象,需要注意的是:
外部类名.内部类名 内部类对象 = 外部类对象 new 内部类构造器
内部类可以利用private、protected修饰符修饰,若希望外部类不能访问内部类,则可以使用private修饰符。
二、静态内部类
静态内部类可以使用 static 关键字定义,静态内部类我们不需要创建外部类来访问,可以直接访问它:(例子同上)
public class InnerClass {
public static void main(String args[])
{
OutClass.InnerClass myInClass = new OutClass.InnerClass();
System.out.println(myInClass.y);
}
}
class OutClass
{
int x = 10;
static class InnerClass
{
int y = 5;
}
}
三、成员内部类与外部类成员相互访问
内部类一个高级的用法就是可以访问外部类的属性和方法:
例子同上,在外部类中添加一个字符串,我们在内部类(非静态)添加一个方法没来获取外部类的字段x与字符串
public class InnerClass {
public static void main(String args[])
{
OutClass myOutClass = new OutClass();
OutClass.InnerClass myInnerClass = myOutClass.new InnerClass();
System.out.println(myInnerClass.getOutClass_Method());
}
}
class OutClass
{
int x = 10;
static String string = "Hello";
class InnerClass
{
int y = 5;
public int getOutClass_Method()
{
return x+string;
}
}
}
注意:
(1)、从上述例子看出,内部类可直接访问外部类的字符。内部类访问静态内部类无法访问外部类的成员。当外部类字段为private时候,内部类仍然也可以访问。
(2)、当如果外部类和内部类的成员重名时,内部类访问的话,默认遵循就近原则,如果想访问外部类的成员,则可以使用(外部类名.this.成员)去访问
class OutClass { private int x = 10; class InnerClass { int x = 5; public int getOutClass_Method() { return this.x; //注意此时根据就近原则,x的值为5 } } }当返回值为 return OutClass.this.x时,则x的值为10
(3)、外部类访问成员内部类
因为成员内部类可理解为是外部类的一个成员,所以外部的访问里面的需先new一个对象,即利用外部类创建一个内部类对象即可访问
new OutClass().new InnerClass().getOutClass_Method()
四、静态内部类访问外部类成员
在内部类中创建外部类对象访问外部类成员
格式:new 外部类构造器.字段
class OutClass
{
private int x = 10;
static class InnerClass
{
int x = 5;
int y = 100;
public int getOutClass_Method()
{
return new OutClass().x;
}
}
}
此时x的值为10。
综上:
一、成员内部类
1、外部类访问内部类成员,先创建外部类对象
格式:外部类名.内部类名 内部类对象 = 外部类对象 new 内部类构造器
或
new 外部类名.new 内部类名
2、内部类访问外部类成员
格式:外部类名.this.成员(字段) 外部类名.方法
或
直接访问
二、静态内部类
1、外部类访问内部类成员
格式:外部类名.内部类名 内部类对象 = new 外部类名.内部类构造器
2、内部类访问外部类成员
格式:new 外部类名.成员(this.field)
五、局部内部类
1、局部内部类是定义在外部类的局部位置,比如方法中,并且有类名。
2、声明局部类时不能有访问修饰符,局部类的作用域被限定在声明这个局部类的块中。
3、外部其他类不能访问局部内部类
4、局部内部类定义在方法中/代码块
六、匿名内部类
1、匿名内部类的语法比较奇特,请大家注意,因为匿名内部类既是一个类的定义,同时它本身也是一个对象,因此从语法上看,它既有定义类的特征,也有创建对象的特征,,因此可以调用匿名内部类方法。
2、.可以直接访问外部类的所有成员,包含私有的
3、不能添加访问修饰符,因为它的地位就是一个局部变量
4、作用域:仅仅在定义它的方法或代码块中。
5、匿名内部类—访问---->外部类成员[访问方式:直接访问]
6、外部其他类—不能访问----->匿名内部类(因为匿名内部类地位是一个局部变量)
7、如果外部类和匿名内部类的成员重名时,匿名内部类访问的话,默认遵循就近原则,如果想访问外部类的成员,则可以使用(外部类名.this.成员)去访问