<span style="font-family: Arial, Helvetica, sans-serif; background-color: rgb(255, 255, 255);"><span style="font-size:14px;">1.内部类:将一个类定义到另一个类里面,里面的类叫内部类</span></span>
2.内部类特点
(1)内部类可以访问外部类中的成员(内部类相当于外部类的一个成员,所以可以直接访问,尤其是private变量),如果不用内部类访问private成员还得先创建一个对象,然后 通过set,get方法才能访问private成员,所以此时为了方便创建内部类
(2)外部类要访问内部类,需要创建一个内部类的对象
3.格式
class Outer{
coding1 ...........
class Inner{
coding2 ...........
}
}
会生成一个Outer.class ,也会生成一个Outer$Inner.class
4.一般什么时候用?
在分析类A时,发现A的描述需要类B,而且类B还在访问类A中的内容,此时将B放到A中,这样访问起来比较方便
你实现了某类型的接口,于是可以创建并返回对其的引用
你要解决一个复杂的问题,想创建一个类来辅助你的解决方案,但是又不希望这个类是公共可用的
5.访问方式
(1)在类外(此处指的类外是在Outer类的类外)直接访问外部类里的内部类成员(假设内部类没有私有化)
Outer.Inner in = new Outer().new Inner()//把Inner当成Outer的一个成员,并且把Inner当成一个类
(2)假如内部类是静态的,相当于内部类是外部类的静态成员,直接用类名.内部类名调用即可
Outer.Inner in = new Outer.Inner(); //静态的内部类岁外部类加载而加载,因此不需要创建内部类的对象
(3)如果内部类是静态的,内部类里的函数也是静态的,调用不需要创建对象
OUt.Inner.函数名();
(4)如果内部类里有静态成员,内部类必须也是静态的,这是因为静态成员随类的加载就加载,就不需要创建对象,如果内部类不是静态的,还得创建对象,矛盾
(5)如果内部类在方法的作用域里,称为局部内部类;此时内部类是方法里的部分,而不是外部类的一部分。因此在方法之外不能访问内部类,如果内部类访问了方法里的局 部变量,需要将局部变量定义为final,因为内部类在局部的位置上,只能访问局部中被final修饰的变量,否则局部变量会随着方法的弹栈而消失,此时内部类就可能访问 不到这些局部变量
6.使用 .this(点this) 和 .new(点new)
如果想要在内部类中生成对外部类对象的引用,可以使用外部类的名字后面紧跟圆点和this。
<pre name="code" class="java">public class DotThis{
void f(){ Syso("DotThis.f")}
public class Inner {
public DotThis outer(){
return DoThis.this; // 如果只写this,将会返回Inner的this
}
}
}
有时可能想要告知某些其他对象,创建某个内部类的对象,此时用.new语法
<pre name="code" class="java">public class DotNew{
public class Inner{}
public static void main(String[] args){
DotNew dn = new DotNew();
DotNew.Inner dni = dn.new Inner(); //相当于 DotNew.Inner dni = nwe Outer().new Inner();
}
}
7.匿名内部类
前提:内部类必须继承或实现一个类或接口,匿名内部类其实就是一个匿名的子类对象
格式:
<pre name="code" class="java"><pre name="code" class="java">class Fu{
public void show(){}
}
class Outer{
return new Fu(){
public void show2(){}
};
}
匿名内部类实际上使用了父类的默认的构造器生成Fu;
如果基类需要一个有参数的构造器时,只需要简单的传递合适的参数给积累的构造器即可。
class Fu{
public void show(){}
}
class Outer{
public Wrapping wrapping(int x){
return new Fu(x){
public void show2(){}
};
}
如果定义一个匿名内部类,并且希望它使用一个在其外部定义的对象,那么编译器会要求其参数引用是final的。
匿名内部类中不可能有命名构造器(因为它根本就没名字),但是可以通过在匿名内部类中加入构造代码块,达到为匿名内部类创建一个构造器的效果
例如:
class Outer{
return new Base(){
{syso("Inside instance initializer")}
public void f(){syso("In anonymous f()")}
}
}
此时构造代码快的效果就是构造器,当然它有一个限制,你不能重载它,所以仅有这样一个构造器。
8.调用匿名内部类的函数
(1)直接在匿名内部类的右大括号加点方法名
<pre name="code" class="java">class Outer{
public int num = 4;
public void method(){
new Fu(){
public void show(){
syso("show..." + num);
}
}.show();
}
}
由于相当于创建了一个子类,但引用指向了父类,所以调用的必须是父类中的方法。
由上可以想到,这样只能调用一个方法,如果想调用多个方法,格式如下:
class Outer{
public int num = 4;
public void method(){
Fu f =new Fu(){
public void show(){
syso("show..." + num);
}
};
f.show1();
f.show2();
}
}