JAVA 复习(Think In Java, 4th) -- Inner Classes - Part1
2014-09-23 07:47
375 查看
内部类(Inner Class)
一个类是可以在其它类中定义的类,我们可以将数据储存在有意义的内部类,在别人调用我们类、运用相关方法的时候,能做更有序、灵活的运用,如下:
比如在上例,我们在 enrollPeople() 这个方法中,产生一个用内部类对象构建的对象,数据存到该对象,并将这个对象存在一个数组中,而调用此 API的人,便无须了解我们如何処理这些数据,只要有合理的输入及正确的输出即可。另外要注意的是,当自外部宣告非静态( non-static )内部类时,应为:
如果用下面的方法这麽写:
"non-static variable this cannot be referenced from a static context" 这句话的意思是说 EasyInnerClass.People 是一个静态的上下文(static context),而 new 是一个非静态的变数宣告方法,此処所宣告的内存为动态内存,不能为静态上下文所引用。(因为静态变数在内存中的位置是一开始就知道的,而动态变数是程序执行中才会知道的)修改的办法除了上面的方法以外,我们也可以将内部类改为静态的内部类,如下:
在下面这个范例中,内部类作为判断目前数组 index 的方法,它可以存取 private 属性的 ObArray 以判断和实现 InnerPointer 接口,如下:
.this 和 .new
如下:
一个类是可以在其它类中定义的类,我们可以将数据储存在有意义的内部类,在别人调用我们类、运用相关方法的时候,能做更有序、灵活的运用,如下:
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(); } }
相关文章推荐
- JAVA 复习(Think In Java, 4th) -- Arrays - part1
- JAVA 复习(Think In Java, 4th) -- Inner Classes - Part2
- JAVA 复习(Think In Java, 4th) -- Error Handling with Exceptions
- JAVA 复习(Think In Java, 4th) -- Interface
- JAVA 复习(Think In Java, 4th)-- Holding Your Object
- JAVA 复习(Think In Java, 4th) -- File I/O -- Part 1
- JAVA 复习(Think In Java, 4th)-- Holding Your Object
- JAVA 复习(Think In Java, 4th) -- File I/O -- part 2
- 数据结构复习笔记(Data Structures & Algorithms in Java, 4th) --Garbage Collection
- 读书笔记 Think in Java 4th 第十一章 持有对象 List、Set、Queue和Map
- Think In Java 笔记6 Inner Classes
- 如何下载并使用think in java 4th中的源代码
- 现在开始研究java,主攻Think in java 4th
- Think in Java 4th--Java中的volatile
- 看think in java 4th持有对象一章的Map小结,因为一个例子,重新总结下hashCode()和equals(),加深印象。
- 读书笔记 Think in Java 4th 第三章 操作符
- Think in java 答案_Chapter 3_Exercise 3
- Think in java 答案_Chapter 2_Exercise 8
- Think in java 答案_Chapter 3_Exercise 1
- Think in java 答案_Chapter 2_Exercise 12