Java内部类

一、Inner Class
Inner Class 即内部类,也即C++和C#中的Nested Class。但Java 的Inner Class 与 C++和C#最大的不同之处在于,内部类包含一个指向其容器类的引用,可以访问容器类的成员。以下代码演示了这一点:

public class Container {
String Name;
class InnerClass
{
InnerClass(){};
public void func()
{
System.out.println(Name);
}
}
public Container(String name){
Name=name;
InnerClass a=new InnerClass();
}
public static void main(String [] arg)
{
Container a=new Container(“ContainerA");
InnerClass b=a.new InnerClass(); //注意此处
InnerClass c=(new Container(“ContainerB")).new InnerClass(); //本质上等价于上一句
a.func();
c.func();
}
}


注意其中独特的new语法,在静态函数要创建一个Inner Class,必须有一个其容器类的实例。如果直接创建InnerClass b=new InnerClass();则会导致编译出错。

而在Container的构造函数中,创建InnerClass时,自动将this作为InnerClass的引用。在Inner Class 中使用容器类的成员,不需指定实例,自动指向创建它的容器类。这是一个很有用的语法特征,编译器替我们省了许多事。

本例的输出是:
ContainerA
ContainerB

还可以看到,Inner Class 可以访问容器类的任何成员,不管是public、private或protected的成员全是透明的。反之则不然,容器类只能访问Inner Class的public成员。

二、Static Inner Class
即在内部类的前面增加了static修饰符(modifier)。注意,仅仅只有内部类能够被声明为static类型,通常我们声明一个普通类的时候不能使用static,否则编译出错。

前面讲过,编译器会自动给内部类加上一个reference,指向产生它的那个外部类的对象,如果不想要或者说不需要这个reference,那么我们就可以把这个内部类声明为static,禁止这个reference的产生。除此之外静态类的使用与普通的静态类是一样的。

public class StaticInnerClassTest {
public StaticInnerClassTest() {
super();
}
public static void main(String[] args) {
double d[]=new double[20];
for(int i=0;i<d.length;i++)d[i]=100*Math.random();
//FindMinMax test=new FindMinMax();
FindMinMax.Pair pair=FindMinMax.getMinMax(d);
System.out.println("最小值是:"+pair.getFirst());
System.out.println("最大值是:"+pair.getSecond());

}
}
class FindMinMax{
static double min=Double.MAX_VALUE;
static double max=Double.MIN_VALUE;

public static Pair getMinMax(double d[]){
for(double value:d){
if(min>value) min=value;
if(max<value) max=value;
}
return new Pair(min,max);
}

public static class Pair{
private double first;
private double second;
public Pair(double first,double second){
this.first=first;
this.second=second;
}
public double getFirst(){
return this.first;
}
public double getSecond(){
return this.second;
}
}
}


下面是又一例子:

内部类
public class Test {

class A{
public void setA(){

}
}

public static void main(String[] args){
Test t=new Test();

}
}

调用方式:
public class Test2 {

public static void main(String[] args){
Test test=new Test();
Test.A t=test.new A();
t.setA();
}
}

静态内部类
调用静态内部类的非静态方法:
public class Test {

static class A{
public void setA(){

}
}
}

public class Test2 {

public static void main(String[] args){
Test.A a=new Test.A();
a.setA();
}
}

调用静态内部类的静态方法:
public class Test {

static class A{
static public void setA(){

}
}
}

public class Test2 {

public static void main(String[] args){
Test.A.setA();
}
}

new Outer.Inner(); // 可以
new Inner(); // 在Outer类内部可以
new foo.Outer.Inner(); // 在包外做内部类实例化, 或者先导包再像第一个那样写.

三、Anonymous Inner Class
匿名内部类(Anonymous Inner Class),顾名思义,就是没有名字的内部类,这是Java为了方便我们编写程序而设计的一个机制。因为有时候有的内部类只需要创建一个它的对象就可以了,以后再不会用到这个类,这时候使用匿名内部类就比较合适,而且也免去了给它取名字的烦恼。

匿名类的语法,如下所示:
new SuperType(){
内部类的方法和域;
}

注意,这里的SuperType指超类,它可以是一个接口(interface)或者是一个类(Class),当它是一个接口的时候就不能有构造参数(Construction parameters)了。匿名类的语法相对于Java的其他部分来说稍微复杂一点,我们可以按如下方式理解:

1.SuperType为接口
例子:Interface1() test=new Interface1(){

要实现的的方法;

Interface1的域;

内部类的域以及方法;

}
我们可以如下理解:
先声明了如下一个类,
class Anonymous1 implements Interface1{
要实现的的方法;
Interface1的域;
内部类的域以及方法;
}
然后,Interface1() test=new Anonymouse1();
这样就比较容易理解了。

2.SuperType为类
例子:Class2 test=new Class2(Construction parameters){

内部类的域以及方法;

}
我们可以如下理解:
先声明了如下一个类,
class Anonymous2 extends Class2{

public Anonymous2(Construction parameters){

super(Construction parameters);

}
内部类的域以及方法;

}
然后,Class2 test=new Anonymouse2(Construction parameters);

四、Local Inner Class
在方法中定义的内部类称为局部内部类。与局部变量类似,局部内部类不能有访问说明符,因为它不是外围类的一部分,但是它可以访问当前代码块内的常量,和此外围类所有的成员。

局部内部类不需要任何access modifier(private,public,pretected...),否则编译出错,它的作用域一般都被限制在它所在的block中。局部内部类有如下两个优点:
1.它对外面的所有类来说都是隐藏的,即时是它所属的外部类,仅有它所在的方法知道它;
2.它不仅可以访问它所属外部类中的数据,还可以访问局部变量,不过局部变量必须生命为final类型

public class OuterC {
private String name="hehe";

public void useLocalInner(){
final int id=10;
class LocalInner{
public void accessMethod(){//只能访问外部方法的final属性
System.out.println(id);
}
public void accessOuter(){//可以访问外部类的属性和方法
System.out.println(name);
}
};
LocalInner localInner = new LocalInner();
localInner.accessMethod();
localInner.accessOuter();
}


}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值