面向对象程序设计(三)
十、内部类
在类的内部声明类成为内部类,可以分为匿名内部类和实名内部类。
实名内部类:在类体中定义与普通类的定义方法相同也可以继承父类,实现接口,而且访问模式还多了protected和private。在外部类内的使用和普通类使用一样,例如定义一个内部类in如下:
public class inner {
int m;
double d;
public inner()
{
m=9;
d=2.3;
b=new in();
}
in b;
class in
{
static int Z=56;
int m;
double d;
public in()
{
m=15;
d=5.0;
}
}
可以看到在外部类inner的构造函数中中间可以直接使用内部类。内部类也可以直接使用外部类的成员。在外部类外部有两种创建内部类实例方式,第一种是创建静态实名内部类对象:
inner.in ii=new inner.in(); //结果报错。
原因是要创建静态实名内部类对象,但前面内部类没有加上修饰词static因此无法创建,修改后再次调用
inner.in ii=new inner.in(); //可改为in ii=new inner.in();,结果不受影响。
System.out.println(ii.d); //调用非静态成员或方法
System.out.println(in.Z); //调用静态成员或方法,可以in.Z、ii.Z、inner.in.Z均正确,但使用诸如i.Z、inner.Z、inner.ii.Z、i.ii.Z、i.in.Z都是错误的,其中inner和i是外部类名和对象名,而in和ii是内部类名和对象名
输出结果
5.0
56
同理调用静态成员方法和静态成员域也是相同的操作。
第二种创建非静态实名内部类:
inner.in ii=i.new in(); //可改为in ii=i.new in(); ,结果不受影响。同样的内部类不能有static修饰,否则报错。
System.out.println(ii.d); //调用非静态成员。
System.out.println(in.Z); //调用静态成员域,适用情况同上,非静态实名内部类中不能声明定义静态成员方法,若想要定义静态成员域必须同时加上修饰词final。
关于static块也是只能在static内部类中有,否则出错,其余事项无变化
匿名内部类:不能抽象、静态、派生子类。
有如下代码:
class outer { int a=0; int h; public outer(int a,int h) { this.a=a; this.h=h; } void f() { System.out.println("anony"); } } public class anony { public static void main(String []args) { outer b=new outer(5,10) { int a=6; void f(){System.out.println(a);} }; //匿名内部类一定要加分号 System.out.println(b.a); //5,调用父类同名成员域 b.f(); //6,调用子类重写成员方法,成员方法调用子类成员域 } }
其中的outer可以是一个类名,此时匿名内部类是以此类为父类的子类,并构造上转型实例对象,与普通上转型并无差别(存疑,部分性质有待验证)。若是接口名,参数列表可以为空,是实现接口所有抽象方法的类,这时间也是接口的声明对象(接口也是可以声明对象,类似于上装型的那种)。
十一、变量作用域及参数传递方式
静态成员域具有全局作用范围,其他成员域——即非静态成员域,类体中的方法及子类中的方法是它的作用范围,且声明语句可在方法体之前之后的类体中均可。
在成员方法或构造方法中定义的语句成为局部变量只在函数体中有效;for语句初始化只在for语句中使用,结束后失效,但在C/C++中不失效仍可继续使用,注意区分。
十二、对象数组的使用
(18-09-24补)
声明对象的数组不是直觉的直接申请空间并初始化:
class Arr { public int para; public Arr() { para=0; } public Arr(int p) { para=p; } public int getArr() { return para; } } public class Array { public static void main(String [] args) { Arr []a=new Arr() [3]; //错误
Arr []a=new Arr[3]; //正确,但是没有初始化
int m=0;
for(Arr b:a)
{
b=new Arr(m); //初始化
m++;
} //初始化后才能使用(申请空间),否则报空指针。
}
}