Java基礎10---包、內部類、匿名內部類

冬有雪發表於2016-06-11

一、package關鍵字

      包的作用是將位元組碼(.class)進行分類存放 ,包其實就是資料夾。

1.注意事項

  • package語句必須是程式的第一條可執行的程式碼
  • package語句在一個java檔案中只能有一個
  • 如果沒有package,預設表示無包名

2.帶包類的編譯執行

javac編譯的時候帶上-d即可

javac -d . HelloWorld.java

通過java命令執行。

java 包名.HellWord

package cn.ds93;
import xyz.junshuai.*;
public class Programer {
    public static void main(String[] args) {
        Translator t = new Translator("HouHou","nv");
        System.out.println(t.getName() + " is " + t.getSex());
    }
}
package xyz.junshuai;
public class Translator {
    private String name;
    private String sex;

    public Translator(){ }
    public Translator(String name,String sex) {
        this.name = name;
        this.sex = sex;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getName() {
        return name;
    }

    public void setSex(String sex) {
        this.sex = sex;
    }

    public String getSex() {
        return sex;
    }
}

二、四種許可權修飾符

許可權修飾符 本類 同一個包下(子類和無關類) 不同包下(子類) 不同包下(無關類)
private Y
預設 Y Y
protected Y Y Y
public Y Y Y Y

1.類及其組成所使用的常見修飾符

  • 許可權修飾符:private,預設的,protected,public
  • 狀態修飾符:static,final
  • 抽象修飾符:abstract

2.關於類的修飾符

  • 許可權修飾符:預設修飾符,public
  • 狀態修飾符:final
  • 抽象修飾符:abstract
  • 用的最多的就是:public

3.關於成員變數的修飾符

  • 許可權修飾符:private,預設的,protected,public
  • 狀態修飾符:static,final
  • 用的最多的就是:private

4.關於構造方法的修飾符

  • 許可權修飾符:private,預設的,protected,public

  • 用的最多的就是:public

5.關於成員方法的修飾符

  • 許可權修飾符:private,預設的,protected,public
  • 狀態修飾符:static,final
  • 抽象修飾符:abstract

  • 用的最多的就是:public

6.除此以外的組合規則

  • 成員變數:public static final
  • 成員方法:
    • public static
    • public abstract
    • public final

三、內部類

1.內部類訪問特點

  • 內部類可以直接訪問外部類的成員,包括私有。
  • 外部類要訪問內部類的成員,必須建立物件。
  • 外部類名.內部類名 物件名 = 外部類物件.內部類物件;

2.靜態成員內部類

  • 用static修飾
  • 成員內部類被靜態修飾後的訪問方式是:
    • 外部類名.內部類名 物件名 = 外部類名.內部類物件;

來個面試題:

class InnerClass {
    public static void main(String[] args) {
        Outer.Inner oi = new Outer().new Inner();
        oi.print();
    }
}

class Outer {
    public int dong = 100;
    class Inner {
        public int shuai = 200;

        public void print() {
            int hou = 300;
            System.out.print(hou + "\n");
            System.out.print(this.shuai + "\n");
            System.out.print(Outer.this.dong + "\n");
        }
    }
}

3.區域性內部類訪問區域性變數的問題

  • 區域性內部類訪問區域性變數必須用final修飾
  • 區域性內部類在訪問他所在方法中的區域性變數必須用final修飾,為什麼?
          因為當呼叫這個方法時,區域性變數如果沒有用final修飾,他的生命週期和方法的生命週期是一樣的,當方法彈棧,這個區域性變數也會消失,那麼如果區域性內部類物件還沒有馬上消失想用這個區域性變數,就沒有了,如果用final修飾會在類載入的時候進入常量池,即使方法彈棧,常量池的常量還在,也可以繼續使用。但是jdk1.8取消了這個事情,老師認為這是個bug。

四、匿名內部類

1.匿名內部類就是內部類的簡化寫法。

2.前提:存在一個類或者介面

  • 這裡的類可以是具體類也可以是抽象類。

3.格式

new 類名或者介面名(){
            重寫方法;
        }

4.本質

      是一個繼承了該類或者實現了該介面的子類匿名物件。

舉個例子(面試題,補齊Outer類中的程式碼):

interface HouHou {
    public void english();
}

class Outer {
    class Inner implements HouHou {
        public void english() {
//          System.out.println();
        }
    }

    public void print() {
        new Inner() {
            public void english() {
                System.out.println("Shanghai Haishi University");
            }
        }.english();
    }
}

public class AnonymousInnerClass {
    public static void main(String[] args) {
        new Outer().print();
    }
}

5.匿名內部類,只在重寫一個方法時用

interface Inter {
    public void dong();
    public void shuai();
}

class Outer {
    public void hou() {
        new Inter() {   //匿名內部類,只在重寫一個方法時用
            public void dong(){
                System.out.println("lijun");
            }
            public void shuai(){
                System.out.println("lijun2");
            }
        }.dong();

        new Inter() {
            public void dong(){
                System.out.println("lijun");
            }
            public void shuai(){
                System.out.println("lijun2");
            }
        }.shuai();
    }
}

public class AnonymousInner {
    public static void main(String[] args) {
        new Outer().hou();
    }
}

6.匿名內部類在開發中的應用

//匿名內部類在開發中的應用
//本例為有名類,作為對比
public class AnonymousInner2 {
    public static void main(String[] args) {
        Caomin c = new Caomin();
        c.bitter(new Employee());
    }
}

abstract interface Employer {
    public abstract void exploit();
}

class Employee implements Employer {
    public void exploit() {
        System.out.println("哪裡有壓迫,哪裡就有反抗。");
    }
}
class Caomin {
    public void bitter(Employee e) {
        e.exploit();
    }
}
//匿名內部類在開發中的應用
//本例為匿名內部類
public class  AnonyInnerDevelop {
    public static void main(String[] args) {
        Caomin c = new Caomin();
        c.bitter(new Employee() {   //匿名內部類,編譯看左邊,執行看右邊
            public void exploit() {
                System.out.println("哪裡有壓迫,哪裡就有反抗。");
            }
        });
    }
}

abstract interface Employer {
    public abstract void exploit();
}

class Employee implements Employer {
    public void exploit() {
        //System.out.println("哪裡有壓迫,哪裡就有反抗。");
    }
}

class Caomin {
    public void bitter(Employee e) {
        e.exploit();
    }
}

再來一個面試題

//匿名內部類的面試題
public class AnonyInnerInterview {
    public static void main(String[] args) {
        Outer.dong().shuai();   //鏈式程式設計,每次呼叫方法後還能呼叫方法,第一次呼叫方法返回的是物件
    }
}

interface Inter {
    void shuai();
}

class Outer {
    public static Inter dong() {
        return new Inter() {    //返回實現的介面(子類物件)
            public void shuai() {
                System.out.print("匿名內部類");
            }
        };
    }
}

相關文章