java向上转型和向下转型

我们知道,java这个狗一样的东西的三大特性:继承,封装,多态。

然后继承和多态带来的一个比较拗口的问题就是,对象转型问题,我们今天就来扯一下。

首先,规定一下转型的概念,我套用一下黄小斜大神在github上的说法,转型,指的是等号左侧引用类型的改变。

但是此时,有一个概念需要给大家普及一下,我猜测可能很多宝宝们都有这个疑惑,那就是引用(对象的引用)和对象是一个东东吗?

先说结论:引用是引用,对象是对象,两者不是一个东西。

先看代码

Animal animal = new Animal();

按照没有学习java之前的编程理解,或者说大家刚入门学的C语言的语法理解

Animal 是变量类型,animal是变量名,new Animal() 代表一个变量值(方法的返回值也可以看做一个变量值)。

翻译过来就是,我们将new Animal()方法的返回值赋值给Animal类型的变量,变量名为animal。

但是在java中,我们都说万事万物皆对象,那么再说变量啊就太low了,我们换个说法。

Animal是类型,animal是引用,new Animal()是一个Animal类的对象。animal是Animal一个类对象的引用。

需要注意的是,在java中,对象的唯一产出方式就是通过new关键字在堆中创建。

所以我们接下来就可以说为什么引用不是对象了,我们通过反证法。看代码

        Animal animal;
        animal = new Animal();

这两行代码和我们之前那句代码没有任何区别。假设animal是一个对象,那么我们为什么还要重新new一遍呢?显然,animal不是对象,“操纵的标识符实际是指向一个对象的引用”,也就是说animal是一个引用,是指向一个可以指向Animal类的对象的引用。真正创建对象的语句是右边的new Animal();

引用和对象属于多对多的关系。一个引用可以指向多个对象,

        Animal animal;
        animal = new Animal();
        animal = new Animal("乔治");

一个对象也可以被多个引用指向

        Animal animal1;
        animal1 = new Animal();
        Animal animal2 = animal1;

概念都说完了,我们开始进入正题,转型

父类Animal

package com.study.basicJava.extend.father;

public class Animal {
    public Animal(){

    }
    public Animal(String name){
        System.out.println(name);
    }
    public void run(){
        System.out.println("动物都会跑");
    }

    public void sing(){
        System.out.println("动物也会叫");
    }
}

子类Dog

package com.study.basicJava.extend.son;

import com.study.basicJava.extend.father.Animal;

public class Dog extends Animal {
    @Override
    public void run(){
        System.out.println("狗是用四条腿跑的");
    }

    public void seeHome(){
        System.out.println("狗可以看家");
    }
}

代码很简单,我们接下来开始讲向上转型,和向下转型。

向上转型,父类的引用可以指向子类对象。由范围小---》范围大

例如:

        //animal是Animal类的引用,new Dog()创建了一个子类对象
        //animal指向了Dog对象
        Animal animal = new Dog();

或者

 

这种情况下,虽然animal是个父类对象,但是由于他指向了一个子类对象,因此他可以

1 使用父类未被子类重写的方法------>animal.sing()------->"动物也会叫"

2 使用子类重写父类的方法--------->animal.run()---->"狗是用四条腿跑的"

但是子类独有的方法是不可以使用的--->animal.seeHome()----->编译无法通过。

向下转型,子类引用指向父类对象,范围大---->范围小

例如:Dog dog = new Animal();

这句代码编译时无法通过的,必须有强制类型转换:Dog dog = (Dog)new Animal();

这样虽然编译通过了,但是运行时会报错,ClassCastException,Animal类型无法被强转为Dog类型

但是,我们换一种写法

Animal animal = new Dog()

Dog dog = animal;

编译也不通过,但是,加上强制类型转换,Dog dog = (Dog)animal,编译通过,运行无误。

原因是什么呢?

重点还是在转型。第一种情况子类的引用直接指向了父类对象,那么子类拥有的方法父类可能并没有,那么引用将无法运行,因为父类对象中并没有这些方法。

第二种情况,父类引用指向了子类对象,子类对象又指向子类对象,安全无痛,因此没有任何毛病。

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值