国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁(yè) > 編程 > Java > 正文

Java嵌套類(lèi)和內(nèi)部類(lèi)詳解

2019-11-26 15:12:29
字體:
來(lái)源:轉(zhuǎn)載
供稿:網(wǎng)友

一、什么是嵌套類(lèi)及內(nèi)部類(lèi)?

    可以在一個(gè)類(lèi)的內(nèi)部定義另一個(gè)類(lèi),這種類(lèi)稱(chēng)為嵌套類(lèi)(nested classes),它有兩種類(lèi)型:
靜態(tài)嵌套類(lèi)和非靜態(tài)嵌套類(lèi)。靜態(tài)嵌套類(lèi)使用很少,最重要的是非靜態(tài)嵌套類(lèi),也即是被稱(chēng)作為
內(nèi)部類(lèi)(inner)。嵌套類(lèi)從JDK1.1開(kāi)始引入。其中inner類(lèi)又可分為三種:

    其一、在一個(gè)類(lèi)(外部類(lèi))中直接定義的內(nèi)部類(lèi);
    其二、在一個(gè)方法(外部類(lèi)的方法)中定義的內(nèi)部類(lèi);
    其三、匿名內(nèi)部類(lèi)。

下面,我將說(shuō)明這幾種嵌套類(lèi)的使用及注意事項(xiàng)。

二、靜態(tài)嵌套類(lèi)

    如下所示代碼為定義一個(gè)靜態(tài)嵌套類(lèi),

復(fù)制代碼 代碼如下:

public class StaticTest {
private static String name = "javaJohn";
private String id = "X001";

static class Person{
private String address = "swjtu,chenDu,China";
public String mail = "josserchai@yahoo.com";//內(nèi)部類(lèi)公有成員
public void display(){
//System.out.println(id);//不能直接訪問(wèn)外部類(lèi)的非靜態(tài)成員
System.out.println(name);//只能直接訪問(wèn)外部類(lèi)的靜態(tài)成員
System.out.println("Inner "+address);//訪問(wèn)本內(nèi)部類(lèi)成員。
}
}

public void printInfo(){
Person person = new Person();
person.display();

//System.out.println(mail);//不可訪問(wèn)
//System.out.println(address);//不可訪問(wèn)

System.out.println(person.address);//可以訪問(wèn)內(nèi)部類(lèi)的私有成員
System.out.println(person.mail);//可以訪問(wèn)內(nèi)部類(lèi)的公有成員

}
public static void main(String[] args) {
StaticTest staticTest = new StaticTest();
staticTest.printInfo();
}
}

在靜態(tài)嵌套類(lèi)內(nèi)部,不能訪問(wèn)外部類(lèi)的非靜態(tài)成員,這是由Java語(yǔ)法中"靜態(tài)方法不能直接訪問(wèn)非靜態(tài)成員"所限定。
若想訪問(wèn)外部類(lèi)的變量,必須通過(guò)其它方法解決,由于這個(gè)原因,靜態(tài)嵌套類(lèi)使用很少。注意,外部類(lèi)訪問(wèn)內(nèi)
部類(lèi)的的成員有些特別,不能直接訪問(wèn),但可以通過(guò)內(nèi)部類(lèi)來(lái)訪問(wèn),這是因?yàn)殪o態(tài)嵌套內(nèi)的所有成員和方法默認(rèn)為
靜態(tài)的了。同時(shí)注意,內(nèi)部靜態(tài)類(lèi)Person只在類(lèi)StaticTest 范圍內(nèi)可見(jiàn),若在其它類(lèi)中引用或初始化,均是錯(cuò)誤的。

三、在外部類(lèi)中定義內(nèi)部類(lèi)

    如下所示代碼為在外部類(lèi)中定義兩個(gè)內(nèi)部類(lèi)及它們的調(diào)用關(guān)系:

復(fù)制代碼 代碼如下:

public class Outer{
int outer_x = 100;

class Inner{
public int y = 10;
private int z = 9;
int m = 5;
public void display(){
System.out.println("display outer_x:"+ outer_x);
}
private void display2(){
System.out.println("display outer_x:"+ outer_x);
}

}

void test(){
Inner inner = new Inner();
inner.display();
inner.display2();
//System.out.println("Inner y:" + y);//不能訪問(wèn)內(nèi)部?jī)?nèi)變量
System.out.println("Inner y:" + inner.y);//可以訪問(wèn)
System.out.println("Inner z:" + inner.z);//可以訪問(wèn)
System.out.println("Inner m:" + inner.m);//可以訪問(wèn)

InnerTwo innerTwo = new InnerTwo();
innerTwo.show();
}

class InnerTwo{
Inner innerx = new Inner();
public void show(){
//System.out.println(y);//不可訪問(wèn)Innter的y成員
//System.out.println(Inner.y);//不可直接訪問(wèn)Inner的任何成員和方法
innerx.display();//可以訪問(wèn)
innerx.display2();//可以訪問(wèn)
System.out.println(innerx.y);//可以訪問(wèn)
System.out.println(innerx.z);//可以訪問(wèn)
System.out.println(innerx.m);//可以訪問(wèn)
}
}

public static void main(String args[]){
Outer outer = new Outer();
outer.test();
}
}

以上代碼需要說(shuō)明有,對(duì)于內(nèi)部類(lèi),通常在定義類(lèi)的class關(guān)鍵字前不加public 或 private等限制符,若加了
沒(méi)有任何影響,同時(shí)好像這些限定符對(duì)內(nèi)部類(lèi)的變量和方法也沒(méi)有影響(?)。另外,就是要注意,內(nèi)部類(lèi)Inner及
InnterTwo只在類(lèi)Outer的作用域內(nèi)是可知的,如果類(lèi)Outer外的任何代碼嘗試初始化類(lèi)Inner或使用它,編譯就不
會(huì)通過(guò)。同時(shí),內(nèi)部類(lèi)的變量成員只在內(nèi)部?jī)?nèi)內(nèi)部可見(jiàn),若外部類(lèi)或同層次的內(nèi)部類(lèi)需要訪問(wèn),需采用示例程序
中的方法,不可直接訪問(wèn)內(nèi)部類(lèi)的變量。

四、在方法中定義內(nèi)部類(lèi)
    如下所示代碼為在方法內(nèi)部定義一個(gè)內(nèi)部類(lèi):

public class FunOuter {
int out_x = 100;

public void test(){
class Inner{
String x = "x";
void display(){
System.out.println(out_x);
}
}
Inner inner = new Inner();
inner.display();
}

public void showStr(String str){
//public String str1 = "test Inner";//不可定義,只允許final修飾
//static String str4 = "static Str";//不可定義,只允許final修飾
String str2 = "test Inner";
final String str3 = "final Str";
class InnerTwo{
public void testPrint(){
System.out.println(out_x);//可直接訪問(wèn)外部類(lèi)的變量
//System.out.println(str);//不可訪問(wèn)本方法內(nèi)部的非final變量
//System.out.println(str2);//不可訪問(wèn)本方法內(nèi)部的非final變量
System.out.println(str3);//只可訪問(wèn)本方法的final型變量成員
}
}
InnerTwo innerTwo = new InnerTwo();
innerTwo.testPrint();
}

public void use(){
//Inner innerObj = new Inner();//此時(shí)Inner己不可見(jiàn)了。
//System.out.println(Inner.x);//此時(shí)Inner己不可見(jiàn)了。
}


public static void main(String[] args) {
FunOuter outer = new FunOuter();
outer.test();
}
}


從上面的例程我們可以看出定義在方法內(nèi)部的內(nèi)部類(lèi)的可見(jiàn)性更小,它只在方法內(nèi)部
可見(jiàn),在外部類(lèi)(及外部類(lèi)的其它方法中)中都不可見(jiàn)了。同時(shí),它有一個(gè)特點(diǎn),就是方法
內(nèi)的內(nèi)部類(lèi)連本方法的成員變量都不可訪問(wèn),它只能訪問(wèn)本方法的final型成員。同時(shí)另一個(gè)
需引起注意的是方法內(nèi)部定義成員,只允許final修飾或不加修飾符,其它像static等均不可用。

五、匿名內(nèi)部類(lèi)
    如下所示代碼為定義一個(gè)匿名內(nèi)部類(lèi):匿名內(nèi)部類(lèi)通常用在Java的事件處理上

復(fù)制代碼 代碼如下:

import java.applet.*;
import java.awt.event.*;

    public class AnonymousInnerClassDemo extends Applet{
    public void init(){
        addMouseListener(new MouseAdapter(){
            public void mousePressed(MouseEvent me){
             showStatus("Mouse Pressed!");
        }
        })
    }
    public void showStatus(String str){
        System.out.println(str);
    }
    }

在上面的例子中,方法addMouseListener接受一個(gè)對(duì)象型的參數(shù)表達(dá)式,于是,在參數(shù)里,我們定義了一個(gè)匿名內(nèi)部類(lèi)這個(gè)類(lèi)是一個(gè)MouseAdapter類(lèi)型的類(lèi),同時(shí)在這個(gè)類(lèi)中定義了一個(gè)繼承的方法mousePressed,整個(gè)類(lèi)做為一個(gè)參數(shù)。這個(gè)類(lèi)沒(méi)有名稱(chēng),但是當(dāng)執(zhí)行這個(gè)表達(dá)式時(shí)它被自動(dòng)實(shí)例化。同時(shí)因?yàn)椋@個(gè)匿名內(nèi)部類(lèi)是定義在AnonymousInnerClassDemo 類(lèi)內(nèi)部的,所以它可以訪問(wèn)它的方法showStatus。這同前面的內(nèi)部類(lèi)是一致的。

六、內(nèi)部類(lèi)使用的其它的問(wèn)題

通過(guò)以上,我們可以清楚地看出內(nèi)部類(lèi)的一些使用方法,同時(shí),在許多時(shí)候,內(nèi)部類(lèi)是在如Java的事件處理、或做為值對(duì)象來(lái)使用的。同時(shí),我們需注意最后一個(gè)問(wèn)題,那就是,內(nèi)部類(lèi)同其它類(lèi)一樣被定義,同樣它也可以繼承外部其它包的類(lèi)和實(shí)現(xiàn)外部其它地方的接口。同樣它也可以繼承同一層次的其它的內(nèi)部類(lèi),甚至可以繼承外部類(lèi)本身。下面我們給出最后一個(gè)例子做為結(jié)束:

復(fù)制代碼 代碼如下:

public class Layer {
//Layer類(lèi)的成員變量
private String testStr = "testStr";

//Person類(lèi),基類(lèi)
class Person{
String name;
Email email;
public void setName(String nameStr){
this.name = nameStr;
}
public String getName(){
return this.name;
}
public void setEmail(Email emailObj){

this.email = emailObj;
}
public String getEmail(){
return this.email.getMailStr();
}
//內(nèi)部類(lèi)的內(nèi)部類(lèi),多層內(nèi)部類(lèi)
class Email{
String mailID;
String mailNetAddress;
Email(String mailId,String mailNetAddress){
this.mailID = mailId;
this.mailNetAddress = mailNetAddress;
}
String getMailStr(){
return this.mailID +"@"+this.mailNetAddress;
}
}
}
//另一個(gè)內(nèi)部類(lèi)繼承外部類(lèi)本身
class ChildLayer extends Layer{
void print(){
System.out.println(super.testStr);//訪問(wèn)父類(lèi)的成員變量
}
}
//另個(gè)內(nèi)部類(lèi)繼承內(nèi)部類(lèi)Person
class OfficePerson extends Person{
void show(){
System.out.println(name);
System.out.println(getEmail());
}
}
//外部類(lèi)的測(cè)試方法
public void testFunction(){
//測(cè)試第一個(gè)內(nèi)部類(lèi)
ChildLayer childLayer = new ChildLayer();
childLayer.print();

//測(cè)試第二個(gè)內(nèi)部類(lèi)
OfficePerson officePerson = new OfficePerson();
officePerson.setName("abner chai");
//注意此處,必須用 對(duì)象.new 出來(lái)對(duì)象的子類(lèi)對(duì)象
//而不是Person.new Email(...)
//也不是new Person.Email(...)
officePerson.setEmail(officePerson.new Email("josserchai","yahoo.com"));

officePerson.show();
}
public static void main(String[] args) {
Layer layer = new Layer();
layer.testFunction();
}
}

發(fā)表評(píng)論 共有條評(píng)論
用戶(hù)名: 密碼:
驗(yàn)證碼: 匿名發(fā)表
主站蜘蛛池模板: 博乐市| 宿迁市| 烟台市| 洛南县| 金秀| 永寿县| 赤水市| 喀喇| 桦川县| 垫江县| 黄骅市| 开平市| 汾阳市| 绥芬河市| 梓潼县| 洪江市| 廉江市| 丹江口市| 丰顺县| 清徐县| 确山县| 平阴县| 上犹县| 清水河县| 合肥市| 漾濞| 大英县| 岐山县| 临漳县| 淳化县| 澄迈县| 韩城市| 泾源县| 建昌县| 洞口县| 封丘县| 沁阳市| 红原县| 高邑县| 潼南县| 犍为县|