您好,登錄后才能下訂單哦!
二. 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();
}
}
}
}
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。