15_Java筑基之Object類、多態

2022-12-23 14:17:12 來源:51CTO博客

15_Java筑基之Object類、多態

一. Object類

Object類是類層次結構的根類,每個類都使用Object作為超類(父類).

1. equals()方法

指示其他某個對象是否與此對象“相等”.

示例代碼;


(相關資料圖)

/*** 學生類*/public class Student extends Object{    String stuNo;    String stuName;    int age;    public void show() {        System.out.println("學號:"+stuNo+" 姓名:"+stuName+" 年齡:"+age);    }        @Override    public boolean equals(Object obj) {        if(obj==null) {             return false;        }            //強制類型轉換    //注意:可能的NullPointerException    Student stu=(Student)obj;          //比較學號和姓名if(this.stuNo.equals(stu.stuNo)&&this.name.equals(stu.name)){            return true;        }        return false;    }    }public class Test {    public static void main(String[] args) {        Student zhangsan=new Student();        zhangsan.stuNo="bj1805";        zhangsan.stuName="xxx";        zhangsan.age=20;        Student lisi=new Student();        lisi.stuNo="bj1805";        lisi.stuName="xxx";        lisi.age=20;        boolean b=zhangsan.equals(lisi);        boolean b2=zhangsan==lisi;        System.out.println(b);        System.out.println(b2);    }}

2. ==操作符與equals方法的區別:

1. ==: 如果是基本類型進行比較,則比較的是數值;   如果是引用類型進行比較,則比較的是對象的引用(地址); 2. 默認情況下,Object中的 equals和 == 一樣;3. String類型中重寫了Object中的equals方法,所以String中的比較使用equals()方法.

3. hashCode()方法

返回該對象的哈希碼值(理解為對象的地址),每一個對象的哈希碼值唯一.

示例:

Object obj1 = new Object();Object obj2 = new Object();Object obj3 = obj2; //obj2與obj3兩個對象的哈希碼值一樣System.out.println(obj1.hashCode()); System.out.println(obj2.hashCode()); System.out.println(obj3.hashCode());

3. getClass()方法

返回此Object的運行時類,獲取某個類的類對象.

示例:

Object obj = new Object();Class cls = obj.getClass();//通過反射獲取到了Object類

5. toString()方法

返回該對象的字符串,可以在自定義類中重寫toString方法,以實現是對象轉成指定格式的字符串.

示例

public class Person{    String name;    public Person(String name){        this.name = name;    }    //重寫toString方法    public String toString(){        return "name="+name;    }}public class DemoPerson{    public static void main(String[]args){        Person p = new Person("張三");        System.out.println(p);//輸出結果為:name=張三    }}

二. 多態

1. 什么是多態

在生活中,一類事物有多種表現形態,對象的多種形態. 比如: 某個音樂家有三個兒子: 大兒子會唱美聲,二兒子會唱流行,三兒子唱搖滾.程序中舉例, 動物是父類: Dog會旺旺,Cat會喵喵,Pig會哼哼.程序中的 多態: 同一個父類引用類型,使用不同的子類實例可以執行不同的操作.

2. 案例

需求:

編寫一個寵物類 Pet, 屬性: id,name,health,love;方法有print(),打印信息,要封裝成員變量.兩個子類狗狗和貓類,狗狗有品種(strain),貓類有愛好(hobby),重寫父類print()方法;寵物餓了,需要主人給寵物喂食,狗狗吃狗糧、貓咪吃小魚,吃完之后健康值狗狗增加3斤,貓咪增加5斤.

示例:

/*寵物類*/package com.syc.day08;public class Pet{    private int id; //id 寵物編號    private String name;// 寵物昵稱     private int health;// 健康值     private int love;// 親密度       public void setId(int id){        this.id=id;    }       public int getId(){        return id;    }       public void setName(String name){        this.name=name;    }        public String getName(){        return name;    }        public void setHealth(int health){        this.health=health;    }        public int getHealth(){        return health;    }        public void setLove(int love){        this.love=love;    }        public int getLove(){        return love;    }    //方法    public void print(){        System.out.println("寵物id:"+this.id+",寵物昵稱:"+this.name+",健康值:"+health+", 親密度:"+love);    }    }/*dog類繼承Pet類*/package com.syc.day08;public class Dog extends Pet{    private String strain;    public void setStrain(String strain){        this.strain=strain;    }        public String getStrain(){        return strain;    }        public void print(){        int id=getId();        String name=getName();        int health=getHealth();        int love=getLove();        System.out.println("狗狗id:"+id+" 昵稱:"+name+" 健康值:"+health+" 親密度:"+love+"        品種:"+strain);    }       public void eat(){        String name=getName();         System.out.println(name+"大口吃狗糧...."); //增加健康值        int health=getHealth(); setHealth(health+3);     }     }/*貓類*/package com.syc.day08;public class Cat extends Pet{    private String hobby;        public void setHobby(String hobby){        this.hobby=hobby;    }        public String getHobby(){        return hobby;    }        public void print(){        int id=getId();        String name=getName();        int health=getHealth();        int love=getLove();        System.out.println("貓咪id:"+id+" 昵稱:"+name+" 健康值:"+health+" 親密度:"+love+"        愛好:"+hobby);    }        public void eat(){        String name=getName(); System.out.println(name+"大口吃小魚...."); //增加健康值        int health=getHealth(); setHealth(health+5);    }}/*主人*/package com.syc.day08;public class Master{    private String name;    public void setName(String name){        this.name=name;    }        public String getName(){        return name;    }    //喂食    public void feed(Dog d){        System.out.println(name+"要給狗狗喂食物...");         d.eat();        d.print();    }        public void feed(Cat c){         System.out.println(name+"要給貓咪喂食物...");         c.eat();        c.print();    }}package com.syc.day08;public class TestPet{    public static void main(String[] args){         Dog afu=new Dog();        afu.setId(120);        afu.setName("阿福");         afu.setHealth(85);        afu.setLove(90);         afu.setStrain("拉布拉多");         afu.print();                Cat amao=new Cat();         amao.setId(119);         amao.setName("阿貓");        amao.setHealth(90);         amao.setLove(70);         amao.setHobby("爬樹");         amao.print();                Master yuhuan=new Master();         yuhuan.setName("小美");         yuhuan.feed(afu);         yuhuan.feed(amao);    }}

思考:

如果再領養XXX寵物,就需要給XXX喂食,怎么辦? 這樣頻繁修改代碼,代碼可擴展性、可維護性差,考慮使用多態來優化代碼.

3. 多態實現步驟

編寫父類、子類,子類重寫父類方法;運行時使用父類變量,子類的對象(編譯時看父類,運行時看子類).

示例:

/*public void feed(Dog d){    System.out.println(name+"要給狗狗喂食物...");     d.eat();    d.print();}public void feed(Cat c){    System.out.println(name+"要給貓咪喂食物...");     c.eat();    c.print();}*/public void feed(Pet p){    String n=p.getName(); System.out.println(name+"要給"+n+"喂食物..."); p.eat();//調用子類重寫的方法     p.print();//調用子類重寫的方法}

4. 多態使用形式

使用父類作為方法形參實現多態;使用父類作為方法返回值實現多態.

上機練習:

使用多態實現領養寵物,使用父類作為方法返回值.

//主人類中添加領養方法     //領養    public Pet adopt(int type){        if(type==1){            Pet d=new Dog();            d.setHealth(80);            d.setLove(50);            return  d;        }else if(type==2){            Pet c=new Cat();            c.setHealth(80);            c.setLove(50);            return  c;        }else{            return null;        }    }   /*領養寵物*/package com.syc.day08;import java.util.Scanner;public class TestPet2{    public static void main(String[] args){         System.out.println("歡迎來到xxx寵物商店.....");        System.out.println("請選擇您要領養的寵物類型. 1 狗狗; 2 貓咪");         Scanner input=new Scanner(System.in);        int choice=input.nextInt();        Master yuhuan=new Master();        Pet p=yuhuan.adopt(choice);        if(p!=null){            System.out.println("領養成功");            p.print();        }else{            System.out.println("領養失敗");         }    } }

5. 向上轉型、向下轉型

向上轉型:

將子類的對象賦值給父類變量,自動轉換.

Pet pet1 = new Dog();Pet pet2 = new Cat();String str = "abc";Object obj = str;

注意:

<父類型> <引用變量名> = new <子類型>();此時通過父類引用變量調用的方法是子類重寫或父類的方法, 編譯時看父類,運行時看子類;此時通過父類引用變量無法調用子類特有的屬性和方法.

向下轉型:

將父類的變量賦值給子類變量,強制轉換.

Object obj = new String("abc");String str = (String)obj;Pet pet=new Dog(); // Pet pet=new Cat(); Dog d=(Dog)pet; //向下轉型

注意:

<子類型> <引用變量名> = (<子類型> )<父類型的引用變量>;在向下轉型的過程中,如果沒有轉換為真實子類類型,會出現類型轉換異常ClassCastException.

上機練習: 實現主人與寵物玩耍功能

//貓咪捉迷藏: 貓類中public void hideAndSeek(){    String name=getName(); System.out.println(name+"玩捉迷藏...");     int health=getHealth();     setHealth(health-5);}//接球: 狗狗類public void catchBall(){    String name=getName();     System.out.print(name+"玩接球游戲....");     int health=getHealth();     setHealth(health-3);}//和寵物玩耍public void play(Pet pet){    if(pet instanceof Dog){        Dog d=(Dog)pet;        d.catchBall();    }else if(pet instanceof Cat){        Cat c=(Cat)pet;        c.hideAndSeek();    }}

6. instanceof

對象向下轉型時,存在一個問題: 若一個父類A的引用a,指向一個子類B的實例,將a賦值給另一個子類C引用時,會拋出java.lang.ClassCastException異常.

拋出異常后,程序將不能繼續向下執行.為了避免這個異常的拋出,我們可以通過instanceof關鍵字,來判斷引用指向的實例是否可以進行強制轉換成某個子類對象.

示例:

已知Pet類有兩個子類Dog和Cat:

public class Demo{    public static void main(String[]args){        Pet a = new Dog();        check(a);    }        //設計一個方法,判斷一個動物是貓還是狗     public static void check(Pet a){        if(a instanceof Dog){             System.out.println("狗");        }else if(a instanceof Cat){             System.out.println("貓");        }     }}

三. final關鍵字

final: 最終的.可以使用final關鍵字來修飾Java的類、屬性和方法.

1. final修飾變量

final修飾成員變量或局部變量,則成為(符號)常量,只能賦值一次,用大寫字母表示.

修飾成員變量時,定義時同時給出初始值,或在構造方法中賦值;修飾局部變量時,只能賦值一次.

2. final修飾方法

則該方法不能被子類重寫,但能被繼承.

final returnType methodName(paramList){    ... }

3. final修飾類,則類不能被繼承.

final class finalClassName{    ... }

四. 總結

1. Object類: 所有類的父類,默認繼承Object.2. equals()方法: 判斷兩個對象是否相等, this==obj;   ==: 基本類型比較數據,引用類型比較地址/   equals() 默認 和 == 一樣;      hashCode()方法: 返回對象的地址;   getClass()方法: 返回類對象;   toString()方法: 返回對象的字符串形式.3. 多態: 同一個父類引用類型,使用不同的子類實例,執行不同的操作.    父類引用子類對象實現多態的要素或條件:    ①. 子類繼承父類,子類必須重寫父類的方法;    ②. 使用父類變量,子類對象.      多態表現形式:  ①. 使用父類作為方法的參數;  ②. 使用父類作為方法的返回值.4. 向上轉型和向下轉型    向上轉型: 子類轉成父類;    向下轉型: 父類轉成子類,先向上轉型,才能向下轉型.    5. instanceof: 判斷對象是否是某種類型.    if(pet instanceof Dog){        Dog dog=(Dog)pet;    }    6. final 終止的.   ①. final修飾變量,常量:只能賦值一次;   ②. 修飾成員變量;   ③. 修飾局部變量.   ④. final修飾方法,該方法屬于終止方法,不能被重寫,       但能被繼承.     ⑤. final修飾類,終止類,不能被繼承.

標簽: 成員變量 引用類型 局部變量

上一篇:消息!腳本2分鐘實現電話短信報警
下一篇:當前快訊:Day19_06_Vue教程之Vue實例的生命周期