【筆記】阿里雲大學Java物件導向開發課程筆記01-77課時
課時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接受介面物件是強制規定
引數統一
相關文章
- Java課堂筆記(二):物件導向Java筆記物件
- 機器學習課程筆記機器學習筆記
- 物件導向筆記物件筆記
- (Java筆記)物件導向基礎Java筆記物件
- 哈佛大學公正課-筆記筆記
- 史丹佛大學凸優化課程筆記-0優化筆記
- python課程筆記Python筆記
- Java相關課程系列筆記之一Java學習筆記Java筆記
- 北航OS課程筆記--二、系統引導筆記
- 會計學課程筆記筆記
- 王道C短期課程筆記筆記
- 物聯網課程筆記筆記
- lua課程學習筆記筆記
- React簡書開發實戰課程筆記——4React筆記
- DApp設計與開發 課程筆記(一)APP筆記
- 侯捷C++物件導向高階開發筆記C++物件筆記
- Go 筆記之物件導向Go筆記物件
- Python 物件導向筆記Python物件筆記
- 達內課程學習筆記筆記
- 萬物互聯課程筆記筆記
- Stanford機器學習課程筆記——SVM機器學習筆記
- UI設計課程筆記(三)UI筆記
- [Triton課程筆記] 2.2.3 BLS續筆記
- 北航OS課程筆記--三、記憶體管理筆記記憶體
- 老王的JAVA基礎課:第5課 物件導向Java物件
- 網站SEO課程筆記整理版!網站筆記
- 遨遊Unix–APUE課程筆記【1】筆記
- 資料庫課程作業筆記資料庫筆記
- Python基礎課程筆記5Python筆記
- Andrew ng 深度學習課程筆記深度學習筆記
- 遨遊Unix — APUE課程筆記【2】筆記
- 龍哥盟-PMP-課程筆記-四-筆記
- 龍哥盟-PMP-課程筆記-三-筆記
- 龍哥盟-PMP-課程筆記-十九-筆記
- 北航OS課程筆記--一、緒論筆記
- 北航OS課程筆記--六、磁碟管理筆記
- 計算機網路 - 課程筆記計算機網路筆記
- 《大學生就業指導》第一課:就業決策 筆記就業筆記