成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專(zhuān)欄INFORMATION COLUMN

(Thinking in Java)第10章 內(nèi)部類(lèi)

Brenner / 816人閱讀

摘要:內(nèi)部類(lèi)中也可以取得這個(gè)外部類(lèi)對(duì)象引用。創(chuàng)建成員內(nèi)部類(lèi)對(duì)象的時(shí)候需要外部類(lèi)對(duì)象。另外在方法中的內(nèi)部類(lèi)不能加等權(quán)限修飾符,只能加和修飾符。可以在接口內(nèi)部定義內(nèi)部類(lèi),而且他們即使沒(méi)有修飾,也會(huì)自動(dòng)變成的。

Thinking in Java撈干貨,寫(xiě)筆記 一、成員內(nèi)部類(lèi) 1.最基本使用
public class Demo {
    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 void ship(String dest){
        Contents c=new Contents();
        Destination d=new Destination(dest);
        System.out.println(d.readLabel());
    }

    public static void main(String[] args) {
        Demo d=new Demo();
        d.ship("Tasmania");
    }
}
2.內(nèi)部類(lèi)可以訪(fǎng)問(wèn)外部類(lèi)的成員

內(nèi)部類(lèi)可以訪(fǎng)問(wèn)外部類(lèi)的成員變量。如下:

public class Demo {
    private Object[] items;
    private int next = 0;

    public Demo(int size) {
        items = new Object[size];
    }

    public void add(Object x) {
        if (next < items.length) {
            items[next++] = x;
        }
    }

    private class SequenceSelector implements Selector {
        private int i = 0;

        public boolean end() {
            return i == items.length;
        }

        public Object current() {
            return items[i];
        }

        public void next() {
            if (i < items.length) {
                i++;
            }
        }
    }

    public Selector selector() {
        return new SequenceSelector();
    }

    public static void main(String[] args) {
        Demo d = new Demo(10);
        for (int i = 0; i < 10; i++) {
            d.add(Integer.toString(i));
        }
        Selector selector = d.selector();
        while (!selector.end()) {
            System.out.print(selector.current() + " ");
            selector.next();
        }
    }
}

interface Selector {
    boolean end();

    Object current();

    void next();
}

因?yàn)樵趧?chuàng)建內(nèi)部類(lèi)對(duì)象的時(shí)候,內(nèi)部類(lèi)對(duì)象會(huì)捕獲一個(gè)指向外部類(lèi)對(duì)象的引用。訪(fǎng)問(wèn)外部類(lèi)成員的時(shí)候,就是用這個(gè)引用來(lái)獲取外部類(lèi)成員的。內(nèi)部類(lèi)中也可以取得這個(gè)外部類(lèi)對(duì)象引用。舉例如下:

public class DotThis{
    void f(){
        System.out.println("DotThis.f()");
    }
    class Inner{
        public DotThis outer(){
            return DotThis.this;
            //A plain "this" would be Inner"s this
        }
    }

    public Inner inner(){
        return new Inner();
    }

    public static void main(String[] args) {
        DotThis dt=new DotThis();
        DotThis.Inner dti=dt.inner();
        dti.outer().f();
    }
}

當(dāng)要在其他類(lèi)中創(chuàng)建一個(gè)內(nèi)部類(lèi)對(duì)象的時(shí)候,可以使用.new語(yǔ)法。

public class DotNew{
    public class Inner{
    }
    public static void main(String[] args){
        Inner dni=new DotNew().new Inner();
    }
}

當(dāng)創(chuàng)造內(nèi)部類(lèi)對(duì)象的時(shí)候,如果這個(gè)內(nèi)部類(lèi)不是嵌套類(lèi)(靜態(tài)內(nèi)部類(lèi)),那么就必須要通過(guò)外部類(lèi)對(duì)象,才能創(chuàng)建這個(gè)內(nèi)部類(lèi)對(duì)象,為什么呢,之前說(shuō)過(guò),因?yàn)檫@個(gè)內(nèi)部類(lèi)對(duì)象要獲取外部類(lèi)的引用啊。
并且在存在多個(gè)內(nèi)部類(lèi)的時(shí)候,多個(gè)內(nèi)部類(lèi)之間可以互相創(chuàng)建對(duì)象。例子就不舉了。

小結(jié):現(xiàn)在所說(shuō)的都是成員內(nèi)部類(lèi),其實(shí)內(nèi)部類(lèi)沒(méi)那么復(fù)雜,既然叫做成員內(nèi)部類(lèi)了,他就只是類(lèi)的成員罷了。他也可以帶修飾符,他的修飾符和其他普通的成員變量的修飾符的意義也沒(méi)有什么不同。

3.內(nèi)部類(lèi)權(quán)限修飾符

當(dāng)內(nèi)部類(lèi)被private修飾的時(shí)候,該類(lèi)只能被外部類(lèi)內(nèi)的方法使用,其他類(lèi)不能獲取該內(nèi)部類(lèi)的引用,因?yàn)槭莗rivate的,所以其他類(lèi)根本不知道存在一個(gè)這樣的類(lèi)。當(dāng)然也可以作為一個(gè)成員變量使用,但是如果作為成員變量,則其他類(lèi)并不能直接創(chuàng)建內(nèi)部類(lèi)的引用,需要用其他手段獲取該引用,如下:

class Outer{
    Inner in;
    private class Inner implements a_interface{
        void show(){
            System.out.println("123");
        }
    }
}
interface a_interface{
    void show();
}

class test{
    //Inner in=new Outer().in;這是錯(cuò)誤的,因?yàn)閠est并不知道Outer類(lèi)有一個(gè)Inner內(nèi)部類(lèi),因?yàn)槭撬接械?    a_interface in=new Outer().in;//可以運(yùn)用向上轉(zhuǎn)型的方法獲取private修飾的內(nèi)部類(lèi)。
}

小結(jié):其實(shí)這也很好記,無(wú)論是public還是private,修飾到內(nèi)部類(lèi)上的時(shí)候,和他們修飾普通的成員變量(如string,int之類(lèi))的時(shí)候沒(méi)什么不同,規(guī)則都一樣,public就都能使用,private就類(lèi)內(nèi)可以用。所以規(guī)則就記住三條就好:1.先考慮外部類(lèi)的權(quán)限,是否可以獲取一個(gè)外部類(lèi)對(duì)象。2.創(chuàng)建成員內(nèi)部類(lèi)對(duì)象的時(shí)候需要外部類(lèi)對(duì)象。3.考慮內(nèi)部類(lèi)的權(quán)限,是否可以獲取這樣的一個(gè)內(nèi)部類(lèi)對(duì)象(或者說(shuō),在外部知不知道有這樣一個(gè)內(nèi)部類(lèi))。

二、方法和作用域內(nèi)的內(nèi)部類(lèi)

當(dāng)我們需要解決一個(gè)復(fù)雜的問(wèn)題,想創(chuàng)建一個(gè)類(lèi)來(lái)輔助解決問(wèn)題,但是不希望這個(gè)類(lèi)是公共可用的,甚至不希望在外部類(lèi)之內(nèi)的其他地方可以訪(fǎng)問(wèn)到這個(gè)輔助類(lèi)。我們可以運(yùn)用方法內(nèi)的內(nèi)部類(lèi)

public class Outer {
    public InterfaceDemo get_InterfaceDemo(String s) {
         class InterfaceDemoTool implements InterfaceDemo {
            private String label;

            private InterfaceDemoTool(String label) {
                this.label = label;
            }

            public String readLabel() {
                return label;
            }
        }

        return new InterfaceDemoTool(s);
    }

    public static void main(String[] args) {
        Outer o = new Outer();
        InterfaceDemo i = o.get_InterfaceDemo("123");
    }
}

interface InterfaceDemo {
    String readLabel();
}

當(dāng)然在方法中還可以定義多個(gè)內(nèi)部類(lèi),并且這些內(nèi)部類(lèi)之間的關(guān)系和普通一個(gè)Java文件中多個(gè)類(lèi)之間的關(guān)系好像沒(méi)什么不同。也可以相互繼承和創(chuàng)建對(duì)象。另外在方法中的內(nèi)部類(lèi)不能加private等權(quán)限修飾符,只能加abstract和final修飾符。
另外也可以在某個(gè)作用域內(nèi)創(chuàng)建內(nèi)部類(lèi)對(duì)象

if(a==b){
     class inner{
     }
     new inner();
}
三、匿名內(nèi)部類(lèi)

下面這塊代碼中g(shù)et_inner()的意思是,創(chuàng)建一個(gè)繼承自InnerFather的匿名類(lèi)對(duì)象,并且自動(dòng)向上轉(zhuǎn)型為InnerFather后返回。

public class Outer {
    public InnerFather get_inner() {
        return new InnerFather() {
            void print(){
                System.out.println("Inner_Override");
            }
        };
    }

    class InnerFather {
        InnerFather() {

        }
        void print(){
            System.out.println("InnerFather");
        }
    }

    public static void main(String[] args) {
        Outer o = new Outer();
        InnerFather i = o.get_inner();
        i.print();
    }
}

當(dāng)然這只是有無(wú)參構(gòu)造函數(shù),當(dāng)父類(lèi)只有一個(gè)含參構(gòu)造函數(shù)的時(shí)候,我們可以這樣向匿名內(nèi)部類(lèi)傳入一個(gè)構(gòu)造函數(shù)參數(shù)。

public class Outer {
    public InnerFather get_inner(int i) {
        return new InnerFather(i) {
            void print(){
                System.out.println("Inner_Override");
            }
        };
    }

    class InnerFather {
        InnerFather(int i) {

        }
        void print(){
            System.out.println("InnerFather");
        }
    }

    public static void main(String[] args) {
        Outer o = new Outer();
        InnerFather i = o.get_inner(10);
        i.print();
    }
}

可以通過(guò)構(gòu)造代碼塊來(lái)實(shí)現(xiàn)匿名內(nèi)部類(lèi)的自定義的構(gòu)造函數(shù)

abstract class Base {
    public Base(int i) {
        System.out.println("Base constructor");
    }

    public abstract void f();
}

public class AnonymousConstructor {
    public static Base getBase(int i){
        return new Base(i){
            {System.out.println("AnonymousConstructor constructor");}
            public void f(){
            }
        };
    }

    public static void main(String[] args) {
        Base base = getBase(47);
    }
}

(書(shū)上說(shuō),如果傳入了新的對(duì)象,就比如下面例子中的s_in,這個(gè)s_in就必須是final的,但是我實(shí)驗(yàn)了一下發(fā)現(xiàn)并不用啊,我也沒(méi)太搞懂。)

abstract class Base {
    public Base(int i) {
        System.out.println("Base constructor");
    }

    public abstract void f();
}

public class AnonymousConstructor {
    public static Base getBase(int i,String s_in){
        return new Base(i){
            {System.out.println("AnonymousConstructor constructor");}//構(gòu)造代碼塊4.嵌套類(lèi)
            String s=s_in;
            public void f(){
            }
        };
    }

    public static void main(String[] args) {
        Base base = getBase(47,"hello");
    }
}
四、嵌套類(lèi)

嵌套類(lèi)指的是被static修飾的內(nèi)部類(lèi)。這意味著:1.創(chuàng)建嵌套類(lèi)對(duì)象不需要外部類(lèi)對(duì)象。2.不能再嵌套類(lèi)對(duì)象之中訪(fǎng)問(wèn)非靜態(tài)的外圍類(lèi)對(duì)象。普通內(nèi)部類(lèi)的成員和方法只能放在類(lèi)的外部層次上(這句話(huà)我沒(méi)搞懂= =),所以普通內(nèi)部類(lèi)不能有static的成員和方法。但是嵌套類(lèi)可以有。

public class Outer {
    static class Inner{
        static int i=5;
    }
    public static void main(String[] args) {
        Inner i=new Outer.Inner();
    }
}

可以從上面的例子看到,在創(chuàng)建這個(gè)嵌套類(lèi)對(duì)象的時(shí)候,并沒(méi)有像最開(kāi)始那樣,用一個(gè)外部類(lèi)對(duì)象來(lái)創(chuàng)建這個(gè)內(nèi)部類(lèi)對(duì)象。其實(shí)這和靜態(tài)方法差不多。

可以在接口內(nèi)部定義內(nèi)部類(lèi),而且他們即使沒(méi)有static修飾,也會(huì)自動(dòng)變成public static的。

public interface ClassInInterface {
    void howdy();
    class Test implements ClassInInterface{
        public void howdy(){
            System.out.println("howdy!");
        }
        public static void main(String[] args) {
            new Test().howdy();
        }
    }
}

書(shū)上有句話(huà)說(shuō)的很好,在開(kāi)發(fā)的時(shí)候建議在每個(gè)類(lèi)中都寫(xiě)一個(gè)main方法測(cè)試,但是這又必須帶著那些已經(jīng)編譯過(guò)的額外代碼,所以我們可以用嵌套類(lèi)放置測(cè)試代碼。

public class Outer {
    public void f(){
        System.out.println("I need to be tested");
    }

    public static class Tester{
        public static void main(String[] args) {
            Outer o=new Outer();
            o.f();
        }
    }
}

當(dāng)然以上兩段代碼如果是在eclipse上運(yùn)行的話(huà),需要設(shè)置一下運(yùn)行的main函數(shù)在哪,否則會(huì)報(bào)錯(cuò)

五、多層內(nèi)部類(lèi)嵌套

紙老虎,愛(ài)有幾層有幾層,反正只要是外部類(lèi)的東西,不管哪層外部類(lèi),都能訪(fǎng)問(wèn)到。

public class Outer {
    void f(){
        System.out.println("hello");
    }
    class Inner1{
        void g(){
            System.out.println("java");
        }
        class Inner2{
            void h(){
                f();
                g();
            }
        }
    }
    public static void main(String[] args) {
        Outer.Inner1.Inner2 in2=new Outer().new Inner1().new Inner2();
        in2.h();
    }
}

下面是個(gè)好玩的

public class Outer {
    void f(){
        System.out.println("hello");
    }
    class Inner1{
        void f(){
            System.out.println("java");
        }
        class Inner2{
            void h(){
                f();
            }
        }
    }
    public static void main(String[] args) {
        Outer.Inner1.Inner2 in2=new Outer().new Inner1().new Inner2();
        in2.h();
    }
}

最后打印結(jié)果是java。

大概就這么多吧,以后如果還有新東西再補(bǔ)。

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/67513.html

相關(guān)文章

  • Thinking in Java13 字符串

    摘要:四上的操作看五格式化輸出運(yùn)用和語(yǔ)言很相似和是等價(jià)的喲類(lèi)格式化說(shuō)明符轉(zhuǎn)換六正則表達(dá)式網(wǎng)上教程學(xué)七掃描輸入新增了類(lèi)。 一、不可變String String類(lèi)型的對(duì)象是不可變的,所有的改變實(shí)際上都是創(chuàng)建了一個(gè)新的String對(duì)象,另外當(dāng)String作為傳入?yún)?shù)的時(shí)候,其實(shí)實(shí)際上傳入的是這個(gè)引用的一個(gè)拷貝,這個(gè)方法結(jié)束了之后這個(gè)傳入的引用也就消失了,原來(lái)的那個(gè)String不會(huì)受到方法內(nèi)的影響而...

    feng409 評(píng)論0 收藏0
  • Thinking in Java9 接口

    摘要:但如果導(dǎo)出類(lèi)還有抽象方法,那這個(gè)類(lèi)還應(yīng)該加上聲明為抽象類(lèi)。并且接口具有繼承的一系列特點(diǎn),如向上轉(zhuǎn)型等等。接口中的方法是自動(dòng)是的。 Thinking in Java 好書(shū)全是干貨 一、抽象類(lèi)和抽象方法 抽象方法:這種方法只有聲明而沒(méi)有方法體,下面是抽象方法生命所采用的語(yǔ)法 abstract void f(); 包含抽象方法的類(lèi)叫做抽象類(lèi),如果一個(gè)類(lèi)包含一個(gè)或多個(gè)抽象方法,該類(lèi)必須被限定為...

    CoorChice 評(píng)論0 收藏0
  • Thinking in Java14 類(lèi)型信息

    摘要:通過(guò)運(yùn)行時(shí)類(lèi)型信息,程序能夠使用基類(lèi)的指針或引用來(lái)檢查這些指針或引用所指的對(duì)象的實(shí)際派生類(lèi)型。編程應(yīng)該盡量面向接口編程,應(yīng)該對(duì)類(lèi)型信息盡量的少了解二對(duì)象看書(shū),書(shū)上寫(xiě)得好靜態(tài)語(yǔ)句塊在這個(gè)類(lèi)被加載的時(shí)候運(yùn)行。 一、為什么需要RTTI Run-Time Type Information。通過(guò)運(yùn)行時(shí)類(lèi)型信息,程序能夠使用基類(lèi)的指針或引用來(lái)檢查這些指針或引用所指的對(duì)象的實(shí)際派生類(lèi)型。編程應(yīng)該盡量...

    tomorrowwu 評(píng)論0 收藏0
  • Thinking in Java12 通過(guò)異常處理錯(cuò)誤

    摘要:異常處理程序拋出的異常必須在異常處理程序中得到處理。終止與恢復(fù)異常處理有兩種模型,支持終止模型,一旦異常被拋出,表明錯(cuò)誤無(wú)法挽回,無(wú)法退回來(lái)繼續(xù)執(zhí)行之前出錯(cuò)的代碼。對(duì)于異常來(lái)說(shuō),最重要的部分就是類(lèi)名。 一、概念 使用異常能降低處理錯(cuò)誤代碼的復(fù)雜程度,并且將錯(cuò)誤在一個(gè)地方進(jìn)行處理,于是將描述在正常行為過(guò)程中做過(guò)什么事的代碼和出了問(wèn)題怎么辦的代碼相分離 二、基本異常 異常情形指的是當(dāng)前環(huán)境...

    miguel.jiang 評(píng)論0 收藏0
  • Thinking in Java11 持有對(duì)象

    摘要:迭代器解決了這個(gè)問(wèn)題。刪除后于是我們可以寫(xiě)一個(gè)方法,接受一個(gè)類(lèi)型,然后讓他調(diào)用方法,這就不需要考慮這個(gè)是個(gè)還是了,也就是說(shuō),可以將遍歷容器的操作與序列底層的結(jié)構(gòu)分離,迭代器統(tǒng)一了對(duì)容器類(lèi)的訪(fǎng)問(wèn)方式。十二和兩種遍歷的方法,與迭代器方法。 一、泛型和類(lèi)型安全的容器 package tij.hoding; import java.util.ArrayList; public class ...

    v1 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

最新活動(dòng)
閱讀需要支付1元查看
<