Java细节篇之向下转型与向上转型

大家好,我是教授.F

无论是向上转型还是向下转型,前提条件是两个类存在继承关系。

转型指的是将类型的 运行类型 进行改变,为了调用子类中或父类中的方法。

向上转型:

语法:父类类型 引用名 = new 子类类型

向上转型能够调用父类的所有方法,但是不能调用子类的特有方法,因为编译类型为父类。

但是最终调用的效果还要看子类,因为如果子类和父类都有该方法,那么就会调用子类的方法。

案例:

package com.hspedu.detail_;

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

        //向上转型:父类的引用指向了子类的对象
        //语法: 父类类型 引用名 = new 子类类型
        Animal animal = new Cat();
        //Object obj = new Cat();//可以。Cat继承Animal,Animal继承Object。(跨了一级)

        //可以调用父类的所有成员(需遵守访问权限)
        //但是不能调用子类特有的成员
        //animal.catchMouse();
        //报错,因为在编译阶段,能调用那些成员,是由编译类型来决定的
        //编译器认为catchMouse应该在编译类型里面

        //最终运行效果看子类的具体实现
        //调用方法时,按照从子类开始查找方法,然后调用,规则跟方法调用规则一致
        animal.eat();//输出猫吃鱼
        animal.run();//输出跑
        animal.sleep();//输出睡
        animal.show();//输出你好
    }
}

//Animal类
public class Animal {
    String name = "动物";
    int age = 10;
    public void sleep(){
        System.out.println("睡");
    }
    public void run(){
        System.out.println("跑");
    }
    public void eat(){
        System.out.println("吃");
    }
    public void show(){
        System.out.println("你好");
    }
}

//Cat类
package com.hspedu.detail_;

public class Cat extends Animal{
        public void eat(){//方法重写
            System.out.println("猫吃鱼");
        }
        public void catchMouse(){//Cat特有的方法
            System.out.println("猫与老鼠");
        }
}

向下转型:

语法:子类类型 引用名 = (子类类型) 父类类型

向下转型能够调用子类的所有方法,但是不能调用父类的特有方法,因为编译类型为子类。

        注意:只能强转父类的引用,不能强转父类的对象,并且父类的引用必须指向的是当前目标类型的对象。

        这句话怎么理解?

意思是:

Animal animal = new Cat();//animal指向在堆里面的Cat对象
Cat cat = (Cat) animal;//原本animal指向Cat对象,所以可以强转
//将animal强转,形成cat,Cat指向cat对象
Dog dog = (Dog) animal;
//不行,animal指向Cat对象,Cat不能转为Dog,只能Cat转为cat
//父类的引用必须指向的是当前目标类型的对象。
//这里的引用animal,指向的目标类型就是Cat对象,
//所以能转向Cat对象,因为没指向Dog,所以不能转成Dog类型

解析如下图: 

案例:

//测试类
package com.hspedu.detail_;

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

        //向上转型:父类的引用指向了子类的对象
        //语法: 父类类型 引用名 = new 子类类型
        Animal animal = new Cat();//animal指向在堆里面的Cat对象
        //Object obj = new Cat();//可以。Cat继承Animal,Animal继承Object。(跨了一级)

        //可以调用父类的所有成员(需遵守访问权限)
        //但是不能调用子类特有的成员
        //animal.catchMouse();//报错,因为在编译阶段,能调用那些成员,是由编译类型来决定的

        //最终运行效果看子类的具体实现
        //调用方法时,按照从子类开始查找方法,然后调用,规则跟方法调用规则一致
        animal.eat();//输出猫吃鱼
        animal.run();//输出跑
        animal.sleep();//输出睡
        animal.show();//输出你好


        //cat的编译类型 Cat,运行类型是 Cat
        Cat cat = (Cat) animal;//原本animal指向Cat对象,所以可以强转
        //将animal强转,形成cat,Cat指向cat对象
        cat.catchMouse();
        //要求父类的引用类型必须指向的是当前目标类型的对象
        //Dog dog = (Dog) animal;
        //不行,animal指向Cat对象,Cat不能转为Dog,只能Cat转为cat
    }
}

//Animal类
public class Animal {
    String name = "动物";
    int age = 10;
    public void sleep(){
        System.out.println("睡");
    }
    public void run(){
        System.out.println("跑");
    }
    public void eat(){
        System.out.println("吃");
    }
    public void show(){
        System.out.println("你好");
    }
}

//Cat类
package com.hspedu.detail_;

public class Cat extends Animal{
        public void eat(){//方法重写
            System.out.println("猫吃鱼");
        }
        public void catchMouse(){//Cat特有的方法
            System.out.println("帽子老鼠");
        }
}

//Dog类
package com.hspedu.detail_;

public class Dog extends Animal{//Dog是Animal的子类
}

  • 16
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值