Java继承、重写与重载 笔记
1. Java繼承
繼承要符合的關系是:is-a,父類更通用,子類更具體.
1.1 繼承的特性
- 子類擁有父類非private的屬性,方法。
- 子類可以擁有自己的屬性和方法,即子類可以對父類進行擴展。
- 子類可以用自己的方式實現父類的方法。
- Java的繼承是單繼承,但是可以多重繼承,單繼承就是一個子類只能繼承一個父類,多重繼承就是,例如A類繼承B類,B類繼承C類,所以按照關系就是C類是B類的父類,B類是A類的父類,這是java繼承區別于C++繼承的一個特性。
- 提高了類之間的耦合性(繼承的缺點,耦合度高就會造成代碼之間的聯系)。
1.2 繼承關鍵字
繼承可以使用 extends 和 implements 這兩個關鍵字來實現繼承,而且所有的類都是繼承于 java.lang.Object,當一個類沒有繼承的兩個關鍵字,則默認繼承object(這個類在 java.lang 包中,所以不需要 import)祖先類。
- 在 Java 中,類的繼承是單一繼承,也就是說,一個子類只能擁有一個父類,所以 extends 只能繼承一個類。
- 使用 implements 關鍵字可以變相的使java具有多繼承的特性,使用范圍為類繼承接口的情況,可以同時繼承多個接口
final關鍵字:
- final 關鍵字聲明類可以把類定義為不能繼承的,即最終類
- 用于修飾方法,該方法不能被子類重寫
- 實例變量也可以被定義為 final,被定義為 final 的變量不能被修改。被聲明為 final 類的方法自動地聲明為 final,但是實例變量并不是 final
1.3 構造器
子類不能繼承父類的構造器(構造方法或者構造函數),但是父類的構造器帶有參數的,則必須在子類的構造器中顯式地通過super關鍵字調用父類的構造器并配以適當的參數列表。
如果父類有無參構造器,則在子類的構造器中用super調用父類構造器不是必須的,如果沒有使用super關鍵字,系統會自動調用父類的無參構造器。
輸出結果為:
SuperClass(int n) SubClass SuperClass() SubClass(int n):200到底是調用父類的帶參數還是無參構造器還要看實例化對象語句。
1.4 面向對象編程——繼承和多態
繼承的注意點:
- 子類不是父類的子集,子類一般比父類包含更多的數據域和方法。
- 父類中的 private 數據域在子類中是不可見的,因此在子類中不能直接使用它們。
- 繼承是為”是一個”的關系建模的,父類和其子類間必須存在”是一個”的關系,否則不能用繼承。
- 但也并不是所有”是一個”的關系都應該用繼承。例如,正方形是一個矩形,但不能讓 Square 類來繼承 Rectangle 類,因為正方形不能從矩形擴展得到任何東西。正確的繼承關系是 Square 類繼承 Shape 類
- Java 只允許單一繼承(即一個子類只能有一個直接父類),C++ 可以多重繼承(即一個子類有多個直接父類)。
super 關鍵字:
super 表示使用它的類的父類。super 可用于:
- 調用父類的構造方法(帶參);
- 調用父類的方法(子類覆蓋了父類的方法時,即重寫);
- 訪問父類的數據域(可以這樣用但沒有必要這樣用)。
注意:super 語句必須是子類構造方法的第一條語句(必須是子類構造方法的第一句)。不能在子類中使用父類構造方法名來調用父類構造方法。 父類的構造方法不被子類繼承(這也就是為什么要用super關鍵字)。調用父類的構造方法的唯一途徑是使用 super 關鍵字,如果子類中沒顯式調用,則編譯器自動將 super(); 作為子類構造方法的第一條語句。這會形成一個構造方法鏈。
注意:靜態方法中不能使用 super 關鍵字。
如果是繼承的方法,是沒有必要使用 super 來調用,直接即可調用。但如果子類覆蓋或重寫了父類的方法,則只有使用 super 才能在子類中調用父類中的被重寫的方法。
1.5 final 的作用隨著所修飾的類型而不同
1、final 修飾類中的屬性或者變量
無論屬性是基本類型還是引用類型,final 所起的作用都是變量里面存放的”值”不能變。
這個值,對于基本類型來說,變量里面放的就是實實在在的值,如 1,”abc” 等。
而引用類型變量里面放的是個地址,所以用 final 修飾引用類型變量指的是它里面的地址不能變,并不是說這個地址所指向的對象或數組的內容不可以變,這個一定要注意。
例如:類中有一個屬性是 final Person p=new Person(“name”); 那么你不能對 p 進行重新賦值,但是可以改變 p 里面屬性的值 p.setName(‘newName’);
final 修飾屬性,聲明變量時可以不賦值,而且一旦賦值就不能被修改了。對 final 屬性可以在三個地方賦值:聲明時、初始化塊中、構造方法中,總之一定要賦值。
2、final修飾類中的方法
作用:可以被繼承,但繼承后不能被重寫。
3、final修飾類
作用:類不可以被繼承。
在編寫代碼要注意:
執行父類構造函數的語句只能放在函數內語句的首句,不然會報錯。
在繼承關系中,在調用函數(方法)或者類中的成員變量時,JVM(JAVA虛擬機)會先檢測當前的類(也就是子類)是否含有該函數或者成員變量,如果有,就執行子類中的,如果沒有才會執行父類中的。如下:
運行結果如下:
黑色的Jack正在吃魚 Jack正在奔跑 Jack正在睡覺當子類出現與父類一樣的函數時,這個被稱為 重寫 也叫 覆蓋
Object類是所有類的直接父類或間接父類,也就是說是所有類的根父類,這個可以運用于參數的傳遞
如下:
運行結果:
Good morning! This is A Holle! This is B Look! This is C2. Java 重寫(Override)與重載(Overload)
2.1 Java 重寫(Override)
重寫是子類對父類的允許訪問的方法的實現過程進行重新編寫, 返回值和形參都不能改變。即外殼不變,核心重寫!
重寫的好處在于子類可以根據需要,定義特定于自己的行為。 也就是說子類能夠根據需要實現父類的方法。
重寫方法不能拋出新的檢查異?;蛘弑缺恢貙懛椒ㄉ昝鞲訉挿旱漠惓?。例如: 父類的一個方法申明了一個檢查異常 IOException,但是在重寫這個方法的時候不能拋出 Exception 異常,因為 Exception 是 IOException 的父類,只能拋出 IOException 的子類異常。
在面向對象原則里,重寫意味著可以重寫任何現有方法。
在編譯階段,只是檢查參數的引用類型。然而在運行時,Java虛擬機(JVM)指定對象的類型并且運行該對象的方法。
思考以下例子:
該程序將拋出一個編譯錯誤,因為b的引用類型Animal沒有bark方法
2.2 方法的重寫規則
- 參數列表必須完全與被重寫方法的相同;
- 返回類型必須完全與被重寫方法的返回類型相同;
- 訪問權限不能比父類中被重寫的方法的訪問權限更低。例如:如果父類的一個方法被聲明為public,那么在子類中重寫該方法就不能聲明為protected。
- 父類的成員方法只能被它的子類重寫。
- 聲明為final的方法不能被重寫。
- 聲明為static的方法不能被重寫,但是能夠被再次聲明。
- 子類和父類在同一個包中,那么子類可以重寫父類所有方法,除了聲明為private和final的方法。
- 子類和父類不在同一個包中,那么子類只能夠重寫父類的聲明為public和protected的非final方法。
- 重寫的方法能夠拋出任何非強制異常,無論被重寫的方法是否拋出異常。但是,重寫的方法不能拋出新的強制性異常,或者比被重寫方法聲明的更廣泛的強制性異常,反之則可以
- 構造方法不能被重寫。
- 如果不能繼承一個方法,則不能重寫這個方法。
2.3 重載(Overload)
重載(overloading) 是在一個類里面,方法名字相同,而參數不同。返回類型可以相同也可以不同。
每個重載的方法(或者構造函數)都必須有一個獨一無二的參數類型列表。
最常用的地方就是構造器的重載。
重載規則
- 被重載的方法必須改變參數列表(參數個數或類型或順序不一樣);
- 被重載的方法可以改變返回類型;
- 被重載的方法可以改變訪問修飾符;
- 被重載的方法可以聲明新的或更廣的檢查異常;
- 方法能夠在同一個類中或者在一個子類中被重載。
- 無法以返回值類型作為重載函數的區分標準。
重寫與重載之間的區別:
總結:
方法的重寫(Overriding)和重載(Overloading)是java多態性的不同表現,重寫是父類與子類之間多態性的一種表現,重載可以理解成多態的具體表現形式。
(1)方法重載是一個類中定義了多個方法名相同,而他們的參數的數量不同或數量相同而類型和次序不同,則稱為方法的重載(Overloading)。
(2)方法重寫是在子類存在方法與父類的方法的名字相同,而且參數的個數與類型一樣,返回值也一樣的方法,就稱為重寫(Overriding)。
(3)方法重載是一個類的多態性表現,而方法重寫是子類與父類的一種多態性表現。
重載與重寫的簡明理解:
重載反映的是“隨機應變”. 同樣一項功能, 根據數據類型的不同, 采用不同的處理方式. 比如, 同樣是吃飯, 去高檔餐廳吃西餐, 你會西裝革履, 但是去吃火鍋, 穿便裝就比較合適.
重寫反映的是“父子差異”. 你”繼承”了父親吃火鍋的愛好, 但是吃同一份鴛鴦鍋(注意, 數據類型相同) , 你喜歡涮紅湯, 你父親喜歡涮清湯.
補充:父類聲明變量指向子類實例,該父類變量不能調用父類不存在的變量和方法,否則會編譯錯誤
class Animal{public void move(){System.out.println("動物可以移動");} }class Dog extends Animal{public int age;public void move(){age = 10;System.out.println("狗可以跑和走");}public void bark(){System.out.println("狗可以吠叫");} }public class TestOverride{public static void main(String args[]){Animal a = new Animal(); // Animal 對象Animal b = new Dog(); // Dog 對象a.move();// 執行 Animal 類的方法b.move();//執行 Dog 類的方法// b.age;//去掉前注釋符號,會編譯錯誤// b.bark();//去掉前注釋符號,會編譯錯誤} }摘自:
http://www.runoob.com/java/java-override-overload.html
http://www.runoob.com/java/java-inheritance.html
總結
以上是生活随笔為你收集整理的Java继承、重写与重载 笔记的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 键盘光轴是什么意思(光轴是什么)
- 下一篇: Java 多态、抽象类 笔记