您的位置:首页 > 编程语言 > Java开发

JAVA 复习(Think In Java, 4th) -- Inner Classes - Part1

2014-09-23 07:47 375 查看
内部类(Inner Class)

一个类是可以在其它类中定义的类,我们可以将数据储存在有意义的内部类,在别人调用我们类、运用相关方法的时候,能做更有序、灵活的运用,如下:

public class EasyInnerClass {
private People list[] = null;
private int count = 0;
public EasyInnerClass() {
list = new People[5];
}
class People {
String name;
int height;
int weight;

public String toString() {
return "[ "+name+" ]: height- "+height+" ,weight- "+weight;
}
}

public void enrollPeople(String name, int h, int w) {
if(count < 5) {
People theOne = new People();
theOne.name = name;
theOne.height = h;
theOne.weight = w;
list[count] = theOne;
count++;
} else {
System.out.println("too many people...");
}
}

public void printList() {
if(list.length > 0)
for(int i = 0; i < list.length; i++)
{
if(list[i]!=null)
System.out.println(list[i].toString());
}
else
System.out.println("no one is on the list");
}

public static void main(String[] args) {
EasyInnerClass ec = new EasyInnerClass();
ec.enrollPeople("jg",150,60);
ec.enrollPeople("zg",150,60);
ec.enrollPeople("st",150,60);
ec.enrollPeople("ot",150,60);
ec.enrollPeople("dt",150,60);
ec.enrollPeople("sd",150,60);

ec.printList();
}
}



比如在上例,我们在 enrollPeople() 这个方法中,产生一个用内部类对象构建的对象,数据存到该对象,并将这个对象存在一个数组中,而调用此 API的人,便无须了解我们如何処理这些数据,只要有合理的输入及正确的输出即可。另外要注意的是,当自外部宣告非静态( non-static )内部类时,应为:

外部类名.内部类名   变数名 = 外部类变数.宣告方法()
如下:

public class EasyInnerClass {
public class People {
String name;
int height;
int weight;

public People(String n, int h, int w) {
name = n;
height = h;
weight = w;
}

public String toString() {
return "[ "+name+" ]: height- "+height+" ,weight- "+weight;
}
}

public People initPeople(String name, int h, int w){
return new People(name,h,w);
}

public void printPeople(People ppl) {
System.out.println(ppl.toString());
}

public static void main(String[] args) {
EasyInnerClass ec = new EasyInnerClass();
EasyInnerClass.People one = ec.initPeople("John",175,65);
ec.printPeople(one);
}
}



如果用下面的方法这麽写:

public static void main(String[] args) {
EasyInnerClass ec = new EasyInnerClass();
EasyInnerClass.People one = new EasyInnerClass.People("john",149,22);
ec.printPeople(one);
}



"non-static variable this cannot be referenced from a static context" 这句话的意思是说 EasyInnerClass.People 是一个静态的上下文(static context),而 new 是一个非静态的变数宣告方法,此処所宣告的内存为动态内存,不能为静态上下文所引用。(因为静态变数在内存中的位置是一开始就知道的,而动态变数是程序执行中才会知道的)修改的办法除了上面的方法以外,我们也可以将内部类改为静态的内部类,如下:

public class EasyInnerClass {
public static class People {
String name;
int height;
int weight;

public People(String n, int h, int w) {
name = n;
height = h;
weight = w;
}

public String toString() {
return "[ "+name+" ]: height- "+height+" ,weight- "+weight;
}
}

public People initPeople(String name, int h, int w){
return new People(name,h,w);
}

public void printPeople(People ppl) {
System.out.println(ppl.toString());
}

public static void main(String[] args) {
EasyInnerClass ec = new EasyInnerClass();
People one = new People("john",149,22);
ec.printPeople(one);
}
}


在下面这个范例中,内部类作为判断目前数组 index 的方法,它可以存取 private 属性的 ObArray 以判断和实现 InnerPointer 接口,如下:

public class InnerArray {
private Object[] ObArray;
private int next;

interface InnerPointer {
boolean end();
void next();
Object current();
}

private class InnerPointerImpl implements InnerPointer {
private int i = 0;
@Override
public boolean end() {
return i == ObArray.length;
}

@Override
public void next() {
if(!end())
i++;
else
System.out.println("Out of index");
}

@Override
public Object current() {
return ObArray[i];
}
}

public InnerArray(int size) {
ObArray = new Object[size];
}

public InnerPointerImpl initInnerPointerImpl() {
return new InnerPointerImpl();
}

public void add(Object a) {
if(next < ObArray.length) {
ObArray[next] = a;
next++;
}
else
System.out.println("out of array index");
}

public static void main(String[] args) {
InnerArray ia = new InnerArray(10);
InnerArray.InnerPointerImpl ip = ia.initInnerPointerImpl();
for(int i = 0; i < 10; i++)
{
ia.add(i);
}

while(!ip.end())
{
System.out.println(String.valueOf(ip.current()));
ip.next();
}
}
}




.this 和 .new

类名.this
可以很方便的让我们在内部类里指向外面类的对象,而有时我们需要用外部类去宣告它的内部类,这时我们便可以用

外部类对象.new 内部类名();


如下:

import java.util.Arrays;
public class DotNewPractice {
private Object[] jobQueue;
private int curExecIndex;
private interface ProgressListener {
float getCurrentProgress();
boolean isEnd();
}

private ProgressListener listener;

public DotNewPractice(int jobNum) {
System.out.println("this is: " + this.getClass());
jobQueue = new Object[jobNum];
}

public void execute() {
final int Len = jobQueue.length;
for(int i =0; i<Len; i++) {
jobQueue[i] = 0;
curExecIndex = i;
System.out.println(""+listener.getCurrentProgress()+"%");
}
}

public void getJobs() {
Arrays.fill(jobQueue,100);
}

public void initListener() {
listener = new innerclass();
}

public void setProgressListener(ProgressListener ltn) {
listener = ltn;
}

public class innerclass implements ProgressListener {
public innerclass() {
System.out.println("this is: " + this.getClass());
System.out.println("Outer Class this is: " + DotNewPractice.this.getClass()); // 外部类名.this 在这~
System.out.println(innerclass.this.getClass() + " created!");
}

@Override
public float getCurrentProgress() {
return ((float)(curExecIndex+1)/(float)jobQueue.length)*100;
}

@Override
public boolean isEnd() {
return (curExecIndex+1 == jobQueue.length);
}
};

public static void main(String[] args) {
DotNewPractice dp = new DotNewPractice(10);
dp.setProgressListener(dp.new innerclass()); // 用dp.initListener(); 也会得到一样的效果
dp.getJobs();
dp.execute();
}
}


内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: