java學習筆記(Core Java)5 繼承

來源:互聯網
上載者:User

標籤:java學習筆記   拷貝   size   特徵   enum   arraylist   動態   執行個體   integer   

第五章 繼承

1. 類 超類 子類
繼承:extends (所有繼承嗾使公有繼承,沒有私人繼承和保護繼承)
c+++: 用:

2.使用super(c#使用Base)調用基類的方法
子類構造器會預設調用基類的無參構造來初始化基類的私人域
如果基類沒有無參構造,則會報錯

3.this :1.引用隱式傳參 2.調用類其他構造器
super:1.調用超類的方法 2.調用超類的構造器

c++使用初始化列表來調用基類的建構函式

4.java中,不需要將方法聲明為虛擬方法方法,基類指標指向不同對象時,虛擬指標知道指標指向的實際物件類型,所以能正確調用對應的方法

如果不希望讓一個方法具有虛擬特徵,可以標記為final

5.java不支援多繼承
6.多態:動態綁定、靜態繫結和方法表
1)編譯器準確知道調用哪個方法的叫靜態繫結
(用private、static、final聲明過的方法)
在運行時,調用方法依賴於實際類型並實現方法綁定(運行時可知)的叫動態綁定

虛擬機器為基類和衍生類別產生一個方法表,虛擬機器會在方法表中搜尋最適合的方法進行調用

動態綁定的優點就是:對程式進行拓展時,不需要重新對調用方法的代碼進行重新編譯

方法重寫時,子類的方法的訪問性不能低於基類方法

7.阻止繼承 final類
final修飾的類不能被繼承
final修飾的方法不能被覆蓋
final修飾的域在構造方法內初始化,並且不能被改動

被final修飾的類,其方法自動為final方法,但而不包括域

動態綁定對系統開銷很大,所以即時編譯器會自動為沒有被覆蓋的類標記為內嵌函式,減少對系統的開銷

8.強制轉換
1)只能在繼承層次內進行轉換
2)將基類轉換為子類之後,需判斷是否轉換成功 使用instanceof運算子算符檢查
Employee[] staff = new Employee[3];
java:Manager boss = (Manager)staff[1];
if(staff[1] instanceof Manager)//instanceof執行個體是否屬於該類
...
c++: Manager* boss= dynamic_cast<Manager*>(staff[1])
if(boss!= null)
...

如果轉換失敗java不會產生一個Null 物件,而是拋出一個異常

補充: c++四種強制類型轉換,所以c++不是型別安全的
static_cast:基礎資料型別 (Elementary Data Type)轉換
const_cast:常量轉化為非常量,或者反過來
reinterpret_cast:任意類型轉換而無須考慮安全和常量問題,不要輕易使用
dynamic_cast:運行時轉換,運行時要進行類型檢查,存在繼承關係之間(類中要有虛函數才能進行此轉換,需檢查類型資訊,而類型資訊儲存在虛函數表中)
9.抽象類別與抽象方法
抽象類別包含抽象方法也可以包含具體資料、具體方法
類即時不含有抽象方法,也可以聲明為抽象類別
抽象類別不能被執行個體化

c++:尾部=0的方法為純虛函數,包含虛函數的類為虛類(抽象類別) (虛函數可以有自己的實現,純虛函數=0)

10.存取權限:
private:本類可見(也是c++初始化列表的原因,因為子類不可方位基類的private欄位,需要調用基類的建構函式)

public:對所有類可見
protected:本包和所有子類可見(c++只對子類可見)
預設(無修飾符):對本包可見

11.object 超類
在java中,只有基本類型不是對象,其他類型(包括數組,枚舉)都是對象,都擴充於超類

c++:void* ,每個指標都可以轉化為void*指標

12.equal 僅比較了是否具有相同的引用
最好手動的重寫equal方法

重寫equals方法的要求:
1.自反性:對於任何非Null 參考x,x.equals(x)應該返回true
2.對稱性:對於任何引用x和y,如果x.equals(y)返回true,那麼y.equals(x)也應該返回true。
3.傳遞性:對於任何引用x、y和z,如果x.equals(y)返回true,y.equals(z)返回true,那麼x.equals(z)也應該返回true。
4.一致性:如果x和y引用的對象沒有發生變化,那麼反覆調用x.equals(y)應該返回同樣的結果。
5.非空性:對於任意非Null 參考x,x.equals(null)應該返回false。

重寫equals方法的要點:(注意! 重寫該方法)
@overrade public boolean equal(OBject otherObject)
1. 使用==操作符檢查“實參是否為指向對象的同一個引用”。
if(this == otherObject)
2.判斷實參是否為null
if(otherObject == null)
3. 使用instanceof操作符檢查“實參是否來自是否同一個類”。
if(getClass()!= otherObject.getClass()) //是否同一個類
if(!(otherObject)instanceof ClassName)//如果所有子類擁有統一的語義
4. 把實參轉換到正確的類型。
ClassName other = (ClassName)otherObject

5.對所有域依次比較:對於該類中每一個“關鍵”域,檢查實參中的域與當前對象中對應的域值是否匹配。對於既不是float也不是double類型的基本類型的域,可以使用==操作符進行比較;對於對象參考型別的域,可以遞迴地調用所引用的對象的equals方法;對於float類型的域,先使用Float.floatToIntBits轉換成int類型的值,然後使用==操作符比較int類型的值;對於double類型的域,先使用 Double.doubleToLongBits轉換成long類型的值,然後使用==操作符比較long類型的值。

6.當你編寫完成了equals方法之後,應該問自己三個問題:它是否是對稱的、傳遞的、一致的?(其他兩個特性通常會自行滿足)如果答案是否定的,那麼請找到這些特性未能滿足的原因,再修改equals方法的代碼。

數組可以使用Arrays.equal來判斷
////////////////////////////
java.util.Arrays
static Boolean equal(type[] a,type[] b);
static Boolean equal(object a,object b);
////////////////////////////

13.hashCode
每個類都有一個散列碼
如果重寫equal,也需要重寫hashCode

14.toString 強烈建議自己的類重寫提String方法,用於列印日誌或者錯誤資訊 例如:
public String toString()
{
return getClass().getClass
+ "[name=" + name
+ "age=" + age
+ "]";
}

println會直接調用x.toString方法

數組需要調用Arrays.toString方法
多維陣列調用Arrays.deepString方法

/////////////////////////
java.lang.Object
Calss getClass() //返回包含對象資訊的類對象
boolean equal()
String toString();

java.lang.Class
String getName();
Class getSuperclass() //返回超類資訊
/////////////////////////

15.泛型數組 ArrayList<T> array = new ArrayList<T>()
1)c++:類似於vector,但是沒有重載[]。再c++中,列表a=b時一種值拷貝,而在java中,a=b則a,b指向同一個列表

(1)add()
add(int index, T obj) //需要移動大量元素
(2)ensureCapacity(100) //如果可以估計儲存數量,可以再填充前分配一個這麼大的內部//數組空間
(3)size == 數組a.length()
(4)trimToSize() //如果確認列表大小不再增大,可以調用該方法清除多餘的空間

5)set/get :由於沒有重載[]運算子。。。。
set(int iT obj);//替換某個位置上的某個值(不是增加!)
T get(int i); //返回object,擷取後需要強制轉換
6)T remove(int index) //需要移動大量元素
7) x [] = new x[list.size()]
list.toArray(x) //匯入數組
曆史遺留問題:
ArrayList list=employee.find(oldlist)//參數列表元素可能有些不相符
由於早期ArrayList沒有泛型,所以將一個原始的ArrayList賦值一個類型化的ArrayList會有警告,只要確保不會造成後果,可以使用@SuppressWarning("unchecked"),關閉此條警告

16拆箱與裝箱
每個基本類型都有之對應的類(對象封裝類)
Integer Long Float Double Short Byte Character Void Boolean(前六種繼承Number類)

對象封裝類不允許修改其中的值,同時也是final聲明的
使用封裝器聲明變數時,其==表示其是否指向同一個對象,因此
兩個對象封裝器比較時調用equal方法

17.java如何改變傳參的值??
C++:指標傳參,引用傳參 c#:使用 ref 標記實參與形參
java 使用持有人類型(IntHolder、BooleanHold等)
public static void triple(IntHolder x)
{
x.value = 3 * x.value; //可以改變傳參的值
}

關於c++引用:
引用其實就是一個常量指標,同時也是用常量指標去實現的。引用佔用四個位元組。因為是常量指標,所以不能修改被引用的對象的內容。這比使用指標將更加安全

/////////////////////////////
java.lang.Integer
int intValue();//返回interger中的值
static String toString(int i);//將int封裝為十進位String
static String toString(int i,int radix);//指定進位
static int parseInt(String s) //c# int.prase(String s)
static int parseInt(String s,int radix)
static Integer valueOf(String s)
static Integer valueOf(String s,int radix)

java.text.Number.Format
Number prase(String s); //假設s時一個數值
/////////////////////////////

18.可變參數 使用...
public static double max(double... value);
實際上將若干參數綁定在數組中傳遞該max函數
public static void main(String... args);

19.枚舉 enum
實際上是一個類,包含若干個執行個體,因此兩個枚舉類型的值比較,直接使用 == ,永遠不要調用equal。
所有的枚舉類型都是Enum類的子類。所以他們繼承了這個類的許多方法String toString() //返回枚舉常量名
static Enum valueOf(Class enumClass,String name)//返回指定名字給定類的枚舉常量
int ordinal() //返回在enum聲明中枚舉常量的索引 (從0 開始)
int compareTo(E other) //在枚舉中的順序比較

20反射與反射庫
反射被大量用在javaBeans中。
反射的作用:
①在運行中分析類的能力
②在運行在查看類的對象
③實現通過的數組作業碼
④利用Method對象。 特別C++像函數指標(C#,委託與事件)
極其強大的構造工具!!!

(1)Class類
程式運行時,java運行系統始終為所有的對象維護一個被稱為運行時的類型標識,這個資訊跟蹤著每個對象所屬的類,虛擬機器會利用運行時的類型資訊選擇相應的方法執行.Class類負責維護這些資訊,每一個java類在虛擬機器種都會表現出一個Class類 (這與Object中的getClass 返回類的執行個體容易混肴)

Employee e;
e.getName();//返回一個Class對象

e.getClass().getName();//返回類的名字

如果類在包裡,在返回 包名+執行個體名
Data d = new Data();
Class c = d.getClass();
String name = c.getName(); // java.util.Data

使用靜態方法forName擷取類名對應的Class對象
String classname = "java.util.Data";
Class c = forName(classname);//該方法只有在classname時類名或者介面名中使用,否則會拋出異常 checked exception.使用該方法需要提供一個異常處理器

(可以先啟動程式,然後使用forName載入所有的類,給使用者一種啟動很快的幻覺)

使用T.class方法擷取匹配的類對象(T代表任意java類型)
Class c1 = Data.class
Class c2 = int.class
Class c3 = double[].class//曆史原因,數組會返回一個比較奇怪的類名

總結:
三種方法擷取Class類對象
執行個體名.getClass
任意類型T.class
forName(類名字串)//這是一個靜態方法 Class.forName(s);

Class Poin(){...}
Point p = new Point();
Class c1 = p.getClaa();
System.out.println(c1.getName()) // Point

Class c2 = Class.forName("Point")
System.out.println(c2.getName()) // Point

Class c3 = Point.class;
System.out.println(c3.getName()) // Point

每一個類的對象在虛擬機器中都會產生一個Class類對象來儲存這個每個類的資訊,可以擷取到這些資訊進而擷取到這個類的所有資訊。
虛擬機器為每一個類型管理一個Class對象,
可以用 == 比較兩個類對象 if(e.getClass() == Employee.class) ...
擷取執行個體後也可以反射建立對象 e.getClass().newInstance();
newInstance() 會調預設的構造方法,如果沒有,將拋出異常

forName與newInstance() 根據類名產生對象
String s = "java.util,Data";
Data d = (Data)Class.forName(s).newINstance();

Constructor類中的newInstance()//提供構造器參數

////////////////////////////
使用printStackTrace列印出棧的軌跡
java.lang,Class
static Class forName(String classname);
Object newInstance();

java.lang,reflect.Constructon
Object newInstance(Object[] args);//帶參構造
////////////////////////////

 

java學習筆記(Core Java)5 繼承

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.