Day7.多态

本文深入探讨了Java中的多态性,包括向上转型、向下转型、instanceof运算符的使用,以及多态在方法参数和返回值中的应用。通过示例代码解释了如何通过父类引用调用子类方法,展示了多态提升代码可扩展性和可维护性的优势。同时,强调了子类转换为父类的规则和注意事项,以及在向下转型时防止ClassCastException的方法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

3.1实现多态

Java面向对象还有一个重要的特性:多态

1.认识多态

多态一词的通常含义是指能够呈现多种不同的形式或形态。而在程序设计的术语中,它意味着一个特定类型的变量可以引用不同类型的对象,并且能自动地调用引用的对象的方法,也就是根据作用到的不同对象类型,响应不同的操作。方法重写是实现多态的基础。

/**
 * @作者:Xem626
 * @date: 2022/7/13 9:17
 * @TODO
 */
 class Pet {
    public void toHospital(){
        System.out.println("宠物去看病");
    }
}
 class Dog extends Pet{

     public void toHospital(){
         System.out.println("狗去看病");
     }

}
class Bird extends Pet{

    public void toHospital(){
        System.out.println("鸟去看病");
    }

}
 class Test1{
     public static void main(String[] args) {

         Dog dog=new Dog();
         dog.toHospital();
         Bird bird=new Bird();
         bird.toHospital();

         

         Pet pet;
         pet=new Dog();
         pet.toHospital();
         pet=new Bird();
         pet.toHospital();
     }

}

在这里插入图片描述

分析:

​ 测试1和测试2中两端Test类的代码运行效果完全一样。虽然测试2中定义的是Pet类,但实际执行时都是调用Pet子类的方法。测试2的代码就体现了多态性

​ 多态意味着在一次方法调用中根据包含的对象的实际类型(即实际的子类对象)来决定应该调用哪个方法,而不是由用来存储对象引用的变量的类型决定的。当调用一个方法时,为了实现多态的操作,这个方法既是在父类中声明过的,也必须是在子类中重写过的方法。

以后:Pet这个类后期会定义成抽象类,因为这个类的实例化没有任何意义。toHospital()后期申明为抽象方法

注意:

​ 1.抽象类不能被实例化

​ 2.子类如果不是抽象类,则必须重写抽象类中的全部抽象方法

​ 3.abstract修饰不能和final一起使用

​ 4.abstract修饰的方法没有方法体

​ 5.private不能修饰抽象方法

2.向上转型

子类向父类的转换向上转型

​ 向上转型的语法:


<父类型>  <引用变量名>  =new <子类型>()

(1)把int类型常量或变量赋值给double类型,可以进行类型自动转换

​ int i=5;

​ double di =5;

(2)把double类型的常量或变量的值赋给int类型的变量,必须进行强制类型转换

double d2 =3.14;

​ int a = (int)d2;
实际上在引用数据类型的子类和父类之间也存在着类型转换问题,如示例中的代码

//当Pet为父类时,Dog为子类,Pet中包含方法toHosptial()

Pet pet =new Dog();//子类到父类的转换

//会调用Dog()类的toHospital()方法,而不是Pet类的toHospital()方法,体现多态

pet.toHospital()

注意:

​ Pet对象无法调用子类特有的方法

子类转换为父类时的规则:

​ 1.将一个父类的引用指向子类对象称为向上转型,系统自动类型转换

​ 2.此时通过父类引用变量调用方法时,子类覆盖或继承了父类的方法,不是父类的方法

​ 3.此时无法通过父类的引用变量调用子类特有的方法

3.向下转型

当向上转型发生后,将无法调用子类特有的方法,但是如果需要调用子类特有的方法,可以通过把父类转换为子类的实现

将一个指向子类对象的父类引用给一个子类引用,即父类类型转换为子类类型,称为向下转型,此时必须要强制类型转换

向下类型转换的语法:


​	<子类型>   <引用变量名> =(子类类型)<父类类型的引用变量>

/**
 * @作者:Xem626
 * @date: 2022/7/13 9:17
 * @TODO
 */
 class Pet {
    public void toHospital(){
        System.out.println("宠物去看病");
    }
}
 class Dog extends Pet{

     public void toHospital(){
         System.out.println("狗去看病");
     }
     public void catching(){
         System.out.println("玩飞盘");
     }

}
class Bird extends Pet{

    public void toHospital(){
        System.out.println("鸟去看病");
    }

}
 class Test1{
     public static void main(String[] args) {

//         Dog dog=new Dog();
//         dog.toHospital();
//         Bird bird=new Bird();
//         bird.toHospital();
//
//
//
         Pet pet;
         pet=new Dog();
         pet.toHospital();
//         pet=new Bird();
//         pet.toHospital();


         Dog dog=(Dog) pet;
         dog.catching();

     }

}

在这里插入图片描述

4.instanceof运算符

在向下转型的过程中,如果不是转换为真实的子类类型,会出现异常

Pet pet=new Dog();

            pet.toHospital();

            Bird bird=(Bird) pet;//代码编写不会出错运行会报错
            bird.toHospital();

在这里插入图片描述

使用instanceof 时,对象类型必须和instanceof后面的参数所指定的类有继承关系,否则会出现编译错误,

例如:代码“pet instanceof String”。instanceof通常和强转类型转换结合使用

  Pet pet=new Bird();
            pet.toHospital();
            if(pet instanceof Dog){
                Dog dog=(Dog) pet;
                dog.catching();
            }else if(pet instanceof Bird){
                Bird bird=new Bird();
                bird.fly();

在这里插入图片描述

多态的应用
1.使用父类作为方法的形参

使用父类作为方法的参数,是java中实现和使用多态的主要方式

/**
 * @作者:Xem626
 * @date: 2022/7/13 9:50
 * @TODO
 */
public class Host {
    public void letCry(Pet pet){
        pet.cry();//调用动物cry
    }
}

/**
 * @作者:Xem626
 * @date: 2022/7/13 9:54
 * @TODO
 */
public class Test2 {
    public static void main(String[] args) {
        Host host=new Host();
        Pet pet;
        pet=new Dog();
        host.letCry(pet);

        pet=new Bird();
        host.letCry(pet);
    }
}

在这里插入图片描述
本次案例中,主人控制宠物叫的方法中,并没有把宠物子类作为方法的参数,而是使用Pet父类
当调用LetCry()方法时,实际传入的参数是一个子类的宠物,最终调用了这个子类宠物cry方法
这个就是多态的应用:使用父类作为方法的形参

2.使用父类作为方法的返回值

使用父类作为方法的返回,也是java中实现和使用多态的主要方式

public Pet donatePet(String type){
        Pet pet=null;
        if(type=="dog"){
            pet =new Dog();
        }else if(type=="bird"){
            pet =new Bird();
        }else{
            System.out.println("没有宠物类型");
        }
        return pet;
    }
public class Test3 {
    public static void main(String[] args) {
        Host host=new Host();
        Pet pet;

        pet=host.donatePet("dog");
        pet.cry();
        System.out.println("-------------");
        pet=host.donatePet("bird");
        pet.cry();

    }
}
本章总结:

​ 1.继承是Java。Java支持单继承,即个类只能有一个直接父类。Object 所有Java的祖先。

​ 2.在子类中可以根据实际需求对从父类继承的方法进行重新编写,称为方法的重写或覆盖。
​ 3.在子类中重写的方法和父类中被重写的方法必须具有相同的方法名、参数列表,返回值类型必须和被重写方 法的返回值类型相同。
​ 4.在实例化子类时,会首先执行其父类的构造方法,然后再执行子类的构造方法
​ 5.通过super关键字可以访问父类的成员。

​ 6.通过多态可以减少类中的代码量,可以提高代码的可扩展性和可维护性。继承是多态的基础,没有继承就没有多态

​ 7.在多态的应用中,可以使用父类作为方法的形参,还可以作为方法的返回值。

​ 8.把子类转换为父类称为向上转型,系统自动进行类型转换。把父类转换为子类,称为向下转型,必须进行强制类型转换。

​ 9.向上转型后,通过父类引用变量调用的方法是子类覆盖或继承自父类的方法,通过父类引用变量无法调用子类特有的方法。
​ 10.向下转型后可以访问子类特有的方法。向下转型必须转换为父类指向的真实子类类型,否则将出现类型转换异常ClassCastException。

​ 11. instanceof运算符用于判断一个对象是否属于一个类。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Xem626

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值