------Java培训、Android培训、iOS培训、.Net培训、期待与您交流! -------
一、内部类
定义:定义在另一个类里面的类就叫做内部类(嵌套类、内置类)。
访问规则:内部类可以直接访问外部类的成员;外部类要访问内部类时得先建立内部类的对象。
实现内部类的代码如下:
class Outer
{
private int x = 3;
class Inner
{
public void DiaoyongNei()
{
System.out.println("内部类"+x);
}
}
public void BuildNei()
{
Inner inn = new Inner();
inn.DiaoyongNei();
}
}
class Neibulei
{
public static void main(String[] args)
{
Outer ou = new Outer();
ou.BuildNei();
//Outer.Inner oi = new Outer().new Inner();
//oi.DiaoyongNei();
}
}
在类Outer中定义了一个内部类Inner,Inner中定义了方法DiaoyongNei,在main中想要调用Inner中的DiaoyongNei方法,首先要调用Outer中的BuildNei方法建立内部类Inner的对象,然后通过BuildNei调用Inner中的DiaoyongNei方法。内部类中的DiaoyongNei方法访问了Outer中的私有成员变量x。通过这个简单的例子可以很直观的了解内部类的访问规则。
main函数中被注释掉的部分是在其他类中直接建立另一个类的内部类的对象的方法,格式为:外部类名.内部类名 变量名 = new 外部类().new 内部类();。建立对象之后可以直接调用内部类的方法
当内部类在外部类的成员位置时,可以被成员修饰符所修饰。如private、static。
private好理解,static由于其在内存加载时的特殊性,有几点要注意:1、当内部类被静态修饰后,它要访问外部类其他成员时,其他成员也必须是静态的(最基础的)。2、在其他类中访问内部类的非静态成员时,格式为: new 外部类名.内部类名().内部方法()。3、在其他类中访问内部类的静态时,格式为: 外部类名.内部类名.内部方法()
当内部类被定义在局部时(成员内部),就不可以被成员修饰符修饰,可以访问外部变量,但对成员内部变量的访问就有了局限性:被访问的成员内部变量必须是被final修饰的变量。简单的实现代码如下:
class Outer
{
public void function1(final int a)
{
final int b = 5;
class Inner
{
public void function2()
{
System.out.println("a="+a);
System.out.println("b="+b);
}
}
new Inner().function2();
}
}
class InnerClassDemo
{
public static void main(String[] args)
{
Outer ou = new Outer();
ou.function1(7);
ou.function1(9);
}
}
值得一提的是,虽然变量a是被final修饰过的,但传常数7进入后再传常数9输出结果是会改变的,因为在执行完ou.function1(7)之后function1方法即被内存释放掉了,再次执行ou.function1(9)时function1方法又被内存建立,所以此时重新获取a的值。
内部类小结:内部类虽然是一个类,由于被定义在其他类中,因此具有了成员函数的某些性质,在使用时可以将其想象为一个普通的成员函数,好多问题就比较容易理解。但它毕竟是一个类,调用时需要先建立对象就是它作为类最重要的特点。内部类的出现是为了解决成员函数功能少的问题,内部类自成一派,可以实现很多功能,将他定义在其他类中作为内部类,可以理解为系统中的系统。就像电脑中的软件、像人体中的心脏,虽然它们是整个系统中的一部分,但它们自己也有着复杂的功能。
二、匿名内部类
匿名内部类就是内部类的简写格式。它的优点是简化代码,在理解并掌握的前提下,这样写的代码更加简洁。缺点是如果它继承的类或实现的接口中方法太多,在建立匿名内部类时就要重写这么多的方法,就失去了简写的意义。
要定义一个匿名内部类需要一些前提:这个内部类必须继承一个类或者实现接口。
匿名内部类的定义格式为:new 父类或者接口(){定义子类内容}。
调用匿名内部类中方法的格式为:new 父类或者接口(){定义子类内容}.子类方法()。
简单展示代码如下:
abstract class AbsDemo
{
abstract void show();
}
class Outer
{
public void function1()
{
new AbsDemo()
{
public void show()
{
System.out.println("show run");
}
}.show();
}
}
class NiMing
{
public static void main(String[] args)
{
Outer ou = new Outer();
ou.function1();
}
}
内部类Inner由于要简写为匿名内部类,所以我们不能new Inner来建立对象,所以这里通过new 父类或接口来创建对象。注意这里创建的是子类对象,只是用到了父类或接口的名字。子类对象建立后在中括号{}中定义子类的内容,如果要调用子类中的方法时直接在中括号后面调用。这样就相当于将1定义内部类、2创建内部类对象、3调用内部类的方法,这三个操作合在一起完成,在理解并掌握的情况下,代码明细少了很多。
匿名内部类中也可以定义自己特有的方法。
在对匿名内部类掌握不太熟练的情况下,可以先按照正常创建内部类的方法编写代码,然后再将其转写成匿名内部类,这样在写匿名内部类时就会有个直观的参照。