zl程序教程

您现在的位置是:首页 >  Java

当前栏目

java类型转换——向上转型,向下转型

2023-02-18 16:27:07 时间

类型转换

我们通常把将一个类型强制转换为另外一个类型的过程称之为类型转换,本文所提到的对象类型转换,特指存在继承关系的对象,因为在Java中不存在继承关系的对象进行转换的时候会抛出java强制类型转换异常。

向上转型

父类引用指向子类对象为向上转型

fatherClass obj = new sonClass();

其中,fatherClass 是父类名称或接口名称,obj 是创建的对象,sonClass 是子类名称。

**向上转型就是把子类对象直接赋给父类引用,不用强制转换。**使用向上转型可以调用父类类型中的所有成员,不能调用子类类型中特有成员,最终运行效果看子类的具体实现。

向下转型

与向上转型相反,子类对象指向父类引用为向下转型

sonClass obj = (sonClass) fatherClass;

其中,fatherClass 是父类名称,obj 是创建的对象,sonClass 是子类名称。

向下转型可以调用子类类型中所有的成员,不过需要注意的是如果父类引用对象指向的是子类对象,那么在向下转型的过程中是安全的,也就是编译是不会出错误。但是如果父类引用对象是父类本身,那么在向下转型的过程中是不安全的,编译不会出错,但是运行时会出现我们开始提到的 Java 强制类型转换异常,一般使用 instanceof 运算符来避免出此类错误。

那么一直使用instanceof判断一下,再强转类型,代码有些繁琐复杂,从Java14之后提供了一种更简洁的写法:

//java14之前
if(animal instanceof Dog){
    Dog dog = (Dog) animal;
    dog.xxx();
}

//java14
if(animal instanceof Cat cat){
    cat.xxx();
}

举例

class A {
    public void print() {
        System.out.println("A:print");
    }
}

class B extends A {
    public void print() {
        System.out.println("B:print");
    }
}

public class Text {
    public static void main(String args[])
    {
        A a = new B();          //通过子类去实例化父类
        a.print();
    }
}
class A {
    public void print() {
        System.out.println("A:print");
    }
}

class B extends A {
    public void print() {
        System.out.println("B:print");
    }
    public void funcB(){
        System.out.println("funcB");
    }
}

class C extends A {
    public void print() {
        System.out.println("C:print");
    }
    public void funcC(){
        System.out.println("funcC");
    }
}

public class Text {
    public static void func(A a)
    {
        a.print();
        if(a instanceof B)
        {
            B b = (B)a;   //向下转型,通过父类实例化子类
            b.funcB();    //调用B类独有的方法
        }
        else if(a instanceof C)
        {
            C c = (C)a;  //向下转型,通过父类实例化子类
            c.funcC();   //调用C类独有的方法
        }
    }

    public static void main(String args[])
    {
        func(new A());
        func(new B());
        func(new C());
    }
}

总结

父子对象之间的转换分为了向上转型和向下转型,

它们区别如下:

向上转型 : 通过子类对象**(小范围)实例化父类对象(大范围),这种属于自动转换** 向下转型 : 通过父类对象**(大范围)实例化子类对象(小范围),这种属于强制转换**