第五章 面向對象(上)
這是閱讀李剛《瘋狂Java講義》後記錄的關鍵知識。用于補充自己的知識盲區,是以并不會面面俱到。
1.在學習繼承的時候了解到了一個新的概念:組合。組合和繼承都是了代碼的複用,不過組合需要構造更多對象,代碼量更大。它的優勢是降低了代碼的耦合性,在軟體維護階段優勢更突出。到底是該用組合還是繼承,一個最清晰的判斷方法就是問一問自己是否需要從新類向基類進行向上轉型,需要的話就用繼承,不需要的話就用組合方式。(後面有繼承群組合的代碼對比)
2.static修飾的成員不能通路不帶static修飾地成員
this關鍵字作為對象預設引用地兩種情形:
- 構造器中引用該構造器正在初始化的方法
- 在方法中引用調用該方法的對象 (this可省略)
static修飾的方法中不能使用this關鍵字
不要使用對象去調用static方法,應該使用類去調用。
3.java參數傳遞機制:值傳遞。例:swap函數,在Java中用數組實作或者新構造一個類,調用類的參數來實作,不能像c一樣直接實作。
4.形參個數可變的方法
public static void test(int a,String... books){
}
//或者 以數組形式
publi static void test(int a,String[] books){
}
//調用方法也不一樣
1. test(5,"資料結構","計算機網絡")
2. tset(5,new String[]{"資料結構","計算機網絡"})
5.方法在重載時不能依據方法的傳回類型來判斷,應該依據參數清單。
6.當父包中的類想要使用子包的類時,必須使用子包的完整包路徑加類名。
7.當引入的兩個類中都含有想引用的方法時必須寫出該類的全名
import java.util*/;
import java.sql*/;
java.sql.Date d=new java.sql.Date();
8.java常用包
- java.lang:包含核心類,如: String、Math、System、Thread (無需用import引入,系統自動引入)
- java.util:包含工具類/接口和集合架構類/接口 Arrays、List、Set
- java.net:網絡程式設計相關
- java.io:輸入輸出相關
9.一個構造器調用另一個構造器的例子
public class Apple{
public String name;
public String color;
public double weight;
public Apple(){}
public Apple(String name,String color){
this.name=name;
this.color=color;
}
public Apple(String name,String color,double weight){
this(name,color); //隻能作為第一條語句 使用this在後期維護更新時減少麻煩
this.weight=weight;
}
}
10.重載适用于方法,改變同一方法形參;重寫适用于父子類之間,子類改變父類的方法。
重寫遵守“兩同兩小一大”。
- 兩同:方法名相同,形參清單相同
- 兩小:子類方法傳回值類型小于或等于父類,子類方法抛出的異常小于等于父類
- 一大:子類方法通路的權限應大于等于父類
當子類的方法名與父類的方法名相同時,父類的方法被“隐藏”,隻能用super來調用
super不能出現在被static修飾的類裡。
向上轉型執行個體:
class Parent{
public String tag="資料結構";
}
class Derived extends Parent{
private String tag="計算機網絡";
}
public class HideTest{
public void static main(String[] args){
var d=new Derived();
//Dervide的tag是私有的 不能通路,隻能向上轉型通路Parent的
System.out.println(((Parent) d).tag);
}
}
11.多态:編譯時類型和運作時類型不一緻。
編譯時 是BaseClass ,運作時則是SubClass。
調用子類和父類都有的方法時,會調用子類覆寫的方法。
若調用子類有而父類沒有的方法時則會報錯,因為沒有完成編譯。
對象的執行個體變量不會發生多态,隻有方法能。會輸出編譯時(即父類)的變量。
強制轉換類型時,兩個類型之間需要存在繼承關系
強制轉換,精度高的範圍廣的轉換為精度低的範圍小的。
可用instanceof在判斷是否可以轉換成功,來增強程式的健壯性。
if (int instanceof String){
var str=(String) int;
}
将子類的對象給父類引用變量時叫“向上轉型”。
12.繼承與複用的對比
//繼承
class Animal{
public void beat(){
System.out.println("心髒跳動...")
}
public void breathe(){
System.out.printlin("呼吸...")
}
}
class Bird extends Animal{
public void fly(){
System.out.println("起飛,唉,起飛")
}
}
class Wolf extends Animal{
public void run(){
System.out.println("溜了溜了...")
}
}
public class Test1{
public static void main (String[] args){
var b=new Bird();
b.breathe();
b.fly();
var w=new Wolf();
w.breathe();
w.run();
}
}
//組合
class Animal{
public void beat(){
System.out.println("心髒跳動...")
}
public void breathe(){
System.out.printlin("呼吸...")
}
}
class Bird {
public Bird(Animal a){
this.a=a;
}
public void breathe(){
a.breathe();
}
public void fly(){
System.out.println("起飛,唉,起飛")
}
}
class Wolf {
public Wolf(Animal a){
this.a=a;
}
public void breathe(){
a.breathe();
}
public void run(){
System.out.println("溜了溜了...")
}
}
public class Test2{
public static void main (String[] args){
var a1=new Animal();
var b=new Bird(al);
b.breathe();
b.fly();
var a2=new Animal();
var w=new Wolf(a2);
w.breathe();
w.run();
}
}
13.static 修飾的代碼塊永遠最先執行,順序是頂層父類——>父類——>子類;然後執行執行個體代碼塊和構造器,順序是頂層父類——>父類——>子類。