Java與C/C++不同的一些基礎知識點

s1mba發表於2014-11-23
0. 類與檔案

一個 java 檔案可以寫多個類,每個類裡面可以有main函式,一個java檔案裡面只能有一個 public 類,此時 java 檔案的命名只能是public類名.java。使用 javac 編譯一個 java 檔案時,如果有多個類,會生成多個 類名.class 檔案,java 類名 執行程式(單元測試)。多個class 檔案可以打包成一個 jar 檔案,java -jar test.jar 執行前需要設定一下程式入口,即在MANIFEST.MF 裡面新增如下一句話:Main-Class: test.someClassName

1. 關鍵字

final
可以修飾類,方法和成員變數
final修飾的類不能被繼承
final修飾的方法不能被覆蓋
 final修飾的變數是常量,只能賦值一次

覆蓋注意事項:
1. 子類方法覆蓋父類方法時,子類方法的許可權要>=父類
2. 靜態方法只能覆蓋靜態方法
3. 如果父類方法新增final, 則子類重新定義此方法會編譯出錯
4.在子類方法中可以通過super.method 呼叫父類方法,當然如果父類方法是private,也是不能呼叫的(實際上是子類重新定義method,並沒
有覆蓋父類method,可以認為父類method被隱藏了)


static
     用於修飾成員(成員變數和成員函式),被修飾後的成員具備以下特點:
          隨著類的載入而載入,隨著類的消失而消失
          優先於物件而存在
          被所有物件所共享
          可以直接用類名呼叫如類名.成員
     用於修飾靜態程式碼塊: static {...}
          隨著類的載入而執行,而且只執行一次,可以用於給類進行初始化
          注:構造程式碼塊{...}隨著物件的構造而執行,而且建立幾次就執行幾次,可以用於給所有物件進行初始化
          靜態程式碼塊-->建構函式{super()-->成員初始化-->構造程式碼塊-->後續語句}
     使用注意:
          靜態方法只能訪問靜態成員
          靜態方法中不可以出現this, super等關鍵字
          主函式是靜態的

this & super
     this代表本類物件的引用
     super代表一個父類空間
     當本類的成員和區域性變數同名用this區分
     當子父類的成員變數同名用super區分父類

interface 

     當一個抽象類中的方法都是抽象的時候,這時可以將該抽象類用另一種形式定義和表示,就是介面interface. 
     對於介面中的常見成員都有固定的修飾符。
     全域性常量: public static final
     抽象方法: public abstract
     類與類之間是繼承extends關係;類與介面之間是實現implements關係;介面與介面之間是繼承關係,而且介面可以多繼承
     類可以在繼承一個類的同時實現多個介面
     抽象類的繼承,是is a關係,在定義該體系的基本共性內容,介面的實現是like a關係,在定義體系額外功能
     介面型別的引用,用於指向介面的子類物件

2.繼承:

在子類的建構函式中第一行有一個預設的隱式語句 super(); 子類中所有的建構函式預設都會訪問父類中的空引數的構造函
數。如果父類中沒有定義空引數建構函式,那麼子類的建構函式必須用super(...)明確要呼叫父類中哪個建構函式。同時子類建構函式中如果使用this呼叫了本類建構函式時,那麼super語句就沒有了,因為super和this都只能定義在第一行,所有隻能有一個。
但是可以保證的是,子類中肯定會有其他的建構函式訪問父類的建構函式。

3.多型:

成員變數:
     編譯時:參考引用型變數所屬的類中是否有呼叫的成員變數,如果沒有則編譯失敗
     執行時:參考引用型變數所屬的類中是否有呼叫的成員變數,並執行該所屬類中的成員變數

成員函式:
     編譯時:參考引用型別變數所屬的類中是否有呼叫的函式,如果沒有則編譯失敗
     執行時:參考的是物件所屬的類中是否有呼叫的函式

靜態函式:
      編譯時:參考引用型別變數所屬的類中是否有呼叫的靜態方法
      執行時:參考引用型別變數所屬的類中是否有呼叫的靜態方法
      其實對於靜態方法,是不需要物件的,直接用類名呼叫

4.內部類:

     內部類可以直接訪問外部類中的成員
      外部類要訪問內部類,必須建立內部類的物件
   
      // 直接訪問外部類中的內部類中的成員
       outer.inner in = new outer().new inner();
       in.show();

     // 如果內部類是靜態的,相當於一個外部類
      outer.inner in = new outer.inner();
       in.show(); 

     outer.inner.function();

     // 如果內部類中定義了靜態成員,該內部類必須也是靜態的

 Java Code 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17

class Outer
{
    int num = 3;
    class Inner
    {
        int num = 4;
        void show()
        {
            int num = 5;
            System.out.println(Outer.this.num);
        }
    }
    void method()
    {
        new Inner().show();
    }
}
     
 區域性內部類
  內部類可以放在區域性位置上
  內部類在區域性位置上只能訪問區域性中被final修飾的區域性變數

     
匿名內部類

     前提:內部類必須繼承或者實現一個外部類或者介面。

匿名內部類其實就是一個匿名子類物件。

格式:new 父類or介面(){子類內容}

 Java Code 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41


abstract class Demo
{
    abstract void show();
}

class Outer
{
    int num = 4;
    /*
    class Inner extends Demo
    {
        void show()
        {
            System.out.println("show ..."+num);
        }
    }
    */

    public void method()
    {
        //new Inner().show();
        /* Demo de = */ new Demo()//匿名內部類。
        {
            void show()
            {
                System.out.println("show ........" + num);
            }
        } .show();
        //      de.show();
    }
}


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


注意:如下做法是錯誤的

 Java Code 
1
2
3
4
5
6
7
8
9

Object obj = new Object()
{
    public void show()
    {
        System.out.println("show run");
    }

};
obj.show();

因為匿名內部類這個子類物件被向上轉型為了Object型別,而Object類並沒有show()的實現

通常的使用場景之一:
當函式引數是介面型別時,而且介面中的方法不超過三個,可以用匿名內部類作為實際引數進行傳遞

 Java Code 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28


interface Inter
{
    void show1();
    void show2();
}

class InnerClassDemo5
{
    public static void main(String[] args)
    {
        System.out.println("Hello World!");

        show(new Inter()
        {
            public void show1() {}
            public void show2() {}
        });

    }

    public static void show(Inter in)
    {
        in.show1();
        in.show2();
    }
}

5.異常

函式內容如果丟擲需要檢測的異常,那麼函式必須要宣告異常,否則必須在函式內用try catch捕捉,否則編譯失敗
如果呼叫到了宣告異常的函式,要麼try catch 要麼throws, 否則編譯失敗
功能內容可以解決用catch,解決不了用throws告訴呼叫者,由呼叫者解決
一個功能如果丟擲了多個異常,那麼呼叫時必須有對應多個catch進行鍼對性的處理

自定義異常時,繼承Exception類(編譯時異常),或者RuntimeException類(執行時異常)

子類在覆蓋父類方法時,父類的方法如果丟擲了異常,那麼子類的方法只能丟擲父類的異常或者該異常的子類

如果父類丟擲多個異常,那麼子類只能丟擲父類異常的子集。如果父類方法沒有丟擲異常,那麼子類覆蓋時絕對不能拋


6.訪問許可權

包與包之間的類進行訪問,被訪問的包中的類必須是public的,被訪問的包中的類的方法也必須是public的。

               public         protected          default                 private
同一類中    ok              ok                    ok                       ok
同一包中    ok              ok                    ok           
子類中       ok              ok              
不同包中    ok

7.執行緒

建立執行緒的第一種方式:繼承Thread類。

建立執行緒的第二種方式:實現Runnable介面。

1, 定義類實現Runnable介面。
2, 覆蓋介面中的run方法,將執行緒的任務程式碼封裝到run方法中。
3, 通過Thread類建立執行緒物件,並將Runnable介面的子類物件作為Thread類的建構函式的引數進行傳遞。
為什麼?因為執行緒的任務都封裝在Runnable介面子類物件的run方法中。
所以要線上程物件建立時就必須明確要執行的任務。

4, 呼叫執行緒物件的start方法開啟執行緒。

實現Runnable介面的好處:
1, 將執行緒的任務從執行緒的子類中分離出來,進行了單獨的封裝。按照物件導向的思想將任務的封裝成物件。
2, 避免了java單繼承的侷限性。

所以,建立執行緒的第二種方式較為常用。

 Java Code 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48

class Thread
{
    private Runnable r;
    Thread()
    {

    }
    Thread(Runnable r)
    {
        this.r  = r;
    }

    public void run()
    {
        if(r != null)
            r.run();
    }

    public void start()
    {
        run();
    }
}
class ThreadImpl implements Runnable
{
    public void run()
    {
        System.out.println("runnable run");
    }
}
ThreadImpl i = new ThreadImpl();
Thread t = new Thread(i);
t.start();




class SubThread extends Thread
{
    public void run()
    {
        System.out.println("hahah");
    }
}
SubThread s = new SubThread();
s.start();





相關文章