内部类:
为什么要有内部类:
首先举一个简单的例子,如果你想实现一个接口,但是这个接口中的一个方法和你构想的这个类中的一个方法的名称,参数相同,你应该怎么办?这时候,你可以建一个内部类实现这个接口。由于内部类对外部类的所有内容都是可访问的,所以这样做可以完成所有你直接实现这个接口的功能。
不过你可能要质疑,更改一下方法的不就行了吗?
的确,以此作为设计内部类的理由,实在没有说服力。
真正的原因是这样的,java中的内部类和接口加在一起,可以的解决常被C++程序员抱怨java中存在的一个问题 没有多继承。实际上,C++的多继承设计起来很复杂,而java通过内部类加上接口,可以很好的实现多继承的效果。
访问特点:
1.内部类可以直接访问外部类中的成员,包括私有成员。
2.外部类要访问内部类中的成员必须要建立内部类的对象。
内部类的修饰符:
1.private:为了安全考虑。
private class 内部类名(){方法体},此内部类被private修饰后不能在外部类以外的其它地方被创建对象。
class Outer
{
private int num = 10;
private class Inner
{
public void show() {
System.out.println("Inner");
}
}
public void method() {
Inner i = new Inner();
i.show();
}
}
Class InnerTest
{
public static void main(String args[]) {
//会报错,因为不能创建内部类对象,内部类为private类型的
Outer.Inner oi = new Outer().new Inner();
oi.show();
//或者通过外部类方法调用
Outer o = new Outer();
//因为method方法中创建了Inner对象所以与上面代码效果相同
o.method();
}
}
2.static:为了方便,常见用法。
class Outer
{
private int num = 10;
//普通的类中含有静态方法时,类不需要被static修饰
//内部类中含有静态方法时,类需要被static修饰
//这是为什么?
static class Inner
{
public void show() {
System.out.println("Inner");
}
public static show1() {
System.out.println("Inner1");
}
}
public void method() {
Inner i = new Inner();
i.show();
}
}
Class InnerTest
{
public static void main(String args[]) {
//使用Inner类,不可以直接使用
//调用格式
//如果是static修饰内部类
//格式:
//外部类名.内部类名 变量 = new 外部类名.内部类名();
Outer.Inner oi = new Outer.Inner();
oi.show();
}
}
上述问题解答:
Outer类加载的时候,作为成员的内部类Inner不会随着类的加载而加载,但静态方法会被加载,所以需要Inner也被加载,所以Inner需要被static修饰
内部类的位置:
1.成员位置:—— 成员内部类
class Outer
{
private int num = 10;
class Inner
{
public void show() {
System.out.println("Inner");
}
}
public void method() {
Inner i = new Inner();
i.show();
}
}
Class InnerTest
{
public static void main(String args[]) {
//使用Inner类,不可以直接使用
//调用格式
//外部类名.内部类名 变量 = 外部类对象.内部类对象;
Outer.Inner oi = new Outer().new Inner();
oi.show();
//或者通过外部类方法调用
Outer o = new Outer();
//因为method方法中创建了Inner对象所以与上面代码效果相同
o.method();
}
}
2.局部位置:—— 局部内部类(方法中定义的类)
class Outer
{
private int num = 10;
public void method()
{
class Inner
{
public void show()
{
System.out.println("Inner");
}
}
Inner i = new Inner();
i.show();
}
public void function() {
Inner i = new Inner();
//会报错,因为Inner相当于一个局部变量x,只能在method中生效;
}
}
结论:局部内部类只能访问局部变量,局部内部类访问的局部变量必须被final修饰
使用final的原因:
方法被创建是在栈内存中,而此方法中的局部内部类是在堆内存中,当方法被调用完毕后会立马消失,而局部内部类还使用着局部变量,当方法消失后,这个方法区的内容还没有消失,也就是说这个局部变量必须存在,为了延长这个局部变量的生存周期,使用final修饰
匿名内部类(没有名字的局部内部类)
前提:必须存在一个类,抽象类,或者接口。
格式:
new 类名或者接口名()
{
重写类或者接口中的方法。
也可以自己定义新的方法。
}
理解: 是一个继承了类或者实现了接口的匿名的子类对象。
什么时候使用匿名内部类?
一般来说,当接口或者抽象类中的方法在3个以下的时候,考虑使用匿名内部类
当看到一个方法接受的形式参数是一个抽象类或者接口的时候,可以考虑用匿名内部类实现
打个例子:
interface Inter
{
public abstract void show();
public abstract void show2();
}
class Outer
{
public void method()
{
new Inter()
{
public void show()
{
System.out.println("Hello, world.");
}
public void show2()
{
System.out.println("Hello, world.");
}
}.show();
new Inter()
{
public void show()
{
System.out.println("Hello, world.");
}
public void show2()
{
System.out.println("Hello, world.");
}
}.show2();
}
}
class Text
{
public static void main(String[] args)
{
Outer o = new Outer();
Outer.method();
}
}