轉帖|其它|編輯:郝浩|2010-12-09 13:19:31.000|閱讀 461 次
概述:對于Java內部類,大家實際上了解不多。在這里我們以實際代碼的形式,為大家詳細介紹Java內部類在GUI設計的作用。
# 界面/圖表報表/文檔/IDE等千款熱門軟控件火熱銷售中 >>
對于Java內部類,大家實際上了解不多。在這里我們以實際代碼的形式,為大家詳細介紹Java內部類在GUI設計的作用。
Java內部類其實在J2EE編程中使用較少,不過在窗口應用編程中特別常見,主要用來事件的處理。其實,做非GUI編程,內部類完全可以不用。
內部類的聲明、訪問控制等于外部類有所不同,要靈活使用內部類來編寫程序,還是有相當難度的,Java發明了這種難懂的玩意兒,在其他語言中是沒有的,但是在Java中,內部類也相當的重要,尤其做GUI開發時候,事件的響應處理全靠內部類了。
內部類所做的功能使用外部類也同樣可以實現,只是有時候內部類做的更巧妙些。
內部類按照其所在位置不同,可分為以下幾種:
1、(普通的)內部類(最常見的內部類,內部類的定義與類成員平級,)
2、方法內部類
3、匿名類
4、靜態內部類
5、接口內部類
一、內部類聲明與訪問
1、內部類直接在類的內部進行聲明。可以聲明為private、protected、public或者默認訪問權限,這個訪問權限約定和外部類完全一樣。
2、內部類自動擁有對其外圍類所有成員(方法、屬性)的訪問權。如果內部類和外部類成員的名字完全相同,在內部類方法中要訪問外部類成員,則需要使用下面的方式來訪問:外部類名.this.外部成員名,例如Outer.this.i++; (看例子)
3、必須使用外部類對象來創建內部類對象,而不是直接去new一個。
格式為:外部對象名.new 內部類構造方法
比如要創建一個內部類iner對象,需要這么做:
Outer outer = new Outer();
Outer.Inner iner = outer.new Inner();
/**
* 內部類創建與初始化
*
* @author leizhimin 2009-7-17 13:51:52
*/
public class Outer {
private int i = 10;
private int y = 8;
Outer() {
System.out.println("調用Outer構造方法:outer");
}
public void sayMsg() {
System.out.println("Outer class!");
}
class Inner {
int i = 1000;
Inner() {
System.out.println("調用Inner構造方法:inner");
}
void innerMsg() {
System.out.println(">>>>>Inner class!");
sayMsg();
//訪問內部類自己的成員i,也可以寫成 this.i++
this.i++;
//訪問外部類的成員 i和y
Outer.this.i++;
y--;
}
int getI() {
return i;
}
}
public void test() {
Inner in = new Inner();
in.innerMsg();
}
public int getI() {
return i;
}
public void setI(int i) {
this.i = i;
}
}
class Test1 {
public static void main(String[] args) {
Outer outer = new Outer();
outer.test();
System.out.println(outer.getI());
System.out.println("-------1--------");
Outer.Inner iner = outer.new Inner();
iner.innerMsg();
System.out.println(iner.getI());
System.out.println("-------2--------");
System.out.println(outer.getI());
}
}
運行結果:
調用Outer構造方法:outer
調用Inner構造方法:inner
>>>>>Inner class! Outer class! 11 -------1--------
調用Inner構造方法:inner
>>>>>Inner class! Outer class! 1001 -------2-------- 12 Process finished with exit code 0
二、內部類與接口
1、內部類可以實現接口。
2、內部類之間相互可見,但并非內部類之間方法都可見。
public interface Foo{
void say();
}
public interface Bar {
void readme();
}
/**
* 內部類實現接口
*
* @author leizhimin 2009-7-17 14:57:50
*/
public class Test2 {
public static void main(String[] args) {
Outer outer = new Outer();
Foo f = outer.genFoo();
Bar b = outer.genBar();
f.say();
b.readme();
}
}
class Outer {
private class FooImpl implements Foo {
public void say() {
System.out.println("say foo!");
}
}
private class BarImpl implements Bar {
public void readme() {
System.out.println("say bar!");
}
}
public Foo genFoo() {
return new FooImpl();
}
public Bar genBar() {
return new BarImpl();
}
}
輸入結果:
say foo!
say bar!
Process finished with exit code 0
三、訪問權限
外部類分兩種:
一種嵌入了內部類聲明代碼外部類,稱為直接外部類。 另一種是與內部類沒有任何關系的外部類,稱為外部類。
在同一個直接外部類中,內部類之間所有的方法都是相互可見的,包含在直接外部類的main()中可見。
在外部類中,要看到一個類的內部類成員,則至少要求這個內部類的class和成員權限大于或等于protected。
/**
* 內部類實現接口
*
* @author leizhimin 2009-7-17 14:57:50
*/
public class Test2 {
public static void main(String[] args) {
Outer o = new Outer();
Outer.Bar b = o.genBar();
b.readme();
}
}
class Outer {
protected class Foo {
protected void say() {
System.out.println("say foo!");
}
private void test() {
System.out.println("----test------");
}
}
protected class Bar {
protected void readme() {
System.out.println("say bar!");
new Foo().test();
}
}
public Foo genFoo() {
return new Foo();
}
public Bar genBar() {
return new Bar();
}
}
四、方法內部類
方法內部類只在該方法內部可見,方法內部類可以定義在方法中的任何位置。
/**
* 內部類實現接口
*
* @author leizhimin 2009-7-17 14:57:50
*/
public class Test2 {
public static void main(String[] args) {
Outer outer = new Outer();
Foo f = outer.genFoo();
Bar b = outer.genBar();
f.say();
b.readme();
}
}
class Outer {
public Foo genFoo() {
//方法內的內部類
class FooImpl implements Foo {
public void say() {
System.out.println("say foo!");
}
}
return new FooImpl();
}
public Bar genBar() {
Bar b = null;
if (true) {
//任意位置的內部類
class BarImpl implements Bar {
public void readme() {
System.out.println("say bar!");
}
}
b = new BarImpl();
}
return b;
}
}
運行結果:
say foo!
say bar!
Process finished with exit code 0
五、匿名類
匿名類不給出類名,直接定義一個類,通常這個類實現了某種接口或者抽象。匿名類的訪問權限更沒有討論價值了,看個例子就行了。
在一些多線程程序中比較常見,有點變態,呵呵。
/**
* 匿名類.
*
* @author leizhimin 2009-7-17 15:56:17
*/
public class Test3 {
public Foo f = new Foo() {
public void say() {
System.out.println("O(∩_∩)O哈哈~!");
}
};
public Foo test() {
return new Foo() {
public void say() {
System.out.println("say foo!");
}
};
}
public static void main(String[] args) {
Test3 t = new Test3();
t.f.say();
t.test().say();
}
}
interface Foo {
void say();
}
運行結果:
say foo!
Process finished with exit code 0
/**
* 普通類的匿名初始化
*
* @author leizhimin 2009-7-17 16:13:31
*/
public class Fk {
private String x;
public Fk(String x) {
this.x = x;
}
@Override
public String toString() {
return "Fk{" +
"x='" + x + '\'' +
'}';
}
}
class Test4 {
public Fk hehe() {
//把后面的一對大括號去掉呢,呵呵
return new Fk("fk") {
};
}
public static void main(String[] args) {
Test4 t = new Test4();
Fk f = t.hehe();
System.out.println(f);
}
}
運行結果:
Fk{x='fk'}
Process finished with exit code 0
還有一個不得不提的經典實例,來自thining in java,有改動:
interface Service {
void method1();
void method2();
}
interface ServiceFactory {
Service getService();
}
class Implementation1 implements Service {
private Implementation1() {}
public void method1() {System.out.println("Implementation1 method1");}
public void method2() {System.out.println("Implementation1 method2");}
public static ServiceFactory factory = new ServiceFactory() {
public Service getService() {
return new Implementation1();
}
};
}
class Implementation2 implements Service {
private Implementation2() {}
public void method1() {System.out.println("Implementation2 method1");}
public void method2() {System.out.println("Implementation2 method2");}
public static ServiceFactory factory = new ServiceFactory() {
public Service getService() {
return new Implementation2();
}
};
}
public class Factories {
public static void serviceConsumer(ServiceFactory fact) {
Service s = fact.getService();
s.method1();
s.method2();
}
public static void main(String[] args) {
serviceConsumer(Implementation1.factory);
serviceConsumer(Implementation2.factory);
}
}
這個應用給了我們很多思考,我就不說了,不同人看了會有不同的感受。
內部類的巧妙使用會讓你的代碼很牛,如果要形容下,那就是:沒看懂的時候感覺神出鬼沒,看懂后感覺鬼斧神工。不過這些代碼多了,別人想看懂都難,想看懂你思路就難上加難了。呵呵!
六、靜態內部類
靜態內部類是static class型的內部類,這種內部類特點是:它不能訪問外部類的非靜態成員。要創建靜態內部類對象時候,也不需要外部類對象了,直接可以:
new 外部類名.內部類構造方法
來創建,給個例子:
/**
* 靜態內部類
*
* @author leizhimin 2009-7-17 16:53:05
*/
public class Outer {
public static int i =500;
protected static class Inner {
int i =100;
String name;
Inner(String name) {
this.name = name;
}
void sayHello() {
System.out.println("Hello " + name);
Outer.i++;
}
}
public Inner genInner(String name) {
return new Inner(name);
}
}
class Test {
public static void main(String[] args) {
Outer.Inner in1 = new Outer.Inner("1111");
in1.sayHello();
System.out.println(Outer.i);
Outer.Inner in2 = new Outer().genInner("2222");
in2.sayHello();
System.out.println(Outer.i);
}
}
運行結果:
Hello 1111
501
Hello 2222
502
Process finished with exit code 0
七、接口內部類
接口內部類自動都是public static的,相當于為接口定義了一種變量類型,這在java的設計中就有使用,比如在HashMap中,就有:
static class Entry implements Map.Entry
下面我給個例子,
/**
* 接口內部類
*
* @author leizhimin 2009-7-17 17:20:28
*/
public interface AInterface {
void readme();
class Inner1 implements AInterface {
public void readme() {
System.out.println("我是一個接口內部類");
}
}
}
class Main {
public static void main(String[] args) {
AInterface.Inner1 in1 = new AInterface.Inner1();
in1.readme();
}
}
八、內部的類的嵌套
所謂內部類嵌套,就是內部類里面再定義內部類。其實這種用法還真沒見過,試試寫個簡單例子看看吧:
/**
* 嵌套內部類
*
* @author leizhimin 2009-7-17 17:33:48
*/
public class Outer {
private void f0() {
System.out.println("f0");
}
class A {
private void a() {
f0();
System.out.println("a");
}
class B {
protected void b() {
a();
System.out.println("b");
}
}
}
}
class Test{
public static void main(String[] args) {
Outer o = new Outer();
Outer.A a = o.new A();
Outer.A.B b = a.new B();
b.b();
}
}
運行結果:
f0
a
b
Process finished with exit code 0
九、內部類的繼承
內部類的繼承,可以繼承內部類,也可以繼承外部類。
/**
* 內部類的繼承,可以繼承內部類,也可以繼承外部類
*
* @author leizhimin 2009-7-22 13:50:01
*/
public class Outer {
class Inner {
void doSomething() {
System.out.println("Inner doing ...");
}
}
class Inner2 extends Inner {
void doSomething() {
System.out.println("Inner2 doing ...");
}
void readme() {
System.out.println("HeHe!");
}
}
}
class Test {
public static void main(String[] args) {
Outer outer = new Outer();
Outer.Inner in = outer.new Inner();
Outer.Inner2 in2 = outer.new Inner2();
in.doSomething();
in2.doSomething();
in2.readme();
}
}
運行結果:
Inner doing ...
Inner2 doing ...
HeHe!
Process finished with exit code 0
總結:
內部類是Java中最復雜深奧的概念之一,而且內部類在訪問控制,修飾符,繼承,實現,抽象,序列化等等很多方面都是一個很讓人迷惑的問題,在實際中,這些問題也許永遠沒機會沒時間搞清,但是一般說來,懂得以上的內部類的知識就足夠用了。
內部類的設計也許是彌補Java語言本身的先天不足吧,作為語言來說,這個特性太變態了點,難道就沒別的法了?
以上的總結完全是建立在實踐基礎上的,所列舉的例子也許偏頗,不能全面反映問題的本質,希望有興趣的博友多多發表自己的看法與觀點。
本站文章除注明轉載外,均為本站原創或翻譯。歡迎任何形式的轉載,但請務必注明出處、不得修改原文相關鏈接,如果存在內容上的異議請郵件反饋至chenjj@fc6vip.cn
文章轉載自:網絡轉載