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实例的生命周期