【筆記】阿里雲大學Java物件導向開發課程筆記01-77課時

copywang_1992發表於2018-01-13

課時1 物件導向簡介

20180101

物件導向,模組化設計,具備可通用性,可重用

1. 封裝性:內部的操作對外部不可見

2. 繼承性:繼續發展,可以重用設計

3. 多型性:利用這個特性得到良好的設計,可控範圍內的狀態改變

 

OOA物件導向分析

OOD物件導向設計

OOP物件導向程式設計

 

核心所在--考慮記憶體分配問題

 

程式導向,函式式過程,解決問題

 

20180102

課時2 類和物件(基本定義)

類:引用資料型別,記憶體分配問題

描述的群體共性特徵(比如:人)

 

物件是一個具體的可以使用概念(比如具體的某個人)

 

類 ---> 物件

類的組成:方法(操作的行為),屬性(變數,描述物件的基本特點)

 

課時3 類和物件(定義)

class ThisIsAClass {

    屬性1;

    屬性2;

    方法1() {

        方法內容

    }

    方法2() {

        方法內容

    }

}

屬性可以無限定義,注意每一個方法中的程式碼不要太長,否則就要考慮重構;

宣告並例項化物件

類名稱 物件名稱 = new 類名稱();

分部進行

1. 宣告:類名稱 物件名稱 = null;

2. 例項化: 物件名稱 = new 類名稱();

引用資料型別,new用於開闢新的堆記憶體;

效能調優:記憶體問題

 

物件只有例項化之後才能使用:

呼叫類中的屬性 物件名稱.屬性;

呼叫類中的方法 物件名稱.方法名();

 

課時4 類和物件(物件記憶體分析)

引用型別

堆記憶體:儲存真正的資料,物件的屬性資訊

棧記憶體:儲存的堆記憶體的地址,也就是堆記憶體的操作權

如果在定義類的時候沒有給屬性宣告預設值,那麼屬性會採用型別的預設值,比如int是0,String是null

1個棧只能儲存1個地址

 

 

宣告並例項化物件方式:

 

分步方式:

如果只是宣告物件,而不例項化,編譯的時候不會報錯,執行的時候會報錯:NullPointerException

陣列,類,介面會出現此類報錯

 

課時5 類和物件(引用傳遞初次分析)

引用的本質是別名,別名存在棧記憶體中,1個堆記憶體可以被多個棧記憶體所指向(比如同一個人有多個外號,但是其實是指向同一個人)

記憶體分析(地址一樣)

垃圾記憶體:(沒有棧記憶體指向的堆記憶體空間,會被GC定期回收) GarbageCollection

 

課時6 private實現封裝處理

物件導向程式設計有三大特性:封裝、繼承、多型

物件不能直接  .  操作類的屬性

封裝可以使用private實現(有其他實現方式,不唯一),只允許本類訪問

方法一般不使用private

語法格式:

       private 屬性;

 

配置屬性使用setter方法(可以對變數做合理判斷),獲取屬性使用getter方法

publicclass Person {

       private String name;

      

       public void setName(String a) {

              name = a;

       }

       public void getName() {

              return name;

       }

}

 

publicstatic void main (String[] args) {

       Person per = new Person();

       per.setName("test");

       per.getName();'

}

 

規範:

類中的所有屬性定義都是用private封裝,如果需要被外部使用,就定義setter()和getter()方法

 

課時7 構造方法和匿名函式

例項化物件方式:

類名稱 物件名稱 =new 類名稱();

 

類名稱:任何物件都有其對應的類

物件名稱:物件的唯一標記

new:開闢新的堆記憶體空間

類名稱():構造方法

 

構造方法和類名稱一樣,無返回值,宣告一個類之後就會自動生成一個無引數無返回值的預設建構函式(編譯後)

new的時候才呼叫構造方法

類的組成,屬性+普通方法+構造方法

 

publicclass Person {

       private String name;

       public Person() { //預設的構造方法格式

       }

       public void setName(String a) {

              name = a;

       }

       public void getName() {

              return name;

       }

}

 

publicstatic void main (String[] args) {

       Person per = new Person();

       per.setName("test");

       per.getName();'

}

 

構造方法不能帶void修飾符,帶有void的命令不標準,

publicvoid Person()

publicPerson()

對於內中可以自動生成預設構造方法,前提是類中沒有定義同名的構造方法

構造方法可以把類中的屬性初始化(傳入引數的構造方法)

構造方法可以過載(不同引數型別,不同引數個數),注意定義結構,按照引數個數採用升序或者降序排列

定義類的步驟:

1. 寫屬性

2. 寫構造方法

3. 寫普通方法

 

匿名物件:

只有這樣定義: newPerson();

沒有棧空間,使用一次之後就成為垃圾記憶體

 

課時8 【第01個程式碼模型】綜合案例:簡單Java類

簡單java類的開發要求

1. 類的名稱有意義,可以明確的描述某一類事物

2. 類中所有的屬性使用private封裝,並提供setter()/getter()方法

3. 類中必須保留一個無引數的構造方法

4. 類中的所有方法不允許使用System.out方法,輸出要在呼叫處完成

5. 類中應該提供一個返回類完整資訊的方法,getInfo()

 

開發中最多是簡單java類

開發原則

 

課時9 陣列的定義和使用(基本概念)

一組相關型別的變數集合,可以按照統一的方式進行操作,是引用型別

陣列動態初始化(宣告之後,每個資料都為預設值,比如int為0)

1. 宣告並開闢空間

資料型別[] 陣列名稱 =new 資料型別[長度]

或者

資料型別 陣列名稱[] =new 資料型別[長度]

 

2. 分部進行(先宣告,再例項化)

資料型別[] 陣列名稱 =null

陣列名稱 =new 資料型別[長度]

 

操作方式:

陣列的訪問通過索引完成,索引從0開始,到陣列長度-1

比如int[]data = new int[3],索引為0,1,2

- 陣列初始化之後,每個資料都為預設值,比如int為0

- 是一個有序的集合操作,採用迴圈模式操作

- 陣列長度data.length

 

課時10 陣列的定義與使用(陣列引用傳遞)

int[]data = new int[3];

int[]temp = null;

temp= data;

//temp和 data指向同一塊堆記憶體

//data的棧記憶體存的是地址

 

課時11 陣列的定義與使用(陣列靜態初始化)

陣列定義的時候設定內容

語法:

1. 簡化格式

資料型別陣列名稱[] ={value,value,...,value};

 

2. 建議使用,完整格式,可以使用匿名陣列

資料型別 陣列名稱[]=new 資料型別[] {value,value,...,value};

intdata[] = new int[] {1,2,3,4,5,6};

 

缺陷:長度固定

 

課時12 陣列的定義與使用(二維陣列)

行列集合

陣列[行索引][列索引]

語法模式和一維一樣

intdata[][] = new int[][] { {1,2,3},{4,5},{6,7,8,9} };

遍歷陣列使用2重迴圈,外部行,內部列

for(int x=0; x < data.length; x++) {

       for (int y=0; y < data[x].length; y++){

              System.out.print(data[x][y]);

       }

}

//開發過程中出現二維陣列的概率不高

 

課時13 陣列的定義與使用(陣列與方法的操作)

方法接收陣列(引數為陣列)

publicstatic void printArray(int temp[]) {

       //

}

 

方法返回陣列

publicstatic int[] init() {

       return new int[] {1,2,3,4,5};

}

 

傳入陣列,返回陣列

publicstatic void inc(int arr[]) {

       for (int x = 0; x < arr.length; x++) {

              arr[x] *= 2;

       }

}

 

課時14 陣列的定義與使用(Java對陣列的支援)

1. 陣列排序(基本資料型別陣列),升序

java.util.Arrays.sort(陣列名稱);

2. 陣列拷貝(一個陣列的部分內容替換另外一個陣列的部分內容),連續替換

System.arraycopy(原陣列名稱,原陣列起點,目標陣列名稱,目標陣列起點);

 

//邏輯訓練,開發用不上

 

課時15 陣列的定義與使用(陣列案例:陣列資料統計)

陣列的線性操作

最大,最小,平均,總和

迴圈操作模式完成

方法優化

 

課時16 陣列的定義與使用(陣列案例:陣列排序)

1. 基礎排序操作:

氣泡排序:

publicclass ArrayDemo {

     public static void main(String[] args){

         int score[] = {67, 69, 75, 87, 89, 90,99, 100};

         for (int i = 0; i < score.length-1; i++){    //最多做n-1趟排序

             for(int j = 0 ;j < score.length- i - 1; j++){    //對當前無序區間score[0......length-i-1]進行排序(j的範圍很關鍵,這個範圍是在逐步縮小的)

                 if(score[j] < score[j +1]){    //把小的值交換到後面

                     int temp = score[j];

                     score[j] = score[j + 1];

                     score[j + 1] = temp;

                 }

             }           

             System.out.print("第"+ (i + 1) + "次排序結果:");

             for(int a = 0; a <score.length; a++){

                 System.out.print(score[a] +"\t");

             }

             System.out.println("");

         }

             System.out.print("最終排序結果:");

             for(int a = 0; a <score.length; a++){

                 System.out.print(score[a] +"\t");

        }

     }

 }

 

 

課時17 陣列的定義與使用(陣列轉置)

首尾交換

1. 新定義一個空陣列,然後把原陣列的值從後到前存入新的陣列

問題:開闢了兩塊相同的堆記憶體空間,造成浪費

2. 在原陣列上反轉

計算陣列長度/2,交換次數為n,n =(array.length -1)/2

0 和length-1交換

1 和length-2交換

2 和length-3交換

n 和length-n-1交換

 

課時18 陣列的定義與使用(二分查詢法)

指定的陣列中查詢某個元素的位置

前提:陣列先排序

mid =head/2 + tail/2

原理

比如一個排序好的陣列

0,1,2,3,4,5,6,7,8

 

查詢7

第一次查詢

from:0

to:8

mid:4

索引為4的數比7小,所以賦值(第二次查詢)

from:4+1

to:8

mid:(5+8)/2= 6

索引為6的數比7小,所以賦值(第三次查詢)

from:6+1

to:8

mid:(7+8)/2= 7

索引為7的數為7,返回索引7

 

查詢2

第一次查詢

from:0

to:8

mid:4

索引為4的數比2大,所以賦值(第二次查詢)

from:0

to:4-1

mid:(0+3)/2= 1

索引為1的數比2小,所以賦值(第三次查詢)

from:1+1

to:3

mid:(2+3)/2= 2

索引為2的數為2,返回索引2

 

遞迴的結束條件是當from>= to

 

課時19 陣列的定義與使用(物件陣列)

核心掌握

引用資料型別為主,類或者介面

物件陣列動態初始化: 類名稱[] 物件陣列名 =new 類名稱[長度]

物件陣列的靜態初始化:類名稱[] 物件陣列名 =new 類名稱[] {物件名,...}

classPerson {

       private String name;

       private int age;

       public Person(String setName,int setAge){

              name = setName;

              age = setAge;

       }

       public String getInfo() {

              return "name is " + name+ " age is " + age;

       }

}

 

publicclass ArrayDemo {

       public static void main(String[] args) {

              Person[] per = new Person[3]; //動態初始化,預設值為null

              per[0] = newPerson("A",1);

              per[1] = newPerson("B",2);

              per[2] = newPerson("C",3);

              for (int x = 0; x < per.length;x++) {

                     System.out.println(per[x].getInfo());

              }

              Person[] per2 = new Person[] { newPerson("D",4) }; //靜態初始化

              System.out.println(per2[0].getInfo());

       }

}

 

物件儲存的是堆記憶體的地址

 

普通資料陣列堆記憶體直接儲存資料,比如newint[]

而物件陣列堆記憶體表示各個物件的真是資料地址(裡面沒有資料),如上圖

 

課時20 String類的基本特點(String類兩種例項化方式)

所有開發過程中都存在String類

 

第一種

String str ="hello";

str是一個物件,hello是儲存在堆記憶體中

 

第二種

Stringstr = new String("hello");

傳入"hello"的名為String的建構函式

 

課時21 String類的基本特點(字串比較)

 

== 和 equals的區別

 

==比較的是堆記憶體的地址,是數值比較

equals()比較的是字串內容,區分大小小

 

String str1 ="hello"; //把一個匿名物件值為"hello"的物件命名為str1

String str2 = newString("hello");

 

str1 == str2 結果為false

str1.equals(str2) 結果為true

 

開發過程中必須使用equals()

 

課時22 String類的基本特點(字串常量為匿名物件)

 

String str1 ="hello"; //把一個匿名物件值為"hello"的物件命名為str1

 

開發過程中,如果要判斷使用者輸入的字串是否等同於指定的字串,一定要把字串寫在前面,考慮使用者沒有輸入資料的問題

 

操作方法1:字串寫在前面,不會報空指向異常

 

課時23 String類的基本特點(String兩種例項化區別)

 

第一種 直接賦值(開發推薦做法,節省記憶體)

String str ="hello";

str是一個物件,hello是儲存在堆記憶體中

多次賦值(指向的是同一個堆記憶體),使用了共享設計模式

JVM維護物件池, 直接賦值的時候,第一次會儲存到物件池,後續如果有一樣的物件,就引用一樣的物件

也就是一個物件陣列,可以減少同樣字串的記憶體開銷

 

 

 

第二種,構造方法(標準做法)

(從右往左執行)

 

Stringstr = new String("hello");

傳入"hello"的名為String的建構函式

會開闢2個堆記憶體空間,其中一個成為垃圾空間

而且這個物件沒有自動儲存到物件池

 

實現入池的操作

publicString intern();

 

 

課時24 String類的基本特點(字串常量不可變更)

 

字串物件變更:

 

 

字串內容本身是不會變化的,變化的是字串物件的引用

 

開發原則:

字串採用直接賦值模式完成

比較實用equals()方法實現

字串不要頻繁改變

 

課時25 String類的常用方法(DOC文件組成)

 

 

文件組成:

1. 類的相關定義,類的名字,父類,介面等

2. 類的簡介

3. 成員(field)摘要,屬性就是一種成員,

4. 構造(constructor)方法說明,Deprecated建議不用

5. 方法(methods)摘要,返回值,引數說明

 

 

課時26 String類的常用方法(字串與字元陣列)

 

字元陣列 變成 字串

 

public String(char[] value)//構造方法

public String(char[] value,int offset, int count) // offset開始,count個數,構造方法

public char charAt(int index)//返回字串索引位置的字元,索引從0開始 開發中出現的機率很低,普通方法

 

 

字串 變成 字元陣列

publicchar[] toCharArray() //普通方法

 

重點:字串和字元陣列的互相轉換

publicclass StringDemo {

       public static void main(String[] args) {

              String str = "helloworld";

              System.out.println("index 2" + str.charAt(2));

              char[] data = str.toCharArray();

              for (char x : data) {

                     x -= 32; //轉換成大寫

                     System.out.print(x +"/");

              }

              System.out.println(newString(data));

              System.out.println(newString(data,6,5));

       }

}

 

課時27 String類的常用方法(位元組與字串)

位元組:資料傳輸或者編碼轉換

 

支援:

構造方法:

public String(byte[] byte)

public String(byte[] byte,int offset, int length)

 

普通方法:

public byte[] getBytes()

public byte[] getBytes(StringcharsetName) throws UnsupportedEncodingException //編碼轉換

 

public class StringDemo {

      public static void main(String[] args) {

             String str = "hello world";

             byte data[] = str.getBytes();

             for (byte x : data) {

                    System.out.print(x + ",");

             }

      }

}

 

位元組 -128 到 127 無法表示中文

字元才用於表示中文

 

課時28 String類的常用方法(字串比較)

equals()方法

區分大小寫

public boolean equals(StringanotherString)

不區分

public booleanequalsIgnoreCase(String anotherString)

 

 

public int compareTo(StringanotherString) //比較兩個字串的大小關係

相等返回0

如果不相等:

小於(每個字元進行對比,根據編碼數字差返回第一個不相等的字元差)

大於(每個字元進行對比,根據編碼數字差返回第一個不相等的字元差)

這個方法很重要

 

public class StringDemo {

      public static void main(String[] args) {

             String str1 = "hello";

             System.out.println("Hello".equals(str1));

             System.out.println("Hello".equalsIgnoreCase(str1));

            

             System.out.println("A".compareTo("a"));

             System.out.println("a".compareTo("A"));

            

             System.out.println("abb".compareTo("adc"));

      }

}

/*

E:\01_JAVA\project\java_basic\mldn\02\course_28>javaStringDemo

false

true

-32

32

-2

*/

 

 

課時29 String類的常用方法(字串查詢)- 重要

 

contains() // 普通方法,判斷一個子字串是否存在,返回booleanJDK1.5之後追加

 

indexOf() // 普通方法,查詢子字串的索引,返回第一個字元的位置索引,不存在則返回-1

 

indexOf(String str, intindex) //從指定位置開始查詢

 

lastIndexOf() //從後向前找

 

lastIndexOf(String str, intindex) //從指定位置從後往前找

 

startsWith(String prefix) // 由指定子字串開頭

startsWith(String prefix, inttoffset) //從指定位置開始判斷,由指定子字串開頭

 

endsWith(String prefix) //由指定子字串結尾

 

建議使用contains()

 

 

課時30 String類的常用方法(字串替換)

 

指定一個新的字串替換字串中的某個字串

 

//需要替換的字串 目標字串

 

replaceAll(String regex,String replacement)

 

replaceFirst(String regex,String replacement)

 

 

課時31 String類的常用方法(字串拆分)

 

string[] split(String regx)

 

string[] split(String regx,int limit) // 部分拆分,分成幾段,2 代表2段 最大長度,如果沒有到最大長度,那就有多少拆多少

 

\\轉義字元

 

 

課時32 String類的常用方法(字串擷取)

 

substring(int beginindex) //從指定索引擷取到結尾

substring)int beginindex, intendindex) //指定區間擷取

索引從0開始

 

 

 

課時33 String類的常用方法(字串其它操作方法)

 

trim() //去掉字串的左右空格,一個或者多個

 

toUpperCase() //轉大寫

toLowerCase() //轉小寫

這兩個函式,如果不是字母,那麼就不做轉換

 

intern() //字串存入物件池

 

contact(String str) //字串連線,跟+一樣

 

 

length() //字串長度

 

isEmpty() //判斷是否為空字串,長度為0,非null

 

沒有提供首字元大寫的方法

 

實現首字母大寫的方法

 

 

課時34 this關鍵字(this呼叫屬性)

 

this 可以呼叫

1. 本類屬性

2. 本類方法(構造和普通)

3. 當前物件(相對概念)

 

下面賦值執行之後,name 為 null,age 為 0;

程式以大括號為邊界,不會去找外部定義的屬性name

 

 

引數與屬性同名,解決方法

 

類的方法中有需要用到屬性,一定在前面加this關鍵字

課時35 this關鍵字(this呼叫方法)

 

this.函式名稱(引數)

this.構造方法名稱(引數)

 

區分方法的定義來源(繼承中有用)

 

java支援類構造方法的互相呼叫:

例子,使用2個引數的呼叫,先呼叫1個引數的,再賦值age,呼叫1個引數的時候,使用無引數的建構函式先輸出一段資訊,然後再賦值name

 

有以下幾點要求

this()

 

1. this()必須放在構造方法的首行

2. 使用this()構造方法的時候留出口(遞迴死迴圈)(比如在上面這個例子中無參構造裡面呼叫2個引數的建構函式)

 

 

課時36 this關鍵字(表示當前物件)

 

 

this指向p1

 

 

課時37 引用傳遞進階分析

 

java核心

 

3個簡單例子

 

第一個:

class Message {

      private int num ;

      public void setNum(int num) {

             this.num = num ;

      }

      public int getNum() {

             return this.num ;

      }

}

 

public class TestDemo {

      public static void main(String[] args) {

             Message msg = new Message();

             msg.setNum(100);

             fun(msg);

             System.out.println(msg.getNum());

      }

      public static void fun(Message temp) {

             temp.setNum(30);

      }

}

 

 

第二個:

public class TestDemo2 {

      public static void main(String[] args) {

             String str = "hello";

             fun(str);

             System.out.println(str);

      }

      public static void fun(String temp) {

             temp = "world";

      }

}

 

 

第三個:

classMessage2 {

      private String note ;

      public void setNote(String note) {

             this.note = note ;

      }

      public String getNote() {

             return this.note ;

      }

}

 

publicclass TestDemo3 {

      public static void main(String[] args) {

             Message2 msg = new Message2();

             msg.setNote("hello");

             fun(msg);

             System.out.println(msg.getNote());

      }

      public static void fun(Message2 temp) {

             temp.setNote("world");

      }

}

 

 

課時38 【第02個程式碼模型】綜合案例:物件比較

 

比較兩個物件的屬性

實現形式1

classPerson {

      private String name ;

      private int age ;

      public Person(String name, int age) {

             this.name = name ;

             this.age = age ;

      }

      public String getName() {

             return this.name ;

      }

      public int getAge() {

             return this.age ;

      }

}

 

publicclass TestDemo1 {

      public static void main(String[] args) {

             Person perA = newPerson("A",20);

             Person perB = newPerson("A",20);

             System.out.println(perA == perB);

            

             if(perA.getAge() == perB.getAge()&& perA.getName().equals(perB.getName())) {

                    System.out.println("perA == perB ");

             }

      }

}

 

// 這種形式在開發過程中不會出現,主方法需要出現的邏輯太多了

 

方法2

類方法自帶比較方法

compare()

classPerson {

       private String name ;

       private int age ;

       public Person(String name, int age) {

              this.name = name ;

              this.age = age ;

       }

       public String getName() {

              return this.name ;

       }

       public int getAge() {

              return this.age ;

       }

       //this表示當前物件,另外一個是傳入物件

       public boolean compare(Person per) {

              if (per == this) {

                     return true;

              }

              if (per == null) {

                     return false;

              }

              if (this.name.equals(per.name)&& this.age == per.age) {

                     return true;

              } else {

                     return false;

              }

       }

}

 

publicclass TestDemo2 {

       public static void main(String[] args) {

              Person perA = newPerson("A",20);

              Person perB = new Person("A",20);

              System.out.println(perA.compare(perB));

       }

}

 

判斷步驟:

1. 判斷地址

2. 判斷是否為空

3. 判斷物件的各個屬性

 

課時39 引用傳遞實際應用

引用傳遞是java核心

合成設計模式

 

 class Member {

      private String name;

      private int age;

      private Member child;

      //car == null, 說明此人無車

      private Car car;

      public Member(String name, int age) {

             this.name = name;

             this.age = age;

      }

      public void setName(String name) {

             this.name = name;

      }

      public String getName() {

             return this.name;

      }

      public void setAge(int age) {

             this.age = age;

      }

      public int getAge() {

             return this.age;

      }

      public void setChild(Member child) {

             this.child = child;

      }

      public Member getChild() {

             return this.child;

      }

      public void setCar(Car car) {

             this.car = car;

      }

      public Car getCar() {

             return this.car;

      }

      public String getInfo() {

             return "[Member] name = " + this.name + "age = " + this.age;

      }

}

 

class Car {

      private String car;

      private double price;

      private Member member;

      public Car(String car, double price) {

             this.car = car;

             this.price = price;

      }

      public void setCar(String car) {

             this.car = car;

      }

      public String getCar() {

             return this.car;

      }

      public void setPirce(double price) {

             this.price = price;

      }

      public double getPrice() {

             return this.price;

      }

      public void setMem(Member member) {

             this.member = member;

      }

      public Member getMember() {

             return this.member;

      }

      public String getInfo() {

             return "[car] car = " + this.car + "price = " + this.price;

      }

}

 

public class TestDemo {

      public static void main(String[] main) {

             Member mem = new Member("A",30);

             Car car = new Car("car-a",100);

             Member child = new Member("B",2);

             Car childCar = new Car("car-b",200);

            

             mem.setCar(car);

             mem.setChild(child);

             car.setMem(mem);

             child.setCar(childCar);

             childCar.setMem(child);

            

             System.out.println(mem.getInfo());

             System.out.println(mem.getCar().getInfo());

             System.out.println(car.getMember().getInfo());

             System.out.println(mem.getChild().getInfo());

             System.out.println(mem.getChild().getCar().getInfo());

      }

}

 

課時40 【第03個程式碼模型】綜合案例:資料表與簡單Java類(一對多)

 

/**

1. 先定義基本類,包括屬性,建構函式,getInfo()函式

2. 定義各個類之間的關係,僱員的領導,部門裡面的所有僱員,僱員屬於哪個部門

3. 實現開發需求

(1) 設定類物件間的關係

(2) 獲取資料

*/

 

class Emp {

      private int empno ;

      private String ename ;

      private String job ;

      private double sal ;

      private double comm ;

      private Emp mgr ;

      private Dept dept ;

      public Emp() {}

      public Emp(int empno, String ename, String job, double sal,double comm) {

             this.empno = empno ;

             this.ename = ename ;

             this.job = job ;

             this.sal = sal ;

             this.comm = comm;

      }

      public void setMgr(Emp mgr) {

             this.mgr = mgr ;

      }

      public Emp getMgr() {

             return this.mgr ;

      }

      public void setDept(Dept dept) {

             this.dept = dept ;

      }

      public Dept getDept() {

             return this.dept ;

      }

      public String getInfo() {

             return "[Emp] empno = " + empno

             + " ename = " + ename

             + " job = " + job

             + " sal = " + sal

             + " comm = " + comm;

      }

}

 

class Dept {

      private int deptno ;

      private String dname ;

      private String loc ;

      private Emp[] emps;

      public Dept() {}

      public Dept(int deptno, String dname, String loc) {

             this.deptno = deptno ;

             this.dname = dname ;

             this.loc = loc ;

      }

      public void setEmps(Emp[] emps) {

             this.emps = emps ;

      }

      public Emp[] getEmps() {

             return this.emps ;

      }

      public String getInfo() {

             return "[Dept] deptno = " + deptno

             + " dname = " + dname

             + " loc = " + loc;

      }

}

 

public class TestDemo {

      public static void main(String[] args) {

             Dept dept = new Dept(10,"accounting","newyork");

             Emp ea = newEmp(1,"A","Job-a",100.0,1.0);

             Emp eb = newEmp(1,"B","Job-b",200.0,2.0);

             Emp ec = newEmp(1,"C","Job-c",300.0,3.0);

            

             ea.setMgr(eb);

             eb.setMgr(ec);

            

             ea.setDept(dept);

             eb.setDept(dept);

             ec.setDept(dept);

            

             dept.setEmps(new Emp[] {ea,eb,ec});

             System.out.println(dept.getInfo());

             for (Emp emp : dept.getEmps()) {

                    System.out.println("\t |-" +emp.getInfo());

                    if (emp.getMgr() != null) {

                           System.out.println("\t\t |-" +emp.getMgr());

                    }

             }

             System.out.println(eb.getInfo());

             if (eb.getMgr() != null) {

                    System.out.println("\t |-" +eb.getMgr().getInfo());

             }

             if (eb.getDept() != null) {

                    System.out.println("\t\t |-" +eb.getDept().getInfo());

             }

      }

}

 

課時41 【第03個程式碼模型】綜合案例:資料表與簡單Java類(多對多)

 

/**

基本資訊:

學生表:編號,姓名,年齡,

課程表:編號,名稱,學分

學生-課程關係表:學生編號,課程編號,成績

 

需求:

1. 找到一門課程,參加此課程的所有學生資訊和成績

2. 找到一個學生,參加的課程的課程資訊和成績

 

設計過程:

1. 定義基本類,前2個表,

 

2. 第三個表是學生選課資訊

 

3. 篩選關係,去掉第一步做的學生中的課程物件陣列,取出課程中的學生陣列,因為第二部中設計的表可以

表達關係了

 

4. 輸出關係

 

 

*/

class Student {

      private int studentId;

      private String studentName;

      private int studentAge;

      private StudentCourse[] studentCourse;

      public Student() {}

      public Student(int studentId, String studentName, intstudentAge) {

             this.studentId = studentId;

             this.studentName = studentName;

             this.studentAge = studentAge;

      }

      public void setStudentCourse(StudentCourse[] studentCourse) {

             this.studentCourse = studentCourse;

      }

      public StudentCourse[] getStudentCourse() {

             return this.studentCourse;

      }

      public String getInfo() {

             return "[Student] ID = " + this.studentId

             + " Name = " + this.studentName

             + " Age = " + this.studentAge;

      }

}

class Course {

      private int courseId;

      private String courseName;

      private int credit;

      private StudentCourse[] studentCourse;

      public Course() {}

      public Course(int courseId, String courseName, int credit) {

             this.courseId = courseId;

             this.courseName = courseName;

             this.credit = credit;

      }

      public void setStudentCourse(StudentCourse[] studentCourse) {

             this.studentCourse = studentCourse;

      }

      public StudentCourse[] getStudentCourse() {

             return this.studentCourse;

      }

      public String getInfo() {

             return "[Course] ID = " + this.courseId

             + " Name = " + this.courseName

             + " credit = " + this.credit;

      }

}

class StudentCourse {

      private Student student;

      private Course course;

      private double score;

     

      public StudentCourse() {}

      public StudentCourse(Student student, Course course, doublescore) {

             this.student = student;

             this.course = course;

             this.score = score;

      }

      public Student getStudent() {

             return this.student;

      }

      public Course getCourse() {

             return this.course;

      }

      public double getScore() {

             return this.score;

      }

      public String getInfo() {

             return //this.student.getInfo()

             //+ this.course.getInfo()

             //+

             "[score] score = " + this.score;

      }

}

 

public class TestDemo {

      public static void main(String[] args) {

             Student a = new Student(1,"a",18);

             Student b = new Student(2,"b",19);

             Student c = new Student(3,"c",20);

            

             Course ca = new Course(1,"ca",10);

             Course cb = new Course(2,"cb",20);

             Course cc = new Course(3,"cc",30);

            

             a.setStudentCourse(new StudentCourse[] {

                    new StudentCourse(a,ca,100.0),

                    new StudentCourse(a,cb,100.0),

                    new StudentCourse(a,cc,100.0)

             });

             b.setStudentCourse(new StudentCourse[] {

                    new StudentCourse(b,ca,90.0),

                    new StudentCourse(b,cb,90.0),

                    new StudentCourse(b,cc,90.0)

             });

             c.setStudentCourse(new StudentCourse[] {

                    new StudentCourse(c,ca,80.0),

                    new StudentCourse(c,cb,80.0),

                    //new StudentCourse(b,cc,90)

             });

            

             ca.setStudentCourse( new StudentCourse[] {

                    new StudentCourse(a,ca,100.0),

                    new StudentCourse(b,ca,90.0),

                    new StudentCourse(c,ca,80.0)

             });

             cb.setStudentCourse( new StudentCourse[] {

                    new StudentCourse(a,cb,100.0),

                    new StudentCourse(b,cb,90.0),

                    new StudentCourse(c,cb,80.0)

             });

             cc.setStudentCourse( new StudentCourse[] {

                    new StudentCourse(a,cb,100.0),

                    new StudentCourse(b,cb,90.0)

             });

            

             System.out.println("******************************");

             System.out.println(a.getInfo());

             System.out.println(b.getInfo());

             System.out.println(c.getInfo());

            

             System.out.println("******************************");

             System.out.println(ca.getInfo());

             System.out.println(cb.getInfo());

             System.out.println(cc.getInfo());

            

             System.out.println("******************************");

             System.out.println(ca.getInfo());

             for (int x = 0; x < ca.getStudentCourse().length;x++) {

                    System.out.println("\t |- " +ca.getStudentCourse()[x].getStudent().getInfo() + "\n\t\t |- " +ca.getStudentCourse()[x].getInfo());

             }

             System.out.println("******************************");

             System.out.println(a.getInfo());

             for (int x = 0; x < a.getStudentCourse().length; x++){

                    System.out.println("\t |- " +a.getStudentCourse()[x].getCourse().getInfo() + "\n\t\t |- " +ca.getStudentCourse()[x].getInfo());

             }

      }

}

 

課時42 【第03個程式碼模型】綜合案例:資料表與簡單Java類(角色與許可權)

1. 進行單獨類的描述

Dept //部門

Emp //員工

Role //角色

Privilege //許可權

 

屬性

建構函式

getInfo()函式

 

2. 進行關係的描述

一個部門有多個員工 ,且只有一個角色

員工只有一個部門

角色有多個部門,多個許可權

許可權有多個角色

角色-許可權是2個外來鍵(沒有其他多的資料,上個例子有個成績),不需要建表

 

3. 實現資料輸出

建立部門資料,2個

建立員工資料,5個

建立角色資訊,2個

建立許可權資料,4個

 

部門和僱員

僱員和部門

 

部門和角色

角色和部門

 

設定角色和許可權的關係

設定許可權和角色的關係

 

4. 取出資料

完畢

 

class Dept {

      private int deptID;

      private String deptName;

      private Emp[] emps;

      private Role role;

     

      public Dept() {}

      public Dept(int deptID, String deptName) {

             this.deptID = deptID;

             this.deptName = deptName;

      }

      public void setEmps(Emp[] emps) {

             this.emps = emps;

      }

      public Emp[] getEmps() {

             return this.emps;

      }

      public void setRole(Role role) {

             this.role = role;

      }

      public Role getRole() {

             return this.role;

      }

      public String getInfo() {

             return "[Dept] deptID = " + this.deptID

             + " deptName = " + this.deptName;

      }

}

class Emp {

      private int empId;

      private String empName;

      private Dept dept;

     

      public Emp() {}

      public Emp(int empId, String empName) {

             this.empId = empId;

             this.empName = empName;

      }

      public void setDept(Dept dept) {

             this.dept = dept;

      }

      public Dept getDept(){

             return this.dept;

      }

      public String getInfo() {

             return "[Emp] empId = " + this.empId

             + " empName = " + this.empName;

      }

}

class Role {

      private int roleId;

      private String roleName;

      private Dept[] depts;

      private Privilege[] privileges;

     

      public Role() {}

      public Role(int roleId, String roleName) {

             this.roleId = roleId;

             this.roleName = roleName;

      }

      public void setDepts(Dept[] depts) {

             this.depts = depts;

      }

      public Dept[] getDepts() {

             return this.depts;

      }

      public void setPrivileges(Privilege[] privileges) {

             this.privileges = privileges;

      }

      public Privilege[] getPrivileges() {

             return this.privileges;

      }

      public String getInfo() {

             return "[Role] roleId = " + this.roleId

             + " roleName = " + roleName;

      }

}

class Privilege {

      private int pId;

      private String pName;

      private String pFlag;

      private Role[] roles;

     

      public Privilege() {}

      public Privilege(int pId, String pName, String pFlag) {

             this.pId = pId;

             this.pName = pName;

             this.pFlag = pFlag;

      }

      public void setRoles(Role[] roles) {

             this.roles = roles;

      }

      public Role[] getRoles() {

             return this.roles;

      }

      public String getInfo() {

             return "[Privilege] pId = " + pId

             + " pName = " + pName

             + " pFlag = " + pFlag;

      }

}

 

public class TestDemo {

      public static void main(String[] args) {

             Dept deptA = new Dept(1,"財務部");

             Dept deptB = new Dept(2,"技術部");

             Dept deptC = new Dept(3,"行政部");

            

             Emp empA = new Emp(1,"員工A");

             Emp empB = new Emp(2,"員工B");

             Emp empC = new Emp(3,"員工C");

             Emp empD = new Emp(4,"員工D");

             Emp empE = new Emp(5,"員工E");

            

             Role roleA = new Role(1,"普通員工");

             Role roleB = new Role(2,"高階員工");

            

             Privilege PA = new Privilege(1000,"查詢","正常");

             Privilege PB = new Privilege(1001,"刪除","正常");

             Privilege PC = new Privilege(1002,"修改","正常");

            

             empA.setDept(deptA);

             empB.setDept(deptA);

             empC.setDept(deptB);

             empD.setDept(deptB);

             empE.setDept(deptC);

            

             deptA.setEmps(new Emp[] {empA,empB});

             deptB.setEmps(new Emp[] {empC,empD});

             deptC.setEmps(new Emp[] {empE});

            

             deptA.setRole(roleA);

             deptB.setRole(roleA);

             deptC.setRole(roleB);

            

             roleA.setDepts(new Dept[] {deptA,deptB});

             roleB.setDepts(new Dept[] {deptC});

            

             roleA.setPrivileges(new Privilege[] {PA});

             roleB.setPrivileges(new Privilege[] {PA,PB,PC});

            

             PA.setRoles(new Role[] {roleA,roleB});

             PB.setRoles(new Role[] {roleB});

             PC.setRoles(new Role[] {roleB});

            

             System.out.println(empA.getInfo());

             System.out.println("\t |-" +empA.getDept().getInfo());

             System.out.println("\t\t |-" +empA.getDept().getRole().getInfo());

             for (Privilege x :empA.getDept().getRole().getPrivileges()) {

                    System.out.println("\t\t\t |-" +x.getInfo());

             }

             System.out.println(roleA.getInfo());

             for (Dept x : roleA.getDepts()) {

                    System.out.println("\t |- " +x.getInfo());

                    for (Emp y : x.getEmps()) {

                           System.out.println("\t\t|- " + y.getInfo());

                    }

             }

             System.out.println(PA.getInfo());

             for (Role x : PA.getRoles()) {

                    System.out.println("\t |- " +x.getInfo());

                    for (Dept y : x.getDepts()) {

                           System.out.println("\t\t |- " +y.getInfo());

                           for(Emp z : y.getEmps()) {

                           System.out.println("\t\t\t |- "+ z.getInfo());

                    }

                    }

             }

      }

}

 

 

課時43 static關鍵字(static屬性)

 

class Person {

      private String name;

      private int age;

      String country = "China";

      public Person(String name, int age) {

             this.name = name;

             this.age = age;

      }

      public String getInfo() {

             return "[Person] name = " + this.name

             + " age = " + this.age

             + " country = " + this.country;

      }

}

 

public class TestDemo {

      public static void main(String[] args) {

             Person p1 = new Person("張三",10);

             Person p2 = new Person("李四",11);

             Person p3 = new Person("王五",12);

             System.out.println(p1.getInfo() + "\n" +p2.getInfo() + "\n" + p3.getInfo());

      }

}

 

 

以上country物件被重複儲存了

 

需要把country變為共享屬性

加static關鍵字

class Person {

      private String name;

      private int age;

      static String country = "China";

      public Person(String name, int age) {

             this.name = name;

             this.age = age;

      }

      public String getInfo() {

             return "[Person] name = " + this.name

             + " age = " + this.age

             + " country = " + this.country;

      }

}

 

public class TestDemo {

      public static void main(String[] args) {

             Person p1 = new Person("張三",10);

             Person p2 = new Person("李四",11);

             Person p3 = new Person("王五",12);

             p1.country = "USA";

             System.out.println(p1.getInfo() + "\n" +p2.getInfo() + "\n" + p3.getInfo());

      }

}

/*

E:\01_JAVA\project\java_basic\mldn\02\course_43>javacTestDemo.java

 

E:\01_JAVA\project\java_basic\mldn\02\course_43>javaTestDemo

[Person] name = 張三 age = 10 country = USA

[Person] name = 李四 age = 11 country = USA

[Person] name = 王五 age = 12 country = USA

 

E:\01_JAVA\project\java_basic\mldn\02\course_43>

*/

 

這樣就不儲存在堆記憶體中,而是儲存在全域性資料區的記憶體空間中,所有物件都可以對該資料區進行訪問

 

此時程式碼可以通過一個物件修改,static要通過類名稱直接呼叫,不要使用物件

語法

Person.country ="AA";

static屬性不受例項化影響,建立物件前就可以操作

 

選擇:是否選用static關鍵字

定義類99%的情況下不採用static屬性

如果需要描述共享屬性的概念,或者不希望收到例項化物件控制的時候,使用static

 

 

課時44 static關鍵字(static方法)

限制,語法規定:

所有的static方法不允許呼叫非static定義的屬性和方法

所有的非static方法允許呼叫static定義的屬性和方法

 

原因:所有的static方法可以再沒有例項化物件的時候訪問。

 

使用static方法的目的:某些方法不希望受到類例項化物件的限制。

 

課時45 static關鍵字(分析主方法)

public static voidmain(String[] args)

 

主方法中定義方法的語法

public static 返回值 方法名(引數)

 

比如 public static void Print() {

      //

}

 

如果沒加static,那麼就是類中的方法,需要例項化使用

 

public static voidmain(String[] args)

 

public 表示公共,主方法作為程式起點,必須可以被公共使用

static 執行java程式的時候是類名稱,不受例項化限制

void 主方法是起點,沒有返回值

main 系統定義的方法名稱

String[] args 引數,都是String

 

課時46 static關鍵字(static應用)

 

1. static物件的計數統計

class Person {

      private static int count = 0;

      public Person() {

             System.out.println( ++count );

      }

}

 

public class TestDemo {

      public static void main(String[] args) {

             Person p1 = new Person();

             Person p2 = new Person();

             Person p3 = new Person();

      }

}

 

2. static實現 呼叫無參構造對屬性做自動賦值,給屬性自動命名

class Person {

      private String name;

      private static int count = 0;

      public Person() {

             this("NONAME - " + ++count); //呼叫本類有參構造

      }

      public Person(String name) {

             this.name = name;

      }

      public String getName() {

             return this.name;

      }

}

 

public class TestDemo {

      public static void main(String[] args) {

             System.out.println(new Person().getName());

             System.out.println(new Person("MLDN"));

             System.out.println(new Person().getName());

      }

}

 

總結:

static屬性和方法不是定義類的首要選擇

static屬性和方法不受類的例項化物件限制,可以直接通過類名稱呼叫

 

 

課時47 程式碼塊(普通程式碼塊)

不重要的概念,清楚結構即可

 

使用{}定義的一段程式碼

1. 普通程式碼塊

2. 構造程式碼塊

3. 靜態程式碼塊

4. 同步程式碼塊(多執行緒)

 

普通程式碼塊:

定義在方法中的程式碼塊

 

public class TestDemo {

      public static void main(String[] args) {

             {//程式碼塊

                    int x = 10;

                    System.out.println( "x = " + x);

             }//程式碼塊

             int x = 100;

             System.out.println( "x = " + x);

      }

}

 

作用:避免變數重名

作用不大

 

課時48 程式碼塊(構造塊)

 

類中的程式碼塊

 

class Person {

      {//構造塊1

             System.out.println("1");

      }

      {//構造塊2

             System.out.println("2");

      }

      public Person() {

             System.out.println("4");

      }

      {//構造塊3

             System.out.println("3");

      }

}

 

public class TestDemo {

      public static void main(String[] args) {

             new Person();

             new Person();

      }

}

 

E:\01_JAVA\project\java_basic\mldn\02\course_48>javaTestDemo

1

2

3

4

1

2

3

4

 

E:\01_JAVA\project\java_basic\mldn\02\course_48>

 

先會執行構造塊,再執行構造方法

 

普通手段,沒有什麼意義,掌握概念即可

 

 

課時49 程式碼塊(靜態程式碼塊)

使用static關鍵字定義的程式碼塊

1. 非主類定義的

2. 主類中定義的

 

class Person {

      {//構造塊1

             System.out.println("1");

      }

      {//構造塊2

             System.out.println("2");

      }

      public Person() {

             System.out.println("4");

      }

      {//構造塊3

             System.out.println("3");

      }

      static {//靜態塊

             System.out.println("5");

      }

}

 

public class TestDemo {

      public static void main(String[] args) {

             new Person();

             new Person();

      }

}

靜態塊優先於構造塊執行

 

E:\01_JAVA\project\java_basic\mldn\02\course_49>javacTestDemo.java

 

E:\01_JAVA\project\java_basic\mldn\02\course_49>javaTestDemo

5

1

2

3

4

1

2

3

4

 

E:\01_JAVA\project\java_basic\mldn\02\course_49>

 

用於static屬性初始化

classPerson {

       private static String info ="hello";

       {//構造塊1

              System.out.println("1");

       }

       {//構造塊2

              System.out.println("2");

       }

       public Person() {

              System.out.println("4");

       }

       {//構造塊3

              System.out.println("3");

       }

       static {//靜態塊

              info += " world";

              System.out.println(info);

       }

}

 

publicclass TestDemo {

       public static void main(String[] args) {

              new Person();

              new Person();

       }

}

 

E:\01_JAVA\project\java_basic\mldn\02\course_49>javacTestDemo.java

 

E:\01_JAVA\project\java_basic\mldn\02\course_49>javaTestDemo

helloworld

1

2

3

4

1

2

3

4

 

E:\01_JAVA\project\java_basic\mldn\02\course_49>

在主類中使用:

 

publicclass TestDemo {

       static {

              System.out.println("*********************");

       }

       public static void main(String[] args) {

              System.out.println("helloworld");

       }

}

E:\01_JAVA\project\java_basic\mldn\02\course_49>javacTestDemo.java

 

E:\01_JAVA\project\java_basic\mldn\02\course_49>javaTestDemo

*********************

helloworld

 

E:\01_JAVA\project\java_basic\mldn\02\course_49>

 

課時50 內部類的定義及使用(內部類基本概念)

 

暫時不作為首要的類設計原則

 

概念,一個類之內進行其他類結構巢狀的語法形式

 

class Outer {

      private String msg = "out";

      class Inner {

             public void print() {

                    System.out.println(msg);

             }

      }

      public void fun() {

             Inner in = new Inner();

             in.print();

      }

}

 

public class TestDemo {

      public static void main(String[] args) {

             Outer out = new Outer();

             out.fun();

      }

}

 

--- 程式結構混亂

 

好處:外部類對內部類的私有屬性訪問,內部類對外部類的私有屬性訪問

 

例子:

兩個獨立類,訪問外部類的私有屬性,會很複雜

 

class Outer {

      private String msg = "out";

      public String getMsg() {

             return this.msg;

      }

      public void fun() {

             Inner in = new Inner(this);

             in.print();

      }

}

class Inner {

      private Outer out;

      public Inner(Outer out) {

             this.out = out;

      }

      public void print() {

             System.out.println(out.msg);

      }

}

public class OuterDemo {

      public static void main(String[] args) {

             Outer out = new Outer();

             out.fun();

      }

}

 

內部類的操作:

1. 內部類的訪問需要通過外部類的方法完成,如果不想這麼執行,那麼需要進行例項化物件

             外部類.內部類 內部類物件 = new 外部類().new 內部類();

進行外部類的例項化是因為外部類中有普通屬性,需要開闢空間,所以先new外部類

 

2. 不直接產生內部類物件

private class Inner() {

//

}

外部類需要建立方法

Inner in = new Inner()

 

new Outer().fun()

 

3. 外部類當前物件的屬性Outter.this.屬性

 

 

課時51 內部類的定義及使用(static定義內部類)

 

static定義,表示外部類的形式(結構和功能一樣),這個內部類只能訪問外部類中的static屬性和操作

 

 

如果要操作外部類:

語法:

例項化物件: 外部類.內部類 內部類物件名稱 = new 外部類.內部類();

 

 

瞭解即可

 

課時52 內部類的定義及使用(在方法中定義內部類)

 

在方法中定義內部類的形式是最多的

 

問題:JDK1.8正常,之前的版本都是錯誤的

 

JDK1.7之前,如果方法中的內部類需要訪問引數,引數必須使用final定義

 

程式設計中根據jdk版本決定是否加final

 

內部類使用暫時不作為首選

 

 

課時53 繼承的定義與使用(繼承問題的引出)

物件導向的第二個特點

 

在已有的基礎上進行功能的擴充

 

消除結構定義上的重複

 

課時54 繼承的定義與使用(繼承的實現)

 

extends

語法

class 子類 extends 父類 {

}

 

 

 

子類可以直接繼承父類的操作,屬性和方法

 

擴充

 

 

課時55 繼承的定義與使用(繼承使用限制)

 

1. 子類物件在例項化前,先會例項化父類,呼叫父類的構造方法,再例項化子類,呼叫子類的構造方法

 

 

其實子類的構造方法隱含了super()方法

 

 

需要注意的是父類沒有無參構造,那麼super必須指定父類的構造方法

 

 

 

2. 只允許單繼承,不允許多繼承

 

一個子類只能繼承一個父類

 

但是可以使用多層繼承,一般建議3層最多

 

 

3. 進行繼承的時候,子類會繼承父類的所有結構。

私有屬性,構造方法,普通方法

顯示繼承(直接呼叫)

操作父類的私有屬性,隱式繼承(setter和getter)

 

所有的private操作肯定無法直接使用

 

 

 

需要掌握:

1、繼承的語法和目的

2、子類物件的例項化流程

3、繼承的限制

 

擴充套件已有類的功能 ===== 程式碼重用

 

 

課時56 覆寫(方法覆寫)

 

重點核心

 

子類定義了與父類方法名稱、引數型別和個數完全相同的方法,不能有比父類更嚴格的訪問許可權

 

 

 

進行復寫使用的時候,需要關注

 

1、當前使用的物件是使用哪個類new的

2、呼叫方法如果被子類重寫過,則會呼叫子類的方法

 

注意:

被複寫的方法不能比父類有更嚴格的訪問許可權

private < default <public

父類中使用default許可權,那麼子類可以使用default/public

 

方法使用public

屬性使用private

 

但是:

如果父類中使用private,子類中不能使用public,這樣子類的中屬於新方法,不屬於複寫

 

過載 複寫

overloading override

 

過載:方法名稱相同,引數型別和個數不同(返回值可以不同,但是開發規範建議不要)

在同個類中

無許可權要求

 

複寫:

方法名稱,引數型別和個數,返回值都一樣

在繼承關係中提現

子類同個方法不能擁有比父類更嚴格的許可權控制

 

 

 

課時57 覆寫(屬性覆蓋)

 

子類定義了和父類 名稱相同的屬性

 

按照就近取用,取子類的屬性

 

這個操作本身沒有意義,因為屬性都採用Private封裝,且開發過程中不要使用重名屬性

 

 

課時58 覆寫(super關鍵字)

 

super.方法()

super.屬性

 

子類呼叫父類

 

開發原則:在子類中使用父類方法和屬性的時候,使用super

 

 

 

super和this的區別

 

this:

訪問本類中的屬性和方法

先查詢本類,如果本類沒有則查詢本類

表示當前物件

super:

訪問父類中的屬性和方法

不查詢本類,直接找父類

 

 

1、子類複寫弗雷德方法是因為父類的方法功能不足,才需要複寫

2、方法複寫的時候使用的是public許可權

 

課時59 綜合案例:陣列操作(定義Array父類)

 

class Array {

      private int[] data;

      private int foot;

     

      public Array(int length) {

             if (length > 0)

                    this.data = new int [length];

             else

                    this.data = new int [1];

      }

      public boolean add(int num) {

             if (this.foot >= this.data.length) {

                    return false;

             } else {

                    this.data[foot++] = num;

                    return true;

             }

}

 

public class TestDemo {

      public static void main(String[] args) {

             Array array = new Array(5);

      }

}

 

class Array {

      private int[] data;

      private int foot;

     

      public Array(int length) {

             if (length > 0)

                    this.data = new int [length];

             else

                    this.data = new int [1];

      }

      public boolean add(int num) {

             if (this.foot >= this.data.length) {

                    return false;

             } else {

                    this.data[foot++] = num;

                    return true;

             }

      }

      public int[] getData() {

             return this.data;

      }

      public void inc(int num) {

             int[] newData = new int[this.data.length + num];

             System.arraycopy(this.data,0,newData,0,this.data.length);

             this.data = newData;

      }

}

 

public class TestDemo {

      public static void main(String[] args) {

             Array array = new Array(5);

             System.out.println(array.add(10));

             System.out.println(array.add(9));

             System.out.println(array.add(8));

             System.out.println(array.add(7));

             System.out.println(array.add(6));

             array.inc(4);

             System.out.println(array.add(5));

             System.out.println(array.add(4));

             System.out.println(array.add(3));

             System.out.println(array.add(2));

             System.out.println(array.add(1));

             for (int x : array.getData()) {

                    System.out.print(x + ", ");

             }

             System.out.println();

      }

}

 

課時60 綜合案例:陣列操作(SortArray排序子類)

 

class Array {

      private int[] data;

      private int foot;

     

      public Array(int length) {

             if (length > 0)

                    this.data = new int [length];

             else

                    this.data = new int [1];

      }

      public boolean add(int num) {

             if (this.foot >= this.data.length) {

                    return false;

             } else {

                    this.data[foot++] = num;

                    return true;

             }

      }

      public int[] getData() {

             return this.data;

      }

      public void inc(int num) {

             int[] newData = new int[this.data.length + num];

             System.arraycopy(this.data,0,newData,0,this.data.length);

             this.data = newData;

      }

}

class SortArray extends Array{

      //父類中沒有無引數的構造方法,因此子類必須明確呼叫父類中的有參構造方法

      public SortArray(int num) {

             super(num);

      }

      public int[] getData() {

             java.util.Arrays.sort(super.getData());

             return super.getData(); //引用傳遞

      }

}

public class TestDemo {

      public static void main(String[] args) {

             SortArray array = new SortArray(5);

             System.out.println(array.add(10));

             System.out.println(array.add(9));

             System.out.println(array.add(8));

             System.out.println(array.add(7));

             System.out.println(array.add(6));

             array.inc(4);

             System.out.println(array.add(5));

             System.out.println(array.add(4));

             System.out.println(array.add(3));

             System.out.println(array.add(2));

             System.out.println(array.add(1));

             for (int x : array.getData()) {

                    System.out.print(x + ", ");

             }

             System.out.println();

      }

}

 

不同的子類要根據不同的需求進行擴寫

 

課時61 綜合案例:陣列操作(ReverseArray反轉子類)

class Array {

      private int[] data;

      private int foot;

     

      public Array(int length) {

             if (length > 0)

                    this.data = new int [length];

             else

                    this.data = new int [1];

      }

      public boolean add(int num) {

             if (this.foot >= this.data.length) {

                    return false;

             } else {

                    this.data[foot++] = num;

                    return true;

             }

      }

      public int[] getData() {

             return this.data;

      }

      public void inc(int num) {

             int[] newData = new int[this.data.length + num];

             System.arraycopy(this.data,0,newData,0,this.data.length);

             this.data = newData;

      }

}

class SortArray extends Array{

      //父類中沒有無引數的構造方法,因此子類必須明確呼叫父類中的有參構造方法

      public SortArray(int num) {

             super(num);

      }

      public int[] getData() {

             java.util.Arrays.sort(super.getData());

             return super.getData(); //引用傳遞

      }

}

class ReverseArray extendsArray {

      public ReverseArray(int num) {

             super(num);

      }

      public int[] getData() {

             int mid = super.getData().length/2;

             int head = 0;

             int tail = super.getData().length-1;

             for (int x = 0; x < mid; x++) {

                    int temp = super.getData()[head];

                    super.getData()[head] = super.getData()[tail];

                    super.getData()[tail] = temp;

                    head++;

                    tail--;

             }

             return super.getData();

      }

}

public class TestDemo {

      public static void main(String[] args) {

             ReverseArray array = new ReverseArray(5);

             System.out.println(array.add(10));

             System.out.println(array.add(9));

             System.out.println(array.add(8));

             System.out.println(array.add(7));

             System.out.println(array.add(6));

             array.inc(4);

             System.out.println(array.add(5));

             System.out.println(array.add(4));

             System.out.println(array.add(3));

             System.out.println(array.add(2));

             System.out.println(array.add(1));

             for (int x : array.getData()) {

                    System.out.print(x + ", ");

             }

             System.out.println();

      }

}

 

課時62 final關鍵字

 

可以定義 類

 

方法

 

屬性

 

1、定義類的時候不能有子類,不能繼承

2、final定義的方法不能被子類複寫

3、final定義的變數為常量,不能修改

 

全域性常量的定義:識別符號全大寫

public static final intFINAL_INT = 0;

 

 

課時63 多型性

重要!

 

核心表現:

1、方法多型

方法的過載

方法的複寫

 

2、物件的多型性

實現前提:方法覆寫

      [自動]物件的向上轉型:父類 父類物件 = 子類例項; 例如int到double

      [強制]物件的向下轉型:子類 子類物件 = (子類)父類例項; 例如 double到int double = (int)資料

 

      不轉型,例如String

     

 

      向上轉型的情況,父類不可以呼叫子類中的方法

 

      只有強制轉換到 向下轉型 才可以呼叫子類的方法

 

     

【實際開發過程中用不到】不是所有的父類物件都可以向下轉型,如果要實現向下轉型,必須先向上轉型,

否則會出現ClassCastException異常(兩個不同的類發生轉換)

 

 

判斷後再轉型:

instanceof

語法:

子類物件 instanceof 類名稱

 

返回boolean

 

物件多型性:子類和父類之間的轉換

 

向上轉型核心用途:接收引數的操作統一

 

 

向下轉型:子類擴充方法的呼叫

 

以後的開發過程中不要出現向下轉型

 

課時64 抽象類的定義與使用(抽象類基本概念)

 

實際專案開發過程中,子類繼承的必須是抽象類

 

抽象類:基本類擴充了抽象方法(只宣告,沒有方法體)

 

抽象類會要求子類必須重寫抽象方法,比普通類要規範,普通類繼承的時候可以不重寫方法

 

 

abstract關鍵字

 

 

使用:

抽象類無法直接例項化

1、所有的抽象類必須要有子類

2、抽象類的子類(不是抽象類)必須複寫抽象類的全部抽象方法

             ---方法複寫要考慮許可權問題,最好一直使用public方法,而且private和abstract不能同時修飾同一個方法

3、抽象類的物件可以通過多型性,利用子類例項化

 

 

另外一種實現方式:(A類的子類只有1個B),這種設計形式比較少,內部提供子類。

對封裝性有好處,不作為開發首選。

 

 

 

課時65 抽象類的定義與使用(抽象類使用限制)

 

抽象類有構造方法,子類例項化的時候會先例項化父類

 

 

如果父類沒有無參構造,那麼子類要用super()指定父類的有參構造

 

 

另外一個問題:

程式輸出為0

 

例項化操作:

1、類載入

2、物件例項化,空間開闢

3、呼叫構造方法,屬性初始化

 

 

 

 

結論:如果構造方法沒有執行,那麼物件的屬性都是其預設值

 

 

 

抽象類中允許不定義抽象方法,但是依然無法直接從抽象類例項化

抽象類不能使用final宣告,抽象方法不能使用private定義

抽象類分為內部抽象類(可以使用static定義),描述為外部抽象類

 

課時66 抽象類的定義與使用(模版設計模式)

 

抽象類強制規定了子類的實現結構,更多情況下起到模板的作用

 

 

 

 

 

 

 

最具代表性的是:Servlet

 

1、抽象類單繼承侷限

2、抽象類的使用要通過子類例項化使用

 

 

 

課時67 介面的定義與使用(介面基本概念)

 

抽象類,避免單繼承缺點就要使用介面

 

開發設計原則:使用介面優先

 

基本概念:一個抽象方法+全域性常量的集合

 

語法:使用interface

介面命名前加大寫的I

 

子類使用介面,可以實現多個介面,介面可以實現多繼承的概念,關鍵字implements

如果子類不是抽象類,就需要重寫介面中的所有抽象方法

 

 

 

 

介面之間的轉化

 

一個子類繼承了多個介面,通過子類例項化之後,介面之間可以互相轉換

 

 

 

課時68 介面的定義與使用(介面使用限制)

 

1、介面裡只能有public許可權

 

以後編寫介面的時候,介面的方法上需要加上public

 

2、一個子類要繼承父類和多個介面的時候,要使用extends先,再跟上implements

 

 

3、一個抽象類可以使用多個implements繼承多個介面,介面不能繼承抽象類

 

 

三層繼承,以後經常會見到的操作形式

 

 

 

4、一個介面可以使用extends繼承多個父介面

 

 

5、介面可以定義一系列的內部介面,包括:內部普通類,內部抽象類,內部介面,其中使用static定義的介面

可以視為外部介面

 

課時69 介面的定義與使用(使用介面定義標準

 

介面可以表示一個標準

 

三大核心應用

1、定義操作標準

2、表示能力

3、在分散式開發中暴露遠端服務方法(設計的概念比較龐大)rest架構,必須會

 

 

介面是在類上的抽象

設計類之前先設計介面

 

課時70 介面的定義與使用(工廠設計模式)

(重要!!)

 

中間人,避免和物件直接接觸

主方法是客戶端,對於程式的修改不應該影響到客戶端的程式碼

 

interface IFruit {

       publicvoid eat() ;

}

 

class Apple implements IFruit {

       publicvoid eat() {

              System.out.println("吃蘋果");

       }

}

 

class Orange implements IFruit {

       publicvoid eat() {

              System.out.println("吃橘子");

       }

}

 

class Factory {

       //不需要factory產生例項化物件

       publicstatic IFruit getInstance(String cmd) {

              if("apple".equals(cmd)) {

                     returnnew Apple();

              }

              if("orange".equals(cmd)) {

                     returnnew Orange();

              }

              returnnull;

       }

}

 

public class TestDemo {

       publicstatic void main(String[] args) {

              if(args.length != 1) {

                     System.exit(1);

              }

              IFruitfruit = Factory.getInstance(args[0]);

              fruit.eat();

       }

}

 

介面,有子類,有工廠類,工廠類獲取子類物件

 

 

 

 

課時71 介面的定義與使用(代理設計模式)

必須學會

背誦結構!

Proxy

兩個子類共同實現一個介面,一個子類負責真實的業務實現,另外一個完成輔助真實主題的操作

 

介面:核心目的

子類1:核心實現

子類2:代理實現

 

子類2呼叫子類1

 

 

 

 

 

加上工廠模式

 

記住代理模式的結構

 

課時72 介面的定義與使用(抽象類與介面的區別)

 

優先選擇介面,開發

 

抽象類可以加普通方法

 

抽象類:

abstract class

抽象方法+普通方法+全域性常量+全域性變數+屬性+構造方法

可以使用各種許可權

子類使用extends繼承抽象類

一個抽象類可以實現若干個介面

單繼承

 

介面:

interface

抽象方法+全域性常量

只能選擇public許可權

子類利用implements繼承介面

一個介面不能繼承抽象類,但是可以通過extends繼承多個父介面

一個子類可以繼承多個介面

 

實際開發中,抽象類設計比介面複雜

要求掌握:定義介面+實現子類

 

結構體:

類,物件,抽象類,介面

 

 

現階段看見介面,先考慮建立子類

 

1、開發先考慮介面,避免但整合的侷限

 

 

課時73 匿名內部類

 

 

匿名類:抽象類和介面上實現

 

普通類也可以寫匿名內部類,但是不要使用,因為繼承要求都是抽象類

 

暫時不要話費過多精力在匿名內部類上

 

jdk1.8 匿名內部類有了改進

 

 

課時74 Object類(Object類簡介)

 

重要的操作類,java除了Object類之外都是有繼承關係的,預設繼承Object父類

 

以下兩種類的定義效果一致:

class Message {}

class Message extends Object{}

 

例子

 

 

開發過程中,Object類是引數的最高統一型別。

 

Object本身自帶的一些方法:

提供無參構造:所有的子類例項化的時候需要呼叫父類的無參構造

(必須把Object中的方法都掌握)

toString 取得物件資訊

equals 物件的比較

 

課時75 Object類(取得物件資訊)

 

直接輸出物件的時候是物件的地址編碼

 

 

預設輸出物件呼叫的就是toString方法

得到物件地址(所有物件都具有的特徵)

 

子類可以複寫toString方法

public String toString() {

}

 

toString的核心目的在於取得物件資訊。替換了簡單java類中的getInfo方法

 

 

String是作為資訊輸出的重要資料型別,所有的資料型別和String一起的時候,使用+號變為字串連結

而物件要變成字串,要使用toString方法

 

結論:字串是王道,都會向string轉型

 

課時76 Object類(物件比較)

 

使用equals()方法

String類中複寫了equals()

 

開發過程中,使用equals進行物件比較。

 

 

物件比較開發過程中比較少用

 

課時77 Object類(接收引用資料型別)

Object可以接受任意的物件

可以接受所有的引用資料型別(陣列,介面,類)

 

例子1:陣列

 

例子2:介面,Object接受介面物件是強制規定

 

引數統一

 

 

 

 

 

 

 

 

 

 

 

 

相關文章