Java中多态的表现形式

概念:同一个类实例的相同方法在不同情形下有不同的表现形式

在Java中,对于多态的核心表现主要有以下两点:

1. 方法多态:

① 方法重载:同一个方法名称可以根据参数的类型或个数不同调用不同的方法体

② 方法覆写:同一个父类的方法可以根据实例化子类的不同也有不同的实现

方法多态之前的文章里面详细阐述过,在此不再赘述。

2. 对象多态:

① 向上转型(90%):

天然发生,认爹过程,指的是将子类对象变成父类对象

语法:父类 父类引用 = 子类实例;,例如Person per = new Student();

class Person {
    public void print() {
        System.out.println("父类");
    }
}
class Student extends Person {
    public void print() {
        System.out.println("子类");
    }
}
public class XiangShangZhuanXing {
    public static void main(String[] args) {
        Person per = new Student();
        per.print();
    }
}

在这里插入图片描述

  • 结论:不管是否发生了向上转型,核心本质还是在于:你使用的是哪一个子类(new在哪里),而且调用的方法是否被子类所覆写了。

应用场景:参数统一化

例如:要求定义一个方法,这个方法可以接收Person类的所有子类实例,并调用Person类的方法。

class Person {
    public void print() {
        System.out.println("1.我是人类!");
    }
}
class Student extends Person {
    public void print() {
        System.out.println("2.我是学生!");
    }
}
class Worker extends Person {
    public void print() {
        System.out.println("3.我是工人!");
    }
}
public class CanShuTongYiHua {
    public static void main(String[] args) {
        //Person per = new Student();
        WhoYouAre(new Student());
        //Person per = new Worker();
        WhoYouAre(new Worker());
    }
    public static void WhoYouAre(Person per) {
        per.print();
    } 
}

在这里插入图片描述

② 向下转型(1%):

需要强转,指的是将父类对象变成子类对象

语法:子类 子类实例 = (子类)父类实例;,例如Student stu = (Student) per;

  • 问题:向下转型存在的意义或者为什么我们需要向下转型?
class Person {
    public void print() {
        System.out.println("父类");
    }
}
class Student extends Person {
    public void print() {
        System.out.println("子类");
    }
    public void fun() {
        System.out.println("只有子类有");
    }
}
public class XiangXiaZhuanXing {
    public static void main(String[] args) {
        Person per = new Student();
        per.print();
        System.out.println("==========");
        Student stu = (Student) per;
        stu.fun();
    }
}

在这里插入图片描述

  • 结论:在上述代码中父类能调用的就只有本类定义好的方法,并没有Student类中的fun()方法,如果父类要想调用fun()方法就只能进行向下转型处理,总的来说就是当需要子类扩充操作的时候就要采用向下转型。

应用场景:发生在父类引用需要调用子类扩充方法时,才发生向下转型变为子类引用调用其扩充方法

注意:并不是所有的父类对象都可以向下转型 ,如果要想进行向下操作之前,前提是一定要首先发生向上转型,否则在转型时会出现ClassCastException(运行时异常,类型转换异常,发生在两个毫无关系的两个类之间的强转时)

观察错误转型:

class Person {
    public void print() {
        System.out.println("父类");
    }
}
class Student extends Person {
    public void print() {
        System.out.println("子类");
    }
    public void fun() {
        System.out.println("只有子类有");
    }
}
public class XiangXiaZhuanXing {
    public static void main(String[] args) {
        Person per = new Person();
        per.print();
        System.out.println("==========");
        Student stu = (Student) per;
        stu.fun();
    }
}

在这里插入图片描述

  • 结论:上述代码进行向下转型之前Person per = new Person();没有先进行向上转型,所以出现类型转换异常这个错误。
  • 问题 :如果向下转型存在安全隐患,那么如何转型才靠谱呢?

最好的做法就是先进行判断,而后再进行转型,那么就可以依靠关键字instanceof实现。

引用对象 instanceof 类:表示该引用能指向该类,返回true表示可以指向,返回flase表示不能指向。

因此,向下转型的标准格式为:

if(!(per instanceof Student)) {
	per = new Student();   // 先建立起联系
}
Student stu = (Student) per;

观察instanceof操作:

class Person {
    public void print() {
        System.out.println("父类");
    }
}
class Student extends Person {
    public void print() {
        System.out.println("子类");
    }
    public void fun() {
        System.out.println("只有子类有");
    }
}
public class XiangXiaZhuanXing {
    public static void main(String[] args) {
        Person per = new Person();
        //避免ClassCastException
        if(!(per instanceof Student)) {
            per = new Student();
        }
        Student stu = (Student) per;
        stu.fun();
    }
}

在这里插入图片描述

  • 结论:我们可以看到加上instanceof之后就算没有先向上转型,向下转型依然是可以进行的。
总结:
  • 对象的多态性(向上转型或向下转型)本质在于方法的覆写。
  • 通过对象的向上转型可以实现接收参数的统一,向下转型可以实现子类扩充方法的调用(一般不操作向下转型,有安全隐患)。
  • 两个没有关系的类对象是不能够进行转型的,一定会出现ClassCastException。
  • 19
    点赞
  • 69
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值