内部类
在java中,可以将一个类定义在另一个类里面或者一个方法里面,这样的类称为内部类。广泛意义上的内部类一般来说包括这四种:成员内部类、局部内部类、匿名内部类和静态内部类。下面就来了解下这四种内部类的用法。
1、成员内部类
成员内部类是最普通的内部类,它定义在另一个类的内部,形式如下:
class O {
private int a = 1;
public O(){
//外部类构造器
}
/*
* 内部类
*/
class I{
public I(){
//内部类构造器
System.out.println("i!");
}
}
}
成员内部类可以无条件的访问外部类的所有成员属性和成员方法(包括private成员和静态成员)。
public class C {
private double d = 1;
public static String s= "word";
public C(double d){
this.d = d;
getAInstance().f(); //外部内访问内部类时,必须先创建成员内部类的对象,再进行访问
}
private A getAInstance(){
return new A();
}
class A{ //内部类
public void f(){
System.out.println("输出f");
System.out.println(d); //访问外部内的private成员
System.out.println(s); //访问外部类的static静态成员
}
}
}
注意:当成员内部类拥有和外部类同名的成员变量或这方法时,会发生隐藏现象,即默认情况下访问的是成员内部类的成员。如果访问外部类的同名成员,需要以下面的形式进行访问:
外部类.this.成员变量
外部类.this.成员方法
虽然成员内部类可以无条件的访问外部类的成员,而外部类向访问成员内部类的成员时,必须先创建一个成员内部类的对象,再通过指向这个对象的引用来访问。
public class Test1 {
public static void main(String[] args){
//第一种方式
Outer outer = new Outer();
Outer.Inner inner = outer.new Inner(); //必须通过outer对象来创建
//第二种方式
Outer.Inner inner1 = outer.getInnerInstance(); //必须通过outer对象来创建
}
}
class Outer{
private Inner inner = null;
//构造函数
public Outer(){
System.out.println("outer!");
}
public Inner getInnerInstance(){
if (inner == null) {
return new Inner();
} else {
return inner;
}
}
class Inner{
//构造函数
public Inner(){
System.out.println("inner!");
}
}
}
成员内部类是依附外部类二存在的,也就是说,如果创建成员内部类的对象,前提是必须存在一个外部类的对象。创建对象的一般方式如上示例所示。
内部类可以拥有private访问权限、protected访问权限、public访问权限以及包访问权限。比如上面的例子,如果成员内部类Inner用private修饰,则只能在外部类的内部访问,如果用public修饰,则任何地方都能访问;如果用protected修饰,则只能在同一个包下或者继承外部类的情况下访问;如果是默认访问权限,则只能在同一个包下访问。而外部类只能被public和包访问两种权限修饰。
2、局部内部类
局部内部类是定义在一个方法或者一个作用域里面的类,它和成员内部类的区别在于局部内部类的访问权限仅限于方法内或者该作用域内。
public class People {
public People() {
System.out.println("people!");
}
}
class Men{
public Men(){
System.out.println("men!");
}
public People getWomen(){
class Women extends People{ //局部内部类
private int age = 2;
public Women(){
System.out.println("women!");
System.out.println(age);
}
}
return new Women();
}
}
注:局部内部类不能用public、protected、private以及static修饰符的。
3、匿名内部类
(此部分内容在匿名内部类一节中讲解)
4、静态内部类
(结合之前整理的static内容学习)
静态内部类也是定义在另一个类的里面的类,只不过在类的前面用static关键字修饰。静态内部类是不需要依赖于外部类的,这点和类的静态成员属性有点类似,并且它不能使用外部类的非static成员变量或这方法。
public class Test {
public static void main(String[] args){
Outer.Inner inner = new Outer.Inner();
int a= Outer.Inner.i;
System.out.println(a);
}
}
class Outer{
public Outer(){
System.out.println("outer!");
}
static class Inner{
public static final int i = 1;
public Inner(){
System.out.println("inner!");
}
}
}