内部类感觉很复杂,想做个笔记记录一下。
定义
内部类是定义在另一个类中的类。
类型
1.成员内部类
顾名思义,成员内部是最普通的内部类,它的定义为位于另一个类的内部,形如下面的形式:
//主程序
public class Test {
public static void main(String[] args)
{
Outer outer = new Outer();
Outer.Inner inner = outer.new Inner();//创建内部类的语法
}
}
//外部类
class Outer {
private int a = 1;
private int b = 2;
public Outer(){}
//内部类
class Inner
{
public Inner()
{
System.out.print(a + b);
}
}
}
代码结果:
可以看到,内部类Inner可以访问外部类Outer的私有变量。这是因为a,b引用了创建inner的Outer类型的对象outer的域。
2.局部内部类
局部内部类是定义在一个方法或者一个作用域里面的类,它和成员内部类的区别在于局部内部类的访问仅限于方法内或者该作用域内。
观察上面的代码,可以发现内部Inner类只是打印了a+b的值。那我们就可以创建一个sum方法,并把内部Inner类放在sum()方法内,而不是放在整个外部类。代码如下:
//主程序
public class Test {
public static void main(String[] args)
{
Outer outer = new Outer();
outer.sum();
}
}
//外部类
class Outer {
private int a = 1;
private int b = 2;
public Outer(){}
public void sum()
{
//内部类
class Inner
{
public Inner()
{
System.out.print(a + b);
}
}
Inner inner = new Inner();
}
}
局部类有一个优势就是对外部世界完全隐藏,只有sum方法可以知道类的存在。
- 局部类不能用public和private访问说明符进行声明,这是因为他的作用域已经被限定在声明这个局部类的块里了。
- 局部类还可以访问局部变量。 但是局部变量必须声明为final。
3.匿名内部类
将局部内部类的使用再深入一步,上文的Inner类只在sum方法里面使用,如果sum方法刚好只需要创建一次Inner类的对象(上文的例子正好是),那么就不必命名这个类了。这种类就称为匿名内部类。
但使用匿名内部类还有个前提条件:必须继承一个父类或实现一个接口
- 将上文的代码修改为匿名内部类(继承):
//所继承的父类
abstract class Father {
public abstract void sum1();
}
//外部类
public class Outer {
private int a = 1;
private int b = 2;
public Outer(){}
public void sum()
{
//匿名内部类:将抽象类Father中的方法在大括号中实现
//可以省略一个类的书写
Father f = new Father()
{
public void sum1()
{
System.out.println(a + b);
}
};
f.sum1();
}
//主程序
public static void main(String[] args)
{
Outer outer = new Outer();
outer.sum();
}
}
- 将上文的代码修改为匿名内部类(接口):
//所满足的接口:必须要有sum1函数
interface Father {
public void sum1();
}
//外部类
public class Outer {
private int a = 1;
private int b = 2;
public Outer(){}
public void sum()
{
//匿名内部类:将接口中的方法在大括号中实现
//可以省略一个类的书写
Father f = new Father()
{
public void sum1()
{
System.out.println(a + b);
}
};
f.sum1();
}
//主程序
public static void main(String[] args)
{
Outer outer = new Outer();
outer.sum();
}
}
4.静态内部类
有时候,使用内部类只是为了把一个类隐藏在另一个类中,而不需要引用外围类对象,因此可以将内部类声明为static,以便取消产生的引用。
其次,Inner是比较常见的名字,如果没有定义为内部类的话,很有可能和别的相同名字的变量或者方法等冲突。如果是Outer.Inner就可以避免这些问题了。
举例:
//外部类
public class Outer {
private int a = 1;
private int b = 2;
public Outer(){}
//静态内部类
static class Inner
{
public Inner()
{
System.out.print("This is static");
}
}
//主程序
public static void main(String[] args)
{
//有可能冲突
Inner inner = new Inner();
//改进
Outer.Inner inner1 = new Outer.Inner();
}
}
暂时写这些,以后有新的理解再继续完善。