對內部類用的少,基本上都有點陌生了。今天看到一個博客感覺還不錯就轉了過來。先謝謝博主!!!
1.關於內部類的說明
1)在一個類中定義另外一個類,這個類就叫做內部類(inner class) 。內部類的定義和普通類的定義沒什麼區別,它可以直接訪問和引用它的外部類的所有變量和方法(包括private),就像外部類中的其他非static成員的功能一樣。區別是,外部類只能聲明爲public和default,而內部類可以聲明爲private和protected。 中國自學編程網 www.zxbc.cn
2)當我們建立一個inner class時,其對象就擁有了與外部類對象之間的一種關係,這是通過一個特殊的this reference形成的,當內部類的成員方法中訪問某個變量/方法時,如果在該方法和內部類中都沒有定義過這個變量,調用就會被傳遞給內部類中保存的那個外部類對象的引用(OuterClass.this),通過那個外部類對象的引用去調用這個變量。
2.內部類變量訪問
2.1在main中直接從外部類調用內部類的方法
package org.zj.sample;
class Outer {
private int index = 100;
class Inner {
private int index = 50;
void print() {
int index = 30;
System.out.println(index); // 30
System.out.println(this.index); // 50
System.out.println(Outer.this.index); // 100
}
}
void print() {
Inner inner = new Inner();//得到內部類的引用
inner.print();
}
}
class Test {
public static void main(String[] args) {
Outer outer = new Outer();
outer.print();
}
}
該示例程序列出了重名成員變量分佈的3種情況。
訪問內部類方法中的變量:
System.out.println(index);
訪問內部類中的成員變量:
System.out.println(this.index);
訪問所在外部類的成員變量:
System.out.println(Outer.this.index);
2.2在main中顯式返回內部類引用
package org.zj.example;
class Outer {
private int index = 100;
class Inner {
private int index = 50;
void print() {
int index = 30;
System.out.println(index); // 30
System.out.println(this.index); // 50
System.out.println(Outer.this.index); // 100
}
}
Inner getInner() {
return new Inner();//返回一個內部類的引用
}
}
class Test {
public static void main(String[] args) {
Outer outer = new Outer();
Outer.Inner inner = outer.getInner();
inner.print();
}
}
2.3當main方法在Outer類內部
package org.zj.sample1;
class Outer {
private int index = 100;
class Inner {
private int index = 50;
void print() {
int index = 30;
System.out.println(index); // 30
System.out.println(this.index); // 50
System.out.println(Outer.this.index); // 100
}
}
Inner getInner() {
return new Inner();
}
public static void main(String[] args) {
Outer outer = new Outer();
Inner inner = outer.getInner(); // 注意此處變化
inner.print();
}
}
2.4在main方法中直接產生內部類對象
package org.zj.sample2;
class Outer {
private int index = 100;
class Inner {
private int index = 50;
void print() {
int index = 30;
System.out.println(index); // 30
System.out.println(this.index); // 50
System.out.println(Outer.this.index); // 100
}
}
}
class Test {
public static void main(String[] args) {
Outer outer = new Outer();
Outer.Inner inner = outer.new Inner(); // 注意此處變化
inner.print();
}
}
2.5在方法中定義內部類
在方法中定義的內部類只能訪問方法中的final類型的局部變量,因爲用final定義的局部變量相當於是一個常量,它的生命週期超出方法運行的生命週期。而且方法體中的內部類不能有訪問說明符。
package org.zj.sample;
class InOut {
String str=new String("Between");
public void amethod(final int aArgs){
class Inner{
public Inner(){
System.out.println("This is Inner.");//此句可看出它與匿名內部類用法的不同。
}
public void sayHello(){
System.out.println(str);
System.out.println(aArgs);
}
}
Inner inner=new Inner();//此句必須放在定義類Inner的後面
inner.sayHello();
}
public static void main(String[] args){
InOut inOut=new InOut();
inOut.amethod(33);
}
}
在方法體中使用內部類可以使用一個已命名的構造子,或重載構造子。而匿名內部類只能用於實例初始化。
3.內部類的繼承
當一個類繼承自一個內部類時,缺省的構造器不可用。必須使用如下語法:
enclosingClassReference.super();(見下例綠色部分)
package org.zj.sample;
class WithInner{
class Inner{
public void sayHello(){
System.out.println("Hello.");
}
}
}
public class InheritInner extends WithInner.Inner {
InheritInner(WithInner wi){
wi.super();
}
public static void main(String[] args) {
WithInner wi=new WithInner();
InheritInner ii=new InheritInner(wi);
ii.sayHello();
}
}
結果:
Hello.
4.匿名內部類
未使用匿名內部類的情況:這裏單獨寫了一個內部類Inner。
package org.zj.example;
abstract class A{
abstract public void sayHello();
}
class Outer {
public static void main(String[] args){
class Inner extends A{
public void sayHello(){
System.out.println("Hello!");
}
}
new Outer().callInner(new Inner());
}
public void callInner(A a){
a.sayHello();
}
}
使用匿名內部類的情況:直接在new A()中給出Inner的定義。
package org.zj.example;
abstract class A{
abstract public void sayHello();
}
class Outer {
public static void main(String[] args){
new Outer().callInner(new A(){
public void sayHello(){
System.out.println("Hello!");
}
});
}
public void callInner(A a){
a.sayHello();
}
}
5.內部類的2種特殊用法
一個類從另一個類派生出來,又要實現一個接口。但在接口中定義的方法與父類中定義的方法的意義不同,則可以利用內部類來解決這個問題。
package org.zj.sample;
interface Machine {
void run();
}
class Person {
void run() {
System.out.println("run");
}
}
class Robot extends Person {
private class MachineHeart implements Machine {
public void run() {
System.out.println("heart run");
}
}
Machine getMachine() {
return new MachineHeart();
}
}
class Test {
public static void main(String[] args) {
Robot robot = new Robot();
Machine m = robot.getMachine();
m.run();
robot.run();
}
}
在Robot類內部使用內部類MachineHeart來實現接口Machine的run方法。同時Robot類又繼承了父類Person的run方法。如果不使用內部類MachineHeart而使Robot直接實現接口Machine,則該如何調用父類的run方法?
利用內部類可解決c++中多重繼承所解決的問題
package org.zj.example;
class A {
void fn1() {
System.out.println("It’s fn1.");
}
}
abstract class B {
abstract void fn2();
}
class C extends A {
B getB() {
return new B() {
public void fn2() {
System.out.println("It’s fn2.");
}
};
}
}
class Test {
public static void main(String[] args) {
C c = new C();
c.fn1();
c.getB().fn2();
}
}
類C既要繼承類A又要繼承類B,則可將類B的定義放入類C內部,使之成爲內部類。
6.我們爲什麼使用內部類
這是對上一章節兩種用法的總結,可結合上一章節的兩個實例分析。
1) 當我們需要在某一情形下實現一個接口,而在另一情形下又不需要實現這個接口時,我們可以使用內部類來解決這一問題。讓內部類來實現這個接口。
2) 內部類有效的解決了多重繼承的問題。
本文來自CSDN博客,轉載請標明出處:http://blog.csdn.net/armyjian/archive/2007/11/05/1867936.aspx