基礎(chǔ)

Java程序基本結(jié)構(gòu)

/**
 * 可以用來(lái)自動(dòng)創(chuàng)建文檔的注釋
 */
public class Hello {
    public static void main(String[] args) {
        // 向屏幕輸出文本:
        System.out.println("Hello, world!");
        /* 多行注釋開(kāi)始
        注釋內(nèi)容
        注釋結(jié)束 */
    }
} // class定義結(jié)束
  • class關(guān)鍵字用來(lái)創(chuàng)建類,類名必須以英文字母開(kāi)頭,習(xí)慣大寫,大駝峰命名。
  • public 是訪問(wèn)修飾符,代表該class是公開(kāi)的
  • class內(nèi)部可以定義若干方法
  • main是方法名,void代表該方法沒(méi)有返回值,static是修飾符,表示該方法是靜態(tài)的,String[] args表示該方法的參數(shù)必須是String數(shù)組,args是入?yún)ⅲ椒ǖ拿?guī)范一般為小駝峰。
  • 在方法內(nèi)部才是真正執(zhí)行的代碼,java的每一行代碼必須以;結(jié)束。
  • System.out.println()是內(nèi)置的打印方法,結(jié)尾自帶換行,System.out.print()方法不換行顯示,\t可以添加若干空格。

數(shù)據(jù)類型和變量

  • java的變量定義方式為 類型 變量名 = 值
  • 在Java中,變量分為兩種:基本類型的變量和引用類型的變量。
  1. 基本數(shù)據(jù)類型
    基本數(shù)據(jù)類型是CPU可以直接進(jìn)行運(yùn)算的類型。Java定義了以下幾種基本數(shù)據(jù)類型:
  • 整數(shù)類型:byte,short,int,long
類型 占用儲(chǔ)存空間 表數(shù)范圍
byte 1 字節(jié)=8bit 位 -128~127
short 2 字節(jié) -32768 ~ 32767
int 4 字節(jié) -2147483648 ~ 2147483647
long 8 字節(jié) -9223372036854775808 ~ 9223372036854775807

Java程序中變量通常聲明為int型,除非不足以表示較大的數(shù),才使用long
long n2 = 900L long型的結(jié)尾需要加L

  • 浮點(diǎn)數(shù)類型:float,double
類型 占用儲(chǔ)存空間 表數(shù)范圍
單精度 float 4字節(jié) -3.403E38~3.403E38
雙精度 double 8 字節(jié) -1.798E308~1.798E308

(1) float:單精度,尾數(shù)可以精確到7位有效數(shù)字。很多情況下,精度很難滿足需求。
(2) double:雙精度,精度是float的兩倍。通常采用此類型
(3) 對(duì)于float類型,需要加上f后綴。

  • 字符類型:char
  1. char 型數(shù)據(jù)用來(lái)表示通常意義上“字符”(一個(gè)字段=2字節(jié),相當(dāng)于16個(gè)bit)
  2. Java中的所有字符都使用Unicode編碼,故一個(gè)字符可以存儲(chǔ)一個(gè)字母,一個(gè)漢字,或其他書面語(yǔ)的一個(gè)字符
  3. 定義char變量,通常使用一對(duì) ' '(單引號(hào)),內(nèi)部只能寫一個(gè)字符
  4. 表達(dá)方式:(1)聲明一個(gè)字符;(2)轉(zhuǎn)義字符
  5. 直接使用Unicode值來(lái)表示字符型常量:"\uXXXX",其中,XXXX代表一個(gè)十六進(jìn)制整數(shù)。如:\u000a表示\n。
  6. 拓展(轉(zhuǎn)義字符):\b(退格符)、\n(換行符)、\r(回車符)、\t(制表符)、"(雙引號(hào))、'(單引號(hào))、\(反斜線)
  • 布爾類型:boolean
    布爾類型boolean只有truefalse兩個(gè)值

常量

定義變量的時(shí)候,如果加上final修飾符,這個(gè)變量就變成了常量:

final double PI = 3.14; // PI是一個(gè)常量
double r = 5.0;
double area = PI * r * r;
PI = 300; // compile error!
  • 常量在定義時(shí)進(jìn)行初始化后就不可再次賦值,再次賦值會(huì)導(dǎo)致編譯錯(cuò)誤。為了和變量區(qū)分開(kāi)來(lái),常量名通常全部大寫。

移位運(yùn)算

>><<表示又位移和左位移,位移指的是會(huì)把十進(jìn)制數(shù)轉(zhuǎn)換成2進(jìn)制數(shù)進(jìn)行1的位移操作

int n = 7;       // 00000000 00000000 00000000 00000111 = 7
int a = n << 1;  // 00000000 00000000 00000000 00001110 = 14
int b = n << 2;  // 00000000 00000000 00000000 00011100 = 28
int c = n << 28; // 01110000 00000000 00000000 00000000 = 1879048192
int d = n << 29; // 11100000 00000000 00000000 00000000 = -536870912

數(shù)組類型

  • 數(shù)組定義:類型[] 變量名 = new 類型[數(shù)量]
  • 數(shù)組所有元素初始化為默認(rèn)值,整型都是0,浮點(diǎn)型是0.0,布爾型是false;
  • 數(shù)組一旦創(chuàng)建后,大小就不可改變。

條件判斷

  • >,<,>=,<=,==都可以用來(lái)作為判斷
  • 浮點(diǎn)值不能直接用==來(lái)判斷,正確的方法是利用差值小于某個(gè)臨界值來(lái)判斷:
// 條件判斷
public class Main {
    public static void main(String[] args) {
        double x = 1 - 9.0 / 10;
        if (Math.abs(x - 0.1) < 0.00001) {
            System.out.println("x is 0.1");
        } else {
            System.out.println("x is NOT 0.1");
        }
    }
}
  • 判斷引用類型相等
    在Java中,判斷值類型的變量是否相等,可以使用==運(yùn)算符。但是,判斷引用類型的變量是否相等,==表示“引用是否相等”,或者說(shuō),是否指向同一個(gè)對(duì)象。例如,下面的兩個(gè)String類型,它們的內(nèi)容是相同的,但是,分別指向不同的對(duì)象,用==判斷,結(jié)果為false:
public class Main {
    public static void main(String[] args) {
        String s1 = "hello";
        String s2 = "HELLO".toLowerCase();
        System.out.println(s1);
        System.out.println(s2);
        if (s1 == s2) {
            System.out.println("s1 == s2");
        } else {
            System.out.println("s1 != s2");
        }
    }
}

要判斷引用類型的變量?jī)?nèi)容是否相等,必須使用equals()方法:

public class Main {
    public static void main(String[] args) {
        String s1 = "hello";
        String s2 = "HELLO".toLowerCase();
        System.out.println(s1);
        System.out.println(s2);
        if (s1.equals(s2)) {
            System.out.println("s1 equals s2");
        } else {
            System.out.println("s1 not equals s2");
        }
    }
}

注意:執(zhí)行語(yǔ)句s1.equals(s2)時(shí),如果變量s1為null,會(huì)報(bào)NullPointerException

  • public定義公共變量,
  • private 定義私有變量
  • this 始終指向當(dāng)前實(shí)例,如果沒(méi)有命名沖突可以省略
class Person {
    private String name;

    public String getName() {
        return name; // 相當(dāng)于this.name
    }
}
  • 可變參數(shù) 類型...,可變參數(shù)相當(dāng)于數(shù)組類型:
class Group {
    private String[] names;

    public void setNames(String... names) {
        this.names = names;
    }
}
Group g = new Group();
g.setNames("Xiao Ming", "Xiao Hong", "Xiao Jun"); // 傳入3個(gè)String
g.setNames("Xiao Ming", "Xiao Hong"); // 傳入2個(gè)String
g.setNames("Xiao Ming"); // 傳入1個(gè)String
g.setNames(); // 傳入0個(gè)String

可變參數(shù)改寫為String[]類型
但是,調(diào)用方需要自己先構(gòu)造String[],比較麻煩
另一個(gè)問(wèn)題是,調(diào)用方可以傳入null:
而可變參數(shù)可以保證無(wú)法傳入null,因?yàn)閭魅?個(gè)參數(shù)時(shí),接收到的實(shí)際值是一個(gè)空數(shù)組而不是null。

  • 實(shí)例在創(chuàng)建時(shí)通過(guò)new操作符會(huì)調(diào)用其對(duì)應(yīng)的構(gòu)造方法,構(gòu)造方法用于初始化實(shí)例;
    沒(méi)有定義構(gòu)造方法時(shí),編譯器會(huì)自動(dòng)創(chuàng)建一個(gè)默認(rèn)的無(wú)參數(shù)構(gòu)造方法;
    可以定義多個(gè)構(gòu)造方法,編譯器根據(jù)參數(shù)自動(dòng)判斷;
    可以在一個(gè)構(gòu)造方法內(nèi)部調(diào)用另一個(gè)構(gòu)造方法,便于代碼復(fù)用。
  • 方法重載,在一個(gè)類中,我們可以定義多個(gè)方法。如果有一系列方法,它們的功能都是類似的,只有參數(shù)有所不同,那么,可以把這一組方法名做成同名方法。這種方法名相同,但各自的參數(shù)不同,稱為方法重載(Overload)。
class Hello {
    public void hello() {
        System.out.println("Hello, world!");
    }

    public void hello(String name) {
        System.out.println("Hello, " + name + "!");
    }

    public void hello(String name, int age) {
        if (age < 18) {
            System.out.println("Hi, " + name + "!");
        } else {
            System.out.println("Hello, " + name + "!");
        }
    }
}

注意:方法重載的返回值類型通常都是相同的。

繼承

  • java使用extends關(guān)鍵字來(lái)實(shí)現(xiàn)繼承
  • 繼承是面向?qū)ο缶幊讨蟹浅?qiáng)大的一種機(jī)制,它首先可以復(fù)用代碼。當(dāng)我們讓Student從Person繼承時(shí),Student就獲得了Person的所有功能,我們只需要為Student編寫新增的功能。
class Person {
    private String name;
    private int age;

    public String getName() {...}
    public void setName(String name) {...}
    public int getAge() {...}
    public void setAge(int age) {...}
}

class Student extends Person {
    // 不要重復(fù)name和age字段/方法,
    // 只需要定義新增score字段/方法:
    private int score;

    public int getScore() { … }
    public void setScore(int score) { … }
}

注意:子類自動(dòng)獲得了父類的所有字段,嚴(yán)禁定義與父類重名的字段!

  • Java只允許一個(gè)class繼承自一個(gè)類,因此,一個(gè)類有且僅有一個(gè)父類。只有Object特殊,它沒(méi)有父類。
  • 在Java中,沒(méi)有明確寫extends的類,編譯器會(huì)自動(dòng)加上extends Object。所以,任何類,除了Object,都會(huì)繼承自某個(gè)類。

protected

  • 繼承有個(gè)特點(diǎn),就是子類無(wú)法訪問(wèn)父類的private字段或者private方法。例如,Student類就無(wú)法訪問(wèn)Person類的name和age字段:
class Person {
    private String name;
    private int age;
}

class Student extends Person {
    public String hello() {
        return "Hello, " + name; // 編譯錯(cuò)誤:無(wú)法訪問(wèn)name字段
    }
}

這使得繼承的作用被削弱了。為了讓子類可以訪問(wèn)父類的字段,我們需要把private改為protected。用protected修飾的字段可以被子類訪問(wèn):

class Person {
    protected String name;
    protected int age;
}

class Student extends Person {
    public String hello() {
        return "Hello, " + name; // OK!
    }
}

因此,protected關(guān)鍵字可以把字段和方法的訪問(wèn)權(quán)限控制在繼承樹(shù)內(nèi)部,一個(gè)protected字段和方法可以被其子類,以及子類的子類所訪問(wèn)

super

  • super關(guān)鍵字表示父類(超類)。子類引用父類的字段時(shí),可以用super.fieldName
  • 如果父類沒(méi)有默認(rèn)的構(gòu)造方法,子類就必須顯式調(diào)用super()并給出參數(shù)以便讓編譯器定位到父類的一個(gè)合適的構(gòu)造方法。
    這里還順帶引出了另一個(gè)問(wèn)題:即子類不會(huì)繼承任何父類的構(gòu)造方法。子類默認(rèn)的構(gòu)造方法是編譯器自動(dòng)生成的,不是繼承的。

阻止繼承

  • 正常情況下,只要某個(gè)class沒(méi)有final修飾符,那么任何類都可以從該class繼承。
    從Java 15開(kāi)始,允許使用sealed修飾class,并通過(guò)permits明確寫出能夠從該class繼承的子類名稱。
public sealed class Shape permits Rect, Circle, Triangle {
    ...
}

上述Shape類就是一個(gè)sealed類,它只允許指定的3個(gè)類繼承它

多態(tài)

  • 多態(tài)是指,針對(duì)某個(gè)類型的方法調(diào)用,其真正執(zhí)行的方法取決于運(yùn)行時(shí)期實(shí)際類型的方法。
  • 在繼承關(guān)系中,子類如果定義了一個(gè)與父類方法簽名完全相同的方法,被稱為覆寫(Override)。
  • 加上@Override可以讓編譯器幫助檢查是否進(jìn)行了正確的覆寫。希望進(jìn)行覆寫,但是不小心寫錯(cuò)了方法簽名,編譯器會(huì)報(bào)錯(cuò)。

抽象類

  • abstract 關(guān)鍵字可以定義抽象類和抽象方法
abstract class Person {
    public abstract void run();
}

抽象類是無(wú)法被實(shí)例化的,抽象方法也無(wú)法執(zhí)行

接口

  • interface 用來(lái)聲明接口
  • 接口是比抽象類還要抽象的純抽象接口,如果一個(gè)抽象類沒(méi)有字段全是抽象方法,就可以寫成接口
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容