站内搜索: 请输入搜索关键词

当前页面: 开发资料首页Java 专题Java编程思想(2nd)学习笔记(8)-2

Java编程思想(2nd)学习笔记(8)-2

摘要: Java编程思想(2nd)学习笔记(8)-2

二. Inner classes(内隐类)
1. 内隐类的基本用法
1) 如果要在外围class的non-static函数之外产生一个inner class对象,
得以OuterClassName.InnerClassName的形式指定该对象的型别。而在non-static函数内则不用。
public class ExplicitStatic{
class Contents{
private int i = 11;
public int value() { return i; } }
class Destination{
private String label;
Destination(String whereTo){
label = whereTo; }
String readLabel() { return label; } }
public Destination to(String s){
//在outer class的non-static函数中可直接产生inner class对象
return new Destination(s); //(1) }
public Contents cont(){
return new Contents(); //(1) }
public void ship(String dest){
//在outer class的non-static函数中可直接通过InnerClassName
//来指定对象型别
Contents c = cont();
Destination d = to(dest);
System.out.println(d.readLabel()); }
public static void main(String[] args){
ExplicitStatic p = new ExplicitStatic();
p.ship("Tanzania");
ExplicitStatic q = new ExplicitStatic();
//在outer class的非non-static函数内产生inner class对象
ExplicitStatic.Contents c = q.cont();
ExplicitStatic.Destination d = q.to("Borneo");
//不能在static函数直接生成inner class对象
// new Contents(); } }
2) 对于non-static inner class,在外围class的non-static函数可以通
过new产生一个inner class对象,如上面的(1)处。但要在非non-static函数产生
一个inner class对象,则一定要关联到其enclosing class的某个对象。
3) inner class的向上转型
当把一个inner class对象向上转型成为interface时,我们得到的只是一个
reference。
interface Destination{
String readLabel(); }
interface Contents{
int value(); }
class Parcel3{
private class PContents implements Contents{
private int i = 11;
public int value() { return i; } }
protected class PDestination implements Destination{
private String label;
PDestination(String whereTo){
label = whereTo; }
public String readLabel() { return label; } }
public Destination to(String s){
return new PDestination(s); }
public Contents cont(){
return new PContents(); } }
public class ExplicitStatic{
public static void main(String[] args){
Parcel3 p = new Parcel3();
//把inner class对象向上转型
Contents c = p.cont();
Destination d = p.to("Borneo"); } }
虽然我们不能在ExplicitStatic class无法调用Pcontents class,但我们把一个
Pcontents class对象向上转型为Contents,就可对之进行调用。
4) inner class的作用域为定义该inner class的scope内。但inner 
class可在它的作用域之外被继承(见4)。
interface Contents{
int value(); }
class Parcel3{
//PContents1 class的作用域为Parcel3 class内
private class PContents1 implements Contents{
private int i = 11;
public int value() { return i; } }
public Contents cont1(){
return new PContents1(); }
public Contents cont2(){
//PContents2 class的作用域为函数cont2内
class PContents2 implements Contents{
private int i = 11;
public int value() { return i; } }
return new PContents2(); }
//不能在函数cont2外使用PContents2 class /*
public Contents cont22(){
return new PContents2(); } */
public Contents cont3(boolean b){
if(b){
//PContents3 class的作用域为当前if内
class PContents3 implements Contents{
private int i = 11;
public int value() { return i; } }
return new PContents3(); }
//不能在if外使用PContents3 class
//return new PContents3();
return null; } }
public class ExplicitStatic{
public static void main(String[] args){
Parcel3 p = new Parcel3();
Contents c1 = p.cont1();
Contents c2 = p.cont2();
Contents c3 = p.cont3(true); } }
2. 内隐类与外围enclosing class的连接关系
2.1 non-static inner class
1) inner class可以访问enclosing class的所有成员(包括private成员
),就像inner class自己拥有这些成员一样。即inner class天生具有对
enclosing class的所有成员的访问权力。
2) Inner class对象被产生时,一定要关联到其enclosing class的某个
对象(这个enclosing class对象就是Inner class对象的制造者)。建构inner 
class对象的同时,得有其enclosing class对象的reference才行。
原因:因为inner class可以访问enclosing class的所有成员,那么当产生一个
inner class时,编译器会自动为inner class对象添加一个指向enclosing 
class对象的reference(这个reference是隐藏的)。所以Inner class被产生时,
一定要关联到其enclosing class的某个对象。
3) 同一个enclosing class对象产生出来的inner class对象访问的是同
一个enclosing class对象中的成员。
interface Destination{
String readLabel(); }
interface Contents{
int value(); }
class Parcel3{
int i1 = 10;
private String s1 = "Parcel3_";
Parcel3(String s){ s1 += s; }
private class PContents implements Contents{
//可调用enclosing class的成员 (1)
private int i2 = i1;
private String s2 = s1;
PContents(int num){
System.out.println("" + num + ": i2 = " + i2 + ",s2 = " + s2); }
public int value() { return 1; } }
public Contents cont(int i){
return new PContents(i); } }
public class ExplicitStatic{
public static void main(String[] args){
Parcel3 p1 = new Parcel3("1");
Contents c1 = p1.cont(1);
Contents c2 = p1.cont(2);
Parcel3 p2 = new Parcel3("2");
c2 = p2.cont(3);
c2 = p1.cont(4); } }
结果为:
1: i2 = 10,s2 = Parcel3_1
2: i2 = 10,s2 = Parcel3_1
3: i2 = 10,s2 = Parcel3_2
4: i2 = 10,s2 = Parcel3_1
在(1)在inner class调用了enclosing class的成员。结果表明,同一个
enclosing class对象p1产生的inner class对象调用的是同一个enclosing 
class对象中的成员,如结果中的1、2、4。
2.2  Static inner classes(静态内隐类)
1) 产生Static inner classes对象时,不需要同时存在一个enclosing class对象
2) 只能在Static inner classes对象中访问enclosing class中的静态成员。
interface Contents{
int value(); }
class Parcel1{
private static String s1 = "Parcel3_";
private String s11 = “Parcel3_”;
Parcel1(String s){
s1 += s; }
protected static class PContents implements Contents{
//只能访问enclosing class中的s1
String s2 = s1;
//s11不是static成员,不能访问
//String 22 = s11;
PContents(int num){
System.out.println("" + num + ":s2 = " + s2); }
public int value() { return 1; } }
public static Contents cont(int i){
return new PContents(i); } }
public class ExplicitStatic{
public static void main(String[] args){
Parcel1 p1 = new Parcel1("1");
Contents c1 = p1.cont(1);
c1 = Parcel1.cont(2);  //(1)
Parcel1 p2 = new Parcel1("2");
c1 = p2.cont(3);
c1 = Parcel1.cont(4); //(1) } }
因为内隐类Pcontents class是静态的,所以在(1)处不通过enclosing class对
象而是通过静态函数来直接产生其对象。
2.3 无论inner class被嵌套置放的层次有多深,且所有outer class的成员都可
被它访问。
class MNA{
private void f() {}
class A{
private void g() {}
class B{
void h(){
g(); f(); } } }
↑返回目录
前一篇: Java编程思想(2nd)学习笔记(8)-3
后一篇: Java编程思想(2nd)学习笔记(8)-1