多态性:中的向下转型,instanceof 操作符的使用

多态性:中的向下转型,instanceof 操作符的使用

在这里插入图片描述


每博一文案

都说树叶不是一天变黄的,人心也不是一天变凉的,每一个现在的自己,其实都是过去的自己拼凑的。
如今我们的气质里都藏着过去走过的路,看过的书和爱过的人,曾经的好,曾经的话,曾经的眼泪和孝顺,其实一直都在,生生不息。
如今你所遇见的这个我,是被这个世界打磨过的我。正如张爱玲所说的:如果你认识从前的我,你就会
原谅现在的我呢。别人都说你变了,却没人关心你到底经历过什么。
如果我们没走过他人走过的路,经历过他人经历的事,或许真的不能懂他人的悲喜。
每个人都曾想过,要活得无忧无虑,可社会复杂,人心难测,逼的人不得不伪装将自己内心的感情藏得更深。
不敢轻易去爱,因为明白了这个迷茫的世界需要冷漠与对抗。
所以,如果你认识从前的我,也许就会理解我现在的伪装。如果你不认识从前的我,就请不要随意的随意的评判
我,因为你不知道我是怎么走到今天的往后余生。
愿你的每一次成熟都不必靠受伤才能懂得,也愿你傻傻的天真,有人会用心守。
                                                   ——————   一禅心灵庙语


1. 多态: 对象类型转换

基本数据类型的转换

  • 自动类型转换: 的数据类型可以自动转换成 的数据类型
long lnum = 20;        // 在Java当中整数值默认是 int 类型
double dnum = 12.0f;   // 在Java当中小数默认是 double 类型
  • 强制类型转换: 可以把 的数据类型 强制转换的数据类型
int inum = int(200L);     // L long 类型的后缀
float fnum = (float)12.0; 

对于 Java多态 引用类型(对象) 的转换:

  • 向上转型: 子类的类类型可以自动转换成 父类的类类型,被称为 向上转型,但更多是被称为 是 多态
Person person = new Student();  // 向上转型 或者 多态。
  • 强制类型转换: 可以将父类的类类型 必须通过 强制类型的转换子类 的类类型,这样就可以调用子类中特有的方法/属性了。
Person person = new Student();     // 多态
Student student = (Person)person;  // 强制向下转型

在这里插入图片描述


我们使用多态(向上转换) 为了 父类类型以后,如果想要调用 子类中特有的属性和方法 怎么办 ???

可以将 父类类型 强制转换为 对应子类 类型,从而就可以调用 子类中特有的属性和方法了。

多态:向下强制转换

如下代码:

package blogs.blog1;


public class PersonTest{
    public static void main(String[] args) {
        Person p1 = new Student();
        //p1.ncee(); // 直接编译的是父类类型,是无法调用子类中特有的属性/方法的,编译报错

        // 可以使用强制向下转型为对应 子类类型来调用其中的特有的属性/方法
        Student s1 = (Student)p1;
        System.out.println(s1.name);  // 可以调用子类中特有的属性/方法
        s1.ncee();    // 可以调用子类特有的方法


        Person p2 = new Teacher();
        Teacher t1 = (Teacher)p2;
        System.out.println(t1.name);
        t1.teach();    // 调用子类中特有的方法

    }
}

class Person {   // 父类
    String name = "Person";
    int age;

    public Person(String name,int age) {
        this.name = name;
        this.age = age;
    }
    public Person() {

    }

    public void show() {
        System.out.println("我是 Person");
    }



}

class Student extends Person{   // 子类
    int studentId;
    String name = "Student";

    @Override
    public void show() {
        System.out.println("我是 Student");
    }

    public void ncee() {
        System.out.println("高考");
    }

}


class Teacher extends  Person{  // 子类
    int teacherId;
    String name = "Teacher";

    @Override
    public void show() {
        System.out.println("我是 Teacher");
    }


    public void teach() {
        System.out.println("教书育人");
    }
}

在这里插入图片描述


通过强制向下转型,将父类转为 对应的子类的类型,从而就可以调用子类中特有的属性/方法了。

public class PersonTest{
    public static void main(String[] args) {
        Person p1 = new Student();
        //p1.ncee(); // 直接编译的是父类类型,是无法调用子类中特有的属性/方法的,编译报错

        // 可以使用强制向下转型为对应 子类类型来调用其中的特有的属性/方法
        Student s1 = (Student)p1;
        System.out.println(s1.name);  // 可以调用子类中特有的属性/方法
        s1.ncee();    // 可以调用子类特有的方法


        Person p2 = new Teacher();
        Teacher t1 = (Teacher)p2;
        System.out.println(t1.name);
        t1.teach();    // 调用子类中特有的方法

    }
}

注意的是:使用向下强制转换,存在一个问题:就是如果两个引用类型之间没有子父类继承关系/本身的实例关系 ,而是并列关系的话,编译可以通过,但是运行时,会报:java.lang.ClassCastException 类异常。

如下代码:

package blogs.blog1;


public class PersonTest{

    public static void main(String[] args) {
        Person p1 = new Student();
        Teacher t1 = (Teacher)p1;  // 编译可以通过,但是运行时会出现异常:ClassCastException
    }

}

class Person {   // 父类
    String name = "Person";
        int age;

    public Person(String name,int age) {
        this.name = name;
        this.age = age;
    }
    public Person() {

    }

    public void show() {
        System.out.println("我是 Person");
    }



}

class Student extends Person{   // 子类
    int studentId;
    String name = "Student";

    @Override
    public void show() {
        System.out.println("我是 Student");
    }

    public void ncee() {
        System.out.println("高考");
    }

}


class Teacher extends  Person{  // 子类
    int teacherId;
    String name = "Teacher";

    @Override
    public void show() {
        System.out.println("我是 Teacher");
    }


    public void teach() {
        System.out.println("教书育人");
    }
}
public class PersonTest{

    public static void main(String[] args) {
        Person p1 = new Student();
        Teacher t1 = (Teacher)p1;  // 编译可以通过,但是运行时会出现异常:ClassCastException
    }
}

在这里插入图片描述

报错原因:

  1. 编译不会报错是因为:我们将一个父类 Person 类型 强制向下转型为 了 Teacher 其中的一个子类,骗过了编译器,说这个类型就是这个。
  2. 运行报错是因为:编译器运行的时候,发现你给我 强制转换 过来的p1类型,与我本身 Teacher 没有任何关系,既不是 继承关系,也不是本身类的实例化。而是和我并列的 Student 类型,这样处理不对,报错: java.lang.ClassCastException

编译通过,运行不通过

public class PersonTest{
    public static void main(String[] args) {
        Person p1 = new Teacher();
        Student s1 = (Student)p1;  // 编译可以通过,但是运行时会出现异常:ClassCastException
    }
}

在这里插入图片描述

报错原因:

和上面一样。

编译不通过,运行不通过

public class PersonTest{
    public static void main(String[] args) {
        Student s1 = new Teacher();  
    }
}

在这里插入图片描述

报错原因:

左边赋值的 Student 与 右边 new 的 Teacher() 二者之间,没有继承关系,是两个并列不同的类类型,是无法相互强制赋值的。

编译无法通过,就像

String s1 = 123; 一样两个类型不一致,无法赋值。


编译通过,运行通过

直接使用对应的 向下强制转换为对应的类

public class PersonTest{
    public static void main(String[] args) {
        Person p1 = new Student();
        Student s1 = (Student)p1;   
        s1.ncee();   // Student 特有的方法

        Person p2 = new Teacher();
        Teacher t1 = (Teacher)p2;
        t1.teach();  // Teacher 特有的方法
    }
}

在这里插入图片描述


2. instanceof 操作符的使用

对应上述 强制向下转型 出现的 ClassCastException 可以预先使用 instanceof 操作符 进行一个判断。

需要注意的是: instanceof 是操作符,不是方法,所以可以直接使用,不需要导入包。

X instanceof Y 判断 X 是否是 Y的实例对象,或者 X 是否是 Y 的子类。如果是子类/是实例对象,返回 true, 不是返回 false

如下代码:

package blogs.blog1;


public class PersonTest{

    public static void main(String[] args) {
        Person p1 = new Student();
        Person p2 = new Teacher();

        System.out.println("p1 instanceof Student: "+ (p1 instanceof Student));
        System.out.println("p1 instanceof Person: "+(p1 instanceof Person));
        System.out.println("p1 instanceof Teacher: "+(p1 instanceof Teacher));

        System.out.println("***************************");

        System.out.println("p2 instanceof Teacher: "+(p2 instanceof Teacher));
        System.out.println("p2 instanceof Person: "+(p2 instanceof Person));
        System.out.println("p2 instanceof Student: "+(p2 instanceof Student));

    }

}

class Person {   // 父类
    String name = "Person";
    int age;

    public Person(String name,int age) {
        this.name = name;
        this.age = age;
    }
    public Person() {

    }

    public void show() {
        System.out.println("我是 Person");
    }


}

class Student extends Person{   // 子类
    int studentId;
    String name = "Student";

    @Override
    public void show() {
        System.out.println("我是 Student");
    }

    public void ncee() {
        System.out.println("高考");
    }

}


class Teacher extends  Person{  // 子类
    int teacherId;
    String name = "Teacher";

    @Override
    public void show() {
        System.out.println("我是 Teacher");
    }


    public void teach() {
        System.out.println("教书育人");
    }
}

重点代码:

public class PersonTest{

    public static void main(String[] args) {
        Person p1 = new Student();
        Person p2 = new Teacher();

        // 判断 p1 是否是 Student 的实例对象/子类,是返回 true, 不是返回 false
        System.out.println("p1 instanceof Student: "+ (p1 instanceof Student)); 
        // 判断 p1 是否是 Person 的实例地下/子类,是返回 true, 不是返回 false
        System.out.println("p1 instanceof Person: "+(p1 instanceof Person));
        System.out.println("p1 instanceof Teacher: "+(p1 instanceof Teacher));

        System.out.println("***************************");

        System.out.println("p2 instanceof Teacher: "+(p2 instanceof Teacher));
        System.out.println("p2 instanceof Person: "+(p2 instanceof Person));
        System.out.println("p2 instanceof Student: "+(p2 instanceof Student));


    }
}

在这里插入图片描述


举例使用 instanceof 进行一个预先的判断,再向下强制转换

public class PersonTest{
    public static void main(String[] args) {
        Person p1 = new Student();    // 向上转型,多态

        if(p1 instanceof Student) { // 判断 p1 是否是 Student 的实例/子类,是true,强制向下转换
            Student s1 = (Student)p1;
            System.out.println(s1.studentId);   // 子类特有的属性
            s1.ncee();                          // 子类特有的方法
        }
        System.out.println("*******************");

        if(p1 instanceof Teacher) { // 判断 p1 是否是 Teacher 的实例/子类,是true,强制向下转换
            Teacher t1 = (Teacher)p1;
            System.out.println(t1.teacherId);   // 子类特有的属性
            t1.teach();                         // 子类特有的方法
        }
        
        System.out.println("*******************");
        if(p1 instanceof Person) {  // 判断p1 是否是 Person 的实例/子类,是true,强制向下转换
            Person person = (Person)p1;
            person.show();
        }
    }
}

在这里插入图片描述


3. 总结:

  1. 向上转换,称为多态
  2. 多态中:想要调用子类中特有的属性/方法,可以强制向下转型 为对应的子类。
  3. 强制向下转型可能会出现:编译正常,运行异常:java.lang.ClassCastException 类异常
  4. 可以预先使用 instanceof 预先判断再强制向下转型,防止:强制向下转型失败报错:java.lang.ClassCastException 类异常

4. 最后:

限于自身水平,其中存在的错误,希望大家给予指教,韩信点兵——多多益善,谢谢大家,江湖再见,后会有期!!!


在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值