《JAVA編程思想》第五、六、七、八章總結

第五章

1.構造器是什麼?

構造函數(構造器)是一種特殊的函數。其主要功能是用來在創建對象時初始化對象, 即爲對象成員變量賦初始值,總與new運算符一起使用在創建對象的語句中。構造函數與類名相同,沒有返回值,但不能聲明void,訪問權限可以爲任意,但是一般情況下使用public方法權限,構造方法中的參數可以根據需要自行定義,可重載多個不同的構造函數。在JAVA語言中,構造函數與C++語言中的構造函數相同,JAVA語言中普遍稱之爲構造方法。

2.重載和重寫有什麼區別?

重載(overloading):在同一個類中同名函數,具有不同參數個數和類型(返回值不參與),是一個類中多態性的體現。是由靜態類型確定,在類加載的時候就已經確定了,屬於靜態綁定。(當子類和父類存在同一個方法時,子類重寫父類方法時,程序在運行時調用的方法時,是調用父類(接口)的方法呢?還是調用子類的方法呢?我們將確定這種調用何種方法的操作稱之爲綁定。)

重寫(overriding):子類中含有與父類中相同的名字、返回值類型和參數表的方法,則是重寫。是在繼承中體現多態性,屬於動態綁定。

方法的重載和重寫都是實現多態的方式,區別在於前者實現的是編譯時的多態,後者實現的是運行時的多態。

3.this 和super關鍵字

this:

this 是自身的一個對象,代表對象本身,可以理解爲:指向對象本身的一個指針

this 的用法在 Java 中大體可以分爲3種:

1.普通的直接引用

這種就不用講了,this 相當於是指向當前對象本身。

2.形參與成員名字重名,用 this 來區分:

class Person {
    private int age = 10;
    public Person(){
    System.out.println("初始化年齡:"+age);
}
    public int GetAge(int age){
        this.age = age;
        return this.age;
    }
}
 
public class test1 {
    public static void main(String[] args) {
        Person Harry = new Person();
        System.out.println("Harry's age is "+Harry.GetAge(12));
    }
}

可以看到,這裏 age 是 GetAge 成員方法的形參,this.age 是 Person 類的成員變量。

super

super 可以理解爲是指向自己超(父)類對象的一個指針,而這個超類指的是離自己最近的一個父類

super 也有三種用法:

1.普通的直接引用

與 this 類似,super 相當於是指向當前對象的父類,這樣就可以用 super.xxx 來引用父類的成員。

2.子類中的成員變量或方法與父類中的成員變量或方法同名

class Country {
    String name;
    void value() {
       name = "China";
    }
}
  
class City extends Country {
    String name;
    void value() {
    name = "Shanghai";
    super.value();      //調用父類的方法
    System.out.println(name);
    System.out.println(super.name);
    }
  
    public static void main(String[] args) {
       City c=new City();
       c.value();
       }
}

可以看到,這裏既調用了父類的方法,也調用了父類的變量。若不調用父類方法 value(),只調用父類變量 name 的話,則父類 name 值爲默認值 null。

3.引用構造函數

  • super(參數):調用父類中的某一個構造函數(應該爲構造函數中的第一條語句)。
  • this(參數):調用本類中另一種形式的構造函數(應該爲構造函數中的第一條語句)。
class Person { 
    public static void prt(String s) { 
       System.out.println(s); 
    } 
   
    Person() { 
       prt("父類·無參數構造方法: "+"A Person."); 
    }//構造方法(1) 
    
    Person(String name) { 
       prt("父類·含一個參數的構造方法: "+"A person's name is " + name); 
    }//構造方法(2) 
} 
    
public class Chinese extends Person { 
    Chinese() { 
       super(); // 調用父類構造方法(1) 
       prt("子類·調用父類"無參數構造方法": "+"A chinese coder."); 
    } 
    
    Chinese(String name) { 
       super(name);// 調用父類具有相同形參的構造方法(2) 
       prt("子類·調用父類"含一個參數的構造方法": "+"his name is " + name); 
    } 
    
    Chinese(String name, int age) { 
       this(name);// 調用具有相同形參的構造方法(3) 
       prt("子類:調用子類具有相同形參的構造方法:his age is " + age); 
    } 
    
    public static void main(String[] args) { 
       Chinese cn = new Chinese(); 
       cn = new Chinese("codersai"); 
       cn = new Chinese("codersai", 18); 
    } 
}

從本例可以看到,可以用 super 和 this 分別調用父類的構造方法和本類中其他形式的構造方法。

例子中 Chinese 類第三種構造方法調用的是本類中第二種構造方法,而第二種構造方法是調用父類的,因此也要先調用父類的構造方法,再調用本類中第二種,最後是重寫第三種構造方法。

從本質上講,this 是一個指向本對象的指針, 然而 super 是一個 Java 關鍵字

 

4.初始化順序

正常類的加載順序:靜態變量/靜態代碼塊 -> main方法 -> 非靜態變量/代碼塊 -> 構造方法

如果是繼承關係的子類初始化順序:

父類–靜態變量/父類–靜態初始化塊
子類–靜態變量/子類–靜態初始化塊
父類–變量/父類–初始化塊
父類–構造器
子類–變量/子類–初始化塊
子類–構造器

第六章

1.JAVA中的權限關鍵字

第七章

1.組合和繼承的區別,如何選擇使用?

組合:其實一開始就接觸了但不知道這就叫組合,本質就是類的複用。我們創建一個類A,之後再創建一個新的類B,在B類中通過創建A類對象,來調用A類方法。

下面通過具體的例子來展示如何使用:

public class People {
    private String name;
    private int age;
    
    public void setName(String name){
        this.name = name;
    }
    public String getName(){
        return this.name;
    }
    public int getAge(){
        return this.age;
    }
    public void setAge(int age){
        this.age = age;
    }
}
class Student {
    People people = new People();
}

這裏的Student類就是運用了組合。

繼承:這個很熟悉了,直接貼用法

public class Student extends People{
    //doSomething
}

總結一下:

組合:只需在新的類中產生現有類的對象。新的類是由現有類的對象所組成的。
繼承:按照現有類的類型來創建新類,無需改變現有類的形式,並且在其中添加新的代碼。

區別:組合是顯示地允許在新類中放置子對象,而繼承是隱性的這樣做。

 

選擇使用問題:

從語言的邏輯上看,繼承(extend)更應該用於包含關係(sth is a sth_baby),而組合可以是並列或者說共有的關係(sth has a sth_baby)。

2.final關鍵字總結

final關鍵字可以修飾變量、方法和類。

1.用來修飾數據:包括成員變量和局部變量,該變量只能被賦值一次且它的值無法被改變。對於成員變量來講,修飾的類變量,必須在聲明時初始化;修飾的實例變量,必須在聲明時或者構造方法中對它賦值。對於基本數據類型,final會使得數值不變;而對於引用類型,final會使得引用指向的對象不變。
2.用來修飾方法:第一個原因表示該方法無法被重寫,防止繼承的子類去修改該方法;第二個原因是效率。

tips:類中所有private方法都隱式地使用了final關鍵字。

3修飾類:表示該類無法被繼承

第八章

1.爲什麼要有多態的存在?

個人簡單的理解:父類型的引用指向子類型的對象。使用多態有兩個好處:

1. 應用程序不必爲每一個派生類編寫功能調用,只需要對抽象基類進行處理即可。大大提高程序的可複用性。 
2. 派生類的功能可以被基類的方法或引用變量所調用,這叫向後兼容,可以提高可擴充性和可維護性。 

多態可以用在方法的參數中和方法的返回類型中。

舉個例子:


package stduy;
 
abstract  class Animal{
	abstract void eat();
}
 
class Dog extends Animal{
	public void eat() {
		System.out.println("啃骨頭!");
	}
	public void LookHome() {
		System.out.println("看家!");
	}
}
 
class Cat extends Animal{
	public void eat() {
		System.out.println("吃魚!");
	}
	public void catchMouse() {
		System.out.println("抓老鼠!");
	}
}
 
public class Main{
	
	public static void main(String[] args) {
			Dog dog = new Dog();
			
			dog.eat();
			dog.LookHome();
			
			Cat cat = new Cat();
			cat.eat();
			cat.catchMouse();
	}
	
}

這裏主方法分別去調用各個子類的eat方法就很麻煩,我們這裏就可以使用多態。


public class Main{
	
	public static void main(String[] args) {
		
			Dog dog = new Dog();		
			Cat cat = new Cat();
			
			method(dog);
			method(cat);
	}
	public static void method(Animal a) {
		a.eat();
	}

}

 

2.向上轉型和向下轉型是什麼,爲什麼要用它們?

向上轉型和向下轉型都非常抽象,需要舉例說明:


class Father {
	String name = "爸爸";
	public void sleep() {//睡覺方法
		System.out.println(name + "睡覺");
	}
}
/**
 * 子類繼承父類
 */
class Son extends Father {
	String name = "兒子";
	public void p() {//調皮方法
		System.out.println(name + "調皮");
	}

我們先建立一堆父子類。


public class UpAndDown {
	public static void main(String[] args) {
		// 向上轉型:將父類引用指向子類對象
		Father f = new Son();
		f.sleep();//輸出“爸爸睡覺”
      
        //如果f.p();編譯出錯,不可執行。因爲p()不是Father的方法。
	}
}

很明顯,上面的就是向上轉型,將子類轉型成父類,此時子類特有的p()方法就無法調用,但這樣做,方便我統一控制多個子類。


public class UpAndDown {
	public static void main(String[] args) {
		// 向下轉型
		Father f = new Son();
		((Son)f).P();//輸出“兒子調皮”
	}
}

上面就是向下轉型,將向上轉型的子類再向下轉型,這樣原本子類特有的方法p()就可以使用了。


public class UpAndDown {
	public static void main(String[] args) {
		// 直接向下轉型
		Father f = new Father();
        f.sleep();//輸出“爸爸睡覺”
		((Son)f).P();//報錯!!!!!!!!!!
	}

}

但如果我寫成以上的向下轉型就不行,因爲他在創建對象時創建的就是父類對象,根本就不包含子類特有的方法,無法下轉。所以下轉的前提是你本來就有,只不過由於向上轉型失去了,然後通過下轉再次恢復。

爲什麼要用它們

向上轉型:這個好理解java的繼承,多態. 利於程序擴展。這種設計方式,會讓你寫出更易維護,簡潔的代碼。

但向下轉型就有點難以理解了,爲什麼我要先上轉再下轉,多這一步呢,我子類引用指向新建的一個子類對象不就好了?

這篇博客寫的很詳細:

https://blog.csdn.net/xyh269/article/details/52231944

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章