Java 第五天 筆記
1 垃圾回收機制
(1)程式設計師無權呼叫垃圾回收器
(2) 收集並刪除未引用的物件。可以通過呼叫"System.gc()"來觸發垃圾回收,但並不保證會確實進行垃圾回收。JVM的垃圾回收只收集哪些由new關鍵字建立的物件。所以,如果不是用new建立的物件,你可以使用finalize函式來執行清理。
2 建構函式
(1)構造方法的作用:
構造方法作用:對物件進行初始化.
建構函式與普通函式的區別:
(1). 一般函式是用於定義物件應該具備的功能。而建構函式定義的是,物件在呼叫功能之前,在建立時,應該具備的一些內容。也就是物件的初始化內容。
(2). 建構函式是在物件建立時由jvm呼叫, 給物件初始化。一般函式是物件建立後,當物件呼叫該功能時才會執行。
(3). 普通函式可以使用物件多次呼叫,建構函式就在建立物件時呼叫。
(4). 建構函式的函式名要與類名一樣,而普通的函式只要符合識別符號的命名規則即可。
(5). 建構函式沒有返回值型別。
建構函式要注意的細節:
(1). 當類中沒有定義建構函式時,系統會指定給該類加上一個空引數的建構函式。這個是類中預設的建構函式。當類中如果自定義了建構函式,這時預設的建構函式就沒有了。
備註:可以通過javap命令驗證。
(2).在一個類中可以定義多個建構函式,以進行不同的初始化。多個建構函式存在於類中,是以過載的形式體現的。因為建構函式的名稱都相同。
.構造程式碼塊:
構造程式碼塊作用:給所有的物件進行統一的初始化。 具體作用:
1:給物件進行初始化。物件一建立就執行並且優先於建構函式。
2:與建構函式區別
A:構造程式碼塊和建構函式的區別,構造程式碼塊是給所有物件進行統一初始化, 建構函式給對應的物件初始化。
B:構造程式碼塊的作用:它的作用就是將所有構造方法中公共的資訊進行抽取。
3 過載
A 方法的過載是指一個類中可以定義名字相同但是引數不同的方法。呼叫時,會根據不同的引數來呼叫對應的函式
B: 兩同三不同:
同一個類,同一個方法名,
不同是 :引數列表不同(型別,個數,順序)
只有返還值不同不構成方法的過載()如 int a(String sgtr){} ,void a(String i){}
只有形參的名稱不同,不構成方法的過載
與普通方法一樣。構造方法也可以過載
4 static 關鍵字(非靜態可以呼叫靜態的,但是靜態的不可以呼叫非靜態的)
在類中 用static 關鍵字宣告的成員變數為靜態變數,或者叫做類屬性,類變數
:它是該類的公用變數,屬於類,被該類的所有例項共享,在類被載入時被顯示初始化,,對於該類的所有物件來說,static成員變數只有一份。該類的所有物件共享!可以使用物件類屬性來呼叫。不過一般都是使用類名。類屬性。static變數至於方法區中。
用static宣告方法為靜態方法:不需要物件就可以通過(類名.方法名)呼叫。在呼叫該方法時,不會將物件的引用傳遞給它,所以在static方法中不可以訪問非static 成員。
5 this關鍵字(常用於構造方法中(且在一個構造方法中呼叫另一個建構函式時this(也可以還有引數):必須在這個構造器的第一行),初始化變數,和set和get方法中)
public Student02(String name,int id){
this(); //必須位於第一行
this.name = name; //this.name代指當前物件
this.id = id;
}
public Student02(){
System.out.println("構造一個物件");
}
在普通方法中this總是指向呼叫該方法的物件;在建構函式中this總是指向正要初始化的物件;this不能用於static方法。
6 面向物件三大特徵
A:繼承:類是對物件的抽象,繼承是對某一批類的抽象,從而實現對現實世界更好的建模。;提高程式碼的複用性!;extends關鍵字的意思是擴充套件,子類是父類的擴充套件。
子類繼承父類,可以得到父類的全部屬性和方法(除了父類構造方法)。Java中只有單繼承(一個類只有一個直接父類),沒有多繼承。多繼承會引起混亂,使得繼承鏈過於複雜,系統難於維護。Java的多繼承可以通過介面來實現,,如果定義一個類時,沒有呼叫extends,則它的父類是:Java.lang.Object。不同的說法:超類,父類,子類,派生類。
public class Animal {
String eye;
public void run(){
System.out.println("跑");
}
public void eat(){
System.out.println("吃");
}
public void sleep(){
System.out.println("睡");
}
}
class Mammal extends Animal{
public void taiSheng(){
System.out.println("胎生");
}
}
class Paxing extends Animal{ //
public void eggSheng(){
System.out.println("卵生");
}
}
class Bird extends Animal{
public void run(){ //重寫父類方法(重寫後覆蓋父類方法)
super.run(); //super呼叫父類的方法
System.out.println("飛");
}
public void eggSheng(){
System.out.println("卵生");
}
}
繼承涉及的方法重寫:在子類中可以根據需要對從父類繼承的方法進行重寫。重寫的方法必須和被重寫的方法具有相同的方法名稱,引數列表和返回值型別。,重寫方法不能使用比被重寫方法更嚴格的訪問許可權。(由於多型)
Object類: 該類是所有Java類的根基類
如果在類中宣告中未使用extends關鍵字指明其基類那麼該類的基類預設為Object類
public class People{ } 預設繼承 public class People extends Object{}
重寫:toString方法:預設返回:包名+類名[email protected]+雜湊碼(根據物件記憶體位置生成,唯一不重複)。 可以重寫
封裝
在面向物件程式設計方法中,封裝(英語:Encapsulation)是指一種將抽象性函式介面的實現細節部份包裝、隱藏起來的方法。封裝可以被認為是一個保護屏障,防止該類的程式碼和資料被外部類定義的程式碼隨機訪問。要訪問該類的程式碼和資料,必須通過嚴格的介面控制。封裝最主要的功能在於我們能修改自己的實現程式碼,而不用修改那些呼叫我們程式碼的程式片段。適當的封裝可以讓程式碼更容易理解與維護,也加強了程式碼的安全性。
封裝的優點
-
1. 良好的封裝能夠減少耦合。
-
2. 類內部的結構可以自由修改。
-
3. 可以對成員變數進行更精確的控制。
-
4. 隱藏資訊,實現細節。
實現Java封裝的步驟
1. 修改屬性的可見性來限制對屬性的訪問(一般限制為private),例如
public class Person { private String name; private int age; }這段程式碼中,將 name 和 age 屬性設定為私有的,只能本類才能訪問,其他類都訪問不了,如此就對資訊進行了隱藏
2. 對每個值屬性提供對外的公共方法訪問,也就是建立一對賦取值方法,用於對私有屬性的訪問,例如:
public class Person{
private String name; private int age;
public int getAge(){
return age;
}
public String getName(){
return name;
}
public void setAge(int age){
this.age = age;
}
public void setName(String name){
this.name = name;
}
}
以上例項中public方法是外部類訪問該類成員變數的入口。通常情況下,這些方法被稱為getter和setter方法。因此,任何要訪問類中私有成員變數的類都要通過這些getter和setter方法。
Java public private protected
(1)訪問許可權修飾符修飾成員變數和方法
public:表明該成員變數和方法是共有的,能在任何情況下被訪問。
protected:必須在同一包中才能被訪問,但是對於子類來說即使不同包的子類也可以訪問。
default:預設可以在同一個類,同一個包中訪問
private:只能在本類中訪問。
實際上,把重要的資料修飾為private,然後寫一個public的函式訪問它,正好體現了OOP的封裝特性,是OOP安全性的體現。
(2)訪問許可權修飾符修飾類
不能用protected和private修飾類
多型 :簡單的理解就是事物的多種形態。專業的術語說就是:同一個實現介面,使用不同的例項而執行不同的操作。
package zyl.oop.duotai;
public class Animal {
String string;
public void voice(){
System.out.println("普通動物叫聲");
}
}
class Cat extends Animal{
public void voice(){
System.out.println("喵喵");
}
}
class Dog extends Animal{
public void voice(){
System.out.println("旺旺");
}
}
class Pig extends Animal{
public void voice(){
System.out.println("哼哼");
}
}
package zyl.oop.duotai;
public class Test {
public static void testvoice(Animal a){
a.voice();
}
// public static void testvoice(Cat c){
// c.voice();
// }
// public static void testvoice(Dog d){
// d.voice();
// }
// public static void testvoice(Pig p){
// p.voice();
// }
public static void main(String[] args) {
// Cat c = new Cat();
// Animal a = c;
Animal a = new Cat();//父類的引用指向一個子類物件 構成多型
testvoice(a);
Animal b = new Dog();
testvoice(b);
Animal c = new Pig();
testvoice(c);
}
}
結果 :喵喵
旺旺
哼哼
從上面的程式碼可以看出我們在傳一個Cat Dog等類物件的時候,我們進行了一個子類到父類的轉換(向上轉型),這時候呼叫testvoice(a),testvoice(b)testvoice(c)方法不是呼叫的父類的,而是指向子類的。
子類轉換父類的規則
1.將一個父類的引用指向一個子類物件時,稱向上轉型,自動進行型別轉換。
2.此時通過父類引用變數呼叫的方法是子類覆蓋或繼承父類的方法,不是父類的方法。
3.父類無法呼叫子類特有的資料。
結論
1.繼承的存在(無繼承,無多型,繼承是多型的基礎)
2.子類要重寫父類的方法(多型下呼叫子類重寫後的方法)
3.父類引用變數指向子類物件(子類到父類的型別轉換)