第一天
1. Java命名規範:關鍵字、變量、對象、方法、包等名字通常全部字母小寫,如果是多個單詞構成的話就首字母小寫,後面單詞首字母大寫,比如String類中的toString;類名首字母大寫;常量名全部大寫。
2. 基本數據類型:
**1)數據類型分類:**Java分爲基本類型和引用類型 。其中,基本類型有byte、short、int、long、float、double、char、boolean,它們的變量作爲參數傳遞時只是複製了一份,所以不會改變,比如int a=4;傳到addOne(int a)這個方法執行後a的值還是4。引用類型有數組、類和接口,當它們的變量當做值傳遞的時候就會改變,就像C語言裏面傳遞指針那樣。
2)基本數據類型的取值範圍以及字節數:
我覺得這個寫得很好:Java 基本數據類型取值範圍講解
注意一個:boolean的默認值是false。
3)數組:
- 數組的聲明:
int a[];//可以這樣
int[] a;//也可以這樣
但是要注意一下,int a[],i;和int[] a,i;是不一樣的:a都是數組沒問題,但是第一種那裏的i是整型,而第二種那裏的是數組!!!
- 用於數組的逐元循環的for語句:
- 比如:
int fib[]=new int[n];
for(int value:fib)//這個就是了
System.out.println(value);
這裏的value就會依次獲得數組的值。要注意value的類型要和數組的類型一樣。
數組的引用模型:
數組是一個引用類型,所以它傳值給方法之後,方法體裏面是可以改變數組的元素的。來一個對比看看。int a=1,b;先讓b=a;這個之後b=a=1了,然後再調用方法addOne(b);之後,b=1+1=2;但是a還是爲1;再看看數組的:int a[]={1,2,3,4,5},b[];讓b=a(這就是引用賦值了);再b[0]=999;這時候a[0]也變成了999了。就像C++裏面的指針一樣,a,b都指向了同一個數組.
- 二維數組:
int array[][]=new int[5][6];
System.out.println(array.length);//輸出5,即二維數組的行數
System.out.println(array[0].length);//輸出6,即二位數組的列數
//不規則的二維數組
int arr[][]=new int[3][];//申請了第一維的空間
arr[0]=new int[3];//這裏二維數組的第一行就有3個int空間了
arr[1]=new int[6];//這裏二維數組的第二行就有6個int空間了
4) 參數的傳遞:
- 基本數據類型—》傳值
- 引用數據類型—》傳引用
- 常量形參:
public static void functionA(final int n){
//聲明n爲常量,方法體裏不能賦值
n=10;//這樣是錯的,不能對常量賦值
}
public static void functionB(final int arr[]){
//聲明數組爲常量,在方法體裏面不能更改引用
arr[0]=10;//可以,更改的是數組元素
arr = new int[4];//不行,不能對常量賦值,即不能改變數組的引用
}
- 可變形參:向一個方法傳遞可變數目的元素,除了數組參數,還可以通過可變形參實現。在形參類型後面加”…”就表示改形參數目可變(也就是把它當做一個數組)。但是可變形參只能用在最後一個形參位置,並且一個方法最多只能有一個可變形參。比如:
public static void print(int... value);//可變形式參數,可將value視爲int[]類型
【注意】在方法重載中,重載方法之間必須以參數列表相區別,不能以返回值相區別!!!因爲在編譯時,編譯器是根據方法實際參數的數據類型、個數和次序來確定執行重載方法的哪一個。
第二天
- 對象引用模型:首先看看一個測試代碼
public class Test {
public static void main(String[] args) {
// TODO Auto-generated method stub
Year y1 = new Year(2020, 1, 1);
y1.print();//輸出是
Year y2 = y1;
y2.print();
y2 = new Year();
y2.print();
y2.set(y1);
y2.print();
}
}
class Year {
private int year;
private int month;
private int day;
public Year(int year, int month, int day) {
super();
this.year = year;
this.month = month;
this.day = day;
}
public Year() {
this.year = 2017;
this.month = 1;
this.day = 1;
}
public void set(Year y) {
this.year = y.year;
this.month = y.month;
this.day = y.day;
}
//也可以是拷貝構造函數,效果同上
// public Year(Year y){
// this.year = y.year;
// this.month = y.month;
// this.day = y.day;
// }
public void print() {
System.out.println(year + " " + month + " " + day);
}
}
總結一下:如果兩個對象之間是賦值,如上代碼中的y2=y1,這時候y2是不會開闢空間的,y1和y2指向同一個對象,但是用了new後就會給它開闢空間,y2=new Year();y2就有了自己的地盤了。這就像是C++裏面的一樣,只要有新對象產生就會有空間的開闢。記住,有new就開闢。
**【拓展一下】**return this.year+’-‘+this.month+’-‘+this.day;和
return return this.year+”-“+this.month+”-“+this.day;的區別:前一個返回值是int後一個是String,不信可以試試。
2.對象關係和比較運算(都是boolean):
instanceof運算符是判斷一個對象所引用的實例是不是屬於某個類。比如上面的代碼,y1就屬於Year,所以 y1 instanceof Year;就是true咯。
基本數據類型的比較:比如int,float,double等等,都是隻比較兩個變量的值是不是相等。
- 對象比較:這個又有兩種比較了。第一種就是形如 y1==y2;第二種就是y1.equals(y2)。讓我們回到上面的圖一看看,如果是情況一這樣,那麼兩種方法都是true了,但是情況二中兩個都是false。可以加上這兩行代碼測測。
System.out.println(y1==y2);
System.out.println(y1.equals(y2));
3.靜態成員:
靜態成員屬於類,即使沒有創建實例,也可以通過類名訪問靜態成員變量/方法。在靜態成員方法體中,不能訪問實例成員,不能使用this引用!!!!!!!!
同名的實例方法被覆蓋,同名的靜態方法被隱藏。它們的區別在於:子類對象轉換成父類對象後能夠訪問父類被隱藏的變量和方法,而不能訪問父類被覆蓋的變量和方法。子類如要訪問父類中被隱藏的實例變量,則需要使用super關鍵字;如果要訪問父類中被隱藏的類變量,則需要用父類的名字加“.”來訪問。
還是看個例子好:
//file name:Parent.java
public class Parent {
protected static String kind = "This is Parent class";// 這是類變量
protected static int age = 50;// 這是類變量
protected String name = "Parent"; // 這是實例變量
/**
* 靜態方法
*
* @return 返回Parent的kind
*/
public static String getKind() {
System.out.print("Parent.getKind():");
// return this.kind;//錯誤
return kind;
}
/**
* 靜態方法
*
* @return 返回Parent的age
*/
public static int getAge() {
System.out.print("Parent.getAge():");
return age;// 如果是this.age,錯誤
}
/**
* 實例方法
*
* @return Parent的name
*/
public String getName() {
return this.name;
}
/**
* final方法
*
* @return age+1
*/
public final int nextAge() {
return ++age;
}
}
//file name:Child.java
public class Child extends Parent {
protected static String kind = "This is CHild class";
protected int age = 25;// 實例變量,這個和Parent中不同
protected String name = "Child";
/**
* 靜態方法,隱藏了Parent中的方法
*
* @return child中的kind
*/
public static String getKind() {
System.out.print("Child.getKind():");
return kind;
}
/**
* 靜態方法
*
* @return 父類的名字
*/
public static String getParentKind() {
// 通過父類名加.訪問
return Parent.kind;
}
/**
* 實例方法
*
* @return Child的name
*/
public String getName() {
return this.name;
}
/**
* 實例方法
*
* @return Parent中的name
*/
public String getParentName() {
return super.name;
}
// //這樣是錯的,因爲實例方法不能覆蓋父類的靜態方法
// public int getAge(){
// return this.age;
// }
// 這樣也是不行的,父類中的final方法不能夠被覆蓋
// public int nextAge(){
// return ++age;
// }
public static void main(String[] args) {
// TODO Auto-generated method stub
Child child = new Child();
System.out.println("child name:" + child.name + ";age:" + child.age + ";kind:" + child.kind);
Parent parent = child;// 將child類型轉換成Parent對象
System.out.println("After name:" + parent.name + ";age:" + parent.age + ";kind:" + parent.kind);
System.out.println();
System.out.println("child.getParentName():" + child.getParentName());
System.out.println("child.getParentKind():" + child.getParentKind());
System.out.println();
child.getName();
child.getKind();
parent.getName();
parent.getKind();
}
}
第三天
- 抽象類:
- 使用關鍵字abstract聲明的類稱爲抽象類,使用abstract聲明的成員方發稱爲抽象方法。
- 構造方法、靜態成員方法不能被聲明爲抽象方法。
- 抽象類中可以有非抽象方法,但是有抽象方法的類一定要聲明爲抽象類。
- 抽象方法中也有構造方法,而且如果有某個類繼承了該抽象方法,需要給該抽象類提供參數以初始化。
- 最終類:
- 使用關鍵字final聲明的類就是最終類。
- 最終類不能被繼承,即不能有子類。
- 最終類中包含的都是最終方法;非最終類也可以有最終方法。
- 最終方法不能被子類覆蓋。
- 接口:
- 接口是一種(引用)數據類型。
- 接口中的成員變量都是常量(變量名全部大寫),聲明時必須賦值,默認修飾符爲public static final,不能聲明實例成員變量。
- 接口中的成員方法都是抽象的實例成員方法,默認修飾符爲public abstract,不能聲明爲static。(特別注意,如果某個類實現某個接口,必須加上public,如圖)
- 接口不能包含構造方法,因爲構造方法不能是抽象的。
- 接口的訪問控制權限是public或缺省。
- 接口可以多重繼承。
- 一個類可以實現多個接口,多個接口之間用逗號分隔。
- 一個非抽象類如果聲明實現多個接口,那麼它必須實現(覆蓋)所有指定接口中的所有抽象方法,方法的參數列表必須相同,否則它必須聲明爲抽象類。