Java -- 面向物件(三)
阿新 • • 發佈:2020-12-13
Java – 面向物件(三)
本篇的重點是介紹多型的使用,上篇中介紹的繼承,子類和父類,其實將父類物件應用於子類的特徵就是多型。雖然不好理解,建議關於多型的定義理解,看一下參考書,因為他是抽象的內容,而且多型的綜合性非常強,一條語句可能就包含很多的知識點;建議多練習,新手的話多嘗試逐字逐句分析程式碼的含義,使其抽象的內容做到有自己的理解方式;
十二、final
1、概念
1. 是java中提供的一個關鍵字
2. finanl是最終的意思
3. final可以修飾類,方法,成員變數
初衷是因為:java出現了繼承後,子類可以更改父類的功能,當父類功能不許子類改變時可以利用final關鍵字修飾父類。
2、特點
1.被final修飾的類,不能被繼承
2.被final修飾的類,不能被重寫
3.被final修飾的變數是個常量,值不能被修改
3、測試案例
package cn.tedu.finaldemo;
public class Test_Final {
//測試final關鍵字
public static void main(String[] args) {
//建立子類物件測試
Son son = new Son();
// son.SUM = 5;//在不加final時可以修改,加上final之後不可以修改
//警告提示:The static field Son.SUM should be accessed in a static way
// System.out.println(son.SUM);//沒有加static通過物件呼叫,
System.out.println(Son.SUM);//加上靜態static之後,通過類名呼叫
}
}
//建立父類
//1、被final修飾的類是最終類,不能被繼承
//final class Father {//The type Son cannot subclass the final class Father
class Father {
//2、被final修飾的方法是最終方法,不能被重寫
// final public void eat() {//The type Son cannot subclass the final class Father
public void eat() {
System.out.println("爸爸在吃肉");
}
}
//建立子類
class Son extends Father{
//是子類的特有功能,只能建立子類物件才能呼叫
//3、final修飾的變數是常量,常量的值不能被修改
//4、變數前加了final是說變數變成了一個常量。加了static為了方便通過類名來直接呼叫
// int sum = 10;
static final int SUM = 10;
@Override
public void eat() {
System.out.println("兒子在喝湯");
}
}
控制檯顯示:10
十三、多型
1、概念
多型指同一個實體同時具有多種形態,他是面向物件程式設計(OOP)的一個重要特性;
主要是指用一個物件,在不同時刻代表的物件不一樣,指的是物件的多種形態;
好處是可以把不同的子類物件都當成父類來看,可以遮蔽不同子類物件之間的差異,寫入出通用的程式碼,做出通用的程式設計,統一呼叫標準;
例如:水,在不同時刻可以有多種形態,包括水蒸氣,冰,水
Java怎麼體現多型呢?狗有兩種形態:狗和小動物
class Animal{}
class Dog extends Animal{}
Dog d = new Dog();//狗是狗
Animal a = new Dog();//狗是小動物,建立了狗的物件,賦值給動物物件,這就是多型
2、特點
1.多型前提是繼承
2.要是方法的重寫
3.父類引用指向子類物件:如:Animal a = new Dog(); – 小到大,向上轉型;
4.多型中,編譯看左邊,執行看右邊
3、入門案例
package cn.tedu.muiti;
//這個類用來測試多型
public class Test_Muiti {
public static void main(String[] args) {
//3、建立父類測試物件
Animal animal = new Animal();
animal.eat();
//4、建立子類測試物件
Dog dog = new Dog();
dog.eat();//重寫前,使用的是父類的;重寫後,使用的是子類的;
//5、建立多型測試物件
//口訣1:父類引用 指向 子類物件 -- 多型/向上轉型
Animal animal2 = new Dog();
//口訣2:編譯看左邊,執行看右邊
//編譯看左邊:想要儲存成功,只能呼叫左邊(父類)的功能 ---- 統一呼叫標準!!標準就是父類!!
//執行看右邊:執行結果看子類的功能
animal2.eat();
}
}
//1、多型的前提:繼承 + 重寫
class Animal{
public void eat() {
// TODO Auto-generated method stub
System.out.println("...");
}
}
class Dog extends Animal{
//2、重寫:子類的方法宣告和父類一模一樣
@Override //標誌著這是在重寫父類的方法
public void eat() {
System.out.println("真香。。");
}
}
控制檯顯示:
編譯看左邊:想要儲存成功,只能呼叫左邊(父類)的功能;
執行看右邊:執行結果看子類的功能
4.多型的好處
(1)多型的使用
多型可以讓我們不用關心某個物件到底是什麼具體型別,就可以使用該物件的某些方法;
提高了程式的擴充套件性和可維護性
(2)多型的使用特點
成員變數:使用的是父類的;
成員方法:由於存在重寫現象所以使用的是子類的;
靜態成員:隨著物件而存在,誰呼叫的就返回誰的;
(3)測試案例
package cn.tedu.muiti;
public class Test_UseMulti {
public static void main(String[] args) {
//建立多型物件測試
Father f = new Son();
//1、多型中的成員方法怎麼用??
//編譯看左邊,用父類提供的方法宣告部分
//執行看右邊,用子類提供的方法體 --- 多指方法 重寫 現象
f.study();//天天向上
//2、多型中的成員變數怎麼用? -- 父類的
System.out.println(f.sum);
//3、多型中的靜態資源怎麼用? -- 父類的
// System.out.println(f.name);
System.out.println(Father.name);
//4、測試一下靜態方法能不能重寫?? -- 靜態資源不能重寫,誰呼叫就是誰的
//因為靜態資源是跟著類存在的
f.show();
Father.show();
}
}
//多型的前提:繼承 + 重寫
class Father{
int sum = 20;
static String name = "jack";
public void study() {
System.out.println("好好學習");
}
static public void show() {
System.out.println("Fa show...");
}
}
class Son extends Father{
int sum = 10;
static String name = "rose";
@Override
public void study() {
System.out.println("天天向上");
}
static public void show() {
System.out.println("son show...");
}
}
控制檯顯示:
由於多型綜合了前面的封裝和繼承,所以需要多加練習更好的例理解
提供了一個練習案例;
文末會提供聯絡的具體程式碼和答案
/*
* 自己測試練習:
* --父類 --Teacher
* --子類 --Student
* --建立多型測試
* --成員變數,成員方法,靜態資源
*/
十四、異常
1、概述
用來封裝錯誤資訊的物件
組成結構:型別,提示,行號;
2、異常的繼承結構
Throwable - 頂級父類
-- Error:系統錯誤,無法修復
-- Exception:可修復的錯誤
--RunTimeException
--ClassCastException
--ClassNotFoundException
3、異常處理
程式中遇到異常,通常有兩種處理方式:捕獲或者向上丟擲
當呼叫了一個丟擲異常的方法是,呼叫位置可以不做處理繼續向上爆出也可以捕獲異常
不建議向上丟擲,儘量捕獲,不要選擇丟擲,要不然開發者就刺激了;
1.捕獲方式
try{
需要捕獲的程式碼
}catch(異常型別 異常名){
處理方案
}
2.丟擲方式
會在發生異常的方法上新增程式碼: throws異常型別,例如:
public static void main(String[] args) throws Exception{
}
4、測試
package cn.tedu.exception;
import java.util.Scanner;
//這個類用來測試異常的暴露
public class Test_Exception {
public static void main(String[] args) {
//method();//暴露異常
// method2();//捕獲異常
//儘量捕獲,不要選擇丟擲,要不然開發者就刺激了
try {
method3();
} catch (Exception e) {
// 開發階段,上線的時候會被註釋掉
e.printStackTrace();//通常用來排除錯誤
System.out.println("執行失敗");//專案上線時給出的提示
}
}
//丟擲異常:在會出錯的方法上新增程式碼 throws 異常型別
//直接丟擲Exception也是體現了多型,因為根本不關心具體的子類型別,會把子類當做父類來看,寫出通用程式碼
public static void method3() throws Exception{
//接收使用者輸入的兩個整數
int a = new Scanner(System.in).nextInt();
int b = new Scanner(System.in).nextInt();
//做除法運算
System.out.println(a/b);
}
//1、捕獲異常 try{有可能發生異常的程式碼}catch(異常型別 異常名){解決方案}
private static void method2() {
try {
//接收使用者輸入的兩個整數
int a = new Scanner(System.in).nextInt();
int b = new Scanner(System.in).nextInt();
//做除法運算
System.out.println(a/b);
} catch (Exception e) {//2、當try裡的程式碼發生異常時,會給出捕獲方案
//Exception就是多型的體現,好處是不關心具體的子類型別,會把子類當做父類來處理,寫出通用程式碼
System.out.println("請輸入正整數");
}
}
//暴露異常
public static void method() {
//接收使用者輸入的兩個整數
int a = new Scanner(System.in).nextInt();
int b = new Scanner(System.in).nextInt();
//做除法運算
System.out.println(a/b);
}
}
訪問控制符(背過就可以)
用來控制一個類,或者類中的成員的訪問範圍。
多型自我測試的答案
package cn.tedu.muiti;
/*
* 自己測試練習:
* --父類 --Teacher
* --子類 --Student
* --建立多型測試
* --成員變數,成員方法,靜態資源
*/
public class MyTest {
public static void main(String[] args) {
//建立多型物件測試
Teacher t = new Student();
System.out.println(t.age);//30 --父類
Teacher.hei();//180老師 --父類
System.out.println(t.name);//tea --父類
t.study();//正在做題 --子類
//只有重寫的方法才可以執行看右邊
//如果,你非要用 子類的特有功能,多型物件不可能!!此時,只能建立子類物件。
// t.name//報錯,因為t是多型物件,只能使用父類的功能,對於子類特有功能,多型物件無能為力
//方法一:建立子類物件 -- 建議使用
Student s = new Student();
System.out.println(s.name);
//方法二:向下轉型 -- 多型叫做向上轉型 -- 不建議使用
Student s2 = (Student) t;//右側的t是父類 型別,給左側的子類型別 s2賦值時,--需要強轉
System.out.println(s2.name);
}
}
//Teacher類
class Teacher{
//成員變數
int age = 30;
//靜態成員變數
static String name = "tea";
//方法
public void study() {
System.out.println("正在講課");
}
//靜態方法
static public void hei() {
System.out.println("180老師");
}
}
//Student類
class Student extends Teacher{
//成員變數
int age = 18;
//靜態成員變數
static String name = "stu";
//方法
public void study() {
System.out.println("正在做題");
}
//靜態方法
static public void hei() {
System.out.println("160學生");
}
}
涉及到向上轉型和向下轉型!!!
向上轉型和向下轉型
在JAVA中,繼承是一個重要的特徵,通過extends關鍵字,子類可以複用父類的功能,如果父類不能滿足當前子類的需求,則子類可以重寫父類中的方法來加以擴充套件;
在應用中就存在著兩種轉型方式,分別是:向上轉型和向下轉型。
比如:父類Parent,子類Child
向上轉型:
父類的引用指向子類物件Parent p=new Child();
說明:向上轉型時,子類物件當成父類物件,只能呼叫父類的功能,如果子類重寫了父類的方法就根據這個引用指向呼叫子類重寫方法。
向下轉型(較少):
子類的引用的指向子類物件,過程中必須要採取到強制轉型
Parent p = new Child();//向上轉型,此時,p是Parent型別;
Child c = (Child)p;//此時,把Parent型別的p轉成小型別Child
//其實,相當於建立了一個子類物件一樣,可以用父類的,也可以用自己的
說明:向下轉型時,是為了方便使用子類的特殊方法,也就是說當子類方法做了功能拓展,就可以直接使用子類功能。
向下轉型不建議使用,還不如直接建立子類物件
【下篇預告】
抽象類
介面
…