Java向上向下转型问题

面对对象有三大基本特性:继承,封装和多态。

多态是面对对象中技术最灵活的机制,它不但可以增加程序的可维护性,还可以提高代码的可读性,多态是依赖继承性的,甚至可以说是多态性是继承性的扩展。多态性分为对象方法的多态和对象类型的多态

  • 对象方法的多态:方法的重载和重写(重载只要函数名一致即可,重写需要与父类保持一致)
  • 对象类型的多态:在Java中,对象类型的多态可以分为向上转型和向下转型。向上转型是程序自动完成的,而向下转型必须明确指出要转型的子类型,这似乎强制的。

  • 向上转型(将子类类型转换为父类类型)
    The code:

class Person{
    public void tell(){
        System.out.print("父类person的tell()");
    }
}
class Student extends Person{
    public void tell(){
        System.out.print("子类Student的tell()");
    }
    public void print(){
        System.out.print("子类Stdudent的print方法");
    }
}
public class test{
    public static void main(String []args){
        Person per=new Student();
        per.tell();
    }
}

运行结果为:”子类Student的tell方法“。

向上转型是自动的,Person per = new Student() 将子类Student创建的对象向上转型为父类Person类型,它能够调用子类Student重写父类的tell方法,但是无法调用子类Student的print方法。因为子类的实例已经转型为父类了。(向上转型是自动的,转型后的实例可以调用子类中重写父类的方法,但是无法调用子类中没有重写的方法)

  • 向下转型(父类转型为子类)
    The code:
class Person1{
    public void tell(){
       System.out.println("父类Person的tell方法");
    }
    public void say(){
        System.out.println("父类Person的say方法");
    }
}
class Student1 extends Person1{
    public void tell(){
        System.out.println("子类Student的tell方法");
    }
    public void print(){
        System.out.println("子类Student的print方法");
    }
}
public class test1 {
    public static void main(String ages[]){
        Person1 per=new Student1();
        Student1 stu=(Student1)per;
        stu.tell();
        stu.print();
        stu.say();
    }
}

运行结果:
”子类Student的tell方法
子类Student的print方法
父类Person的say方法“

向下转型不是自发的,也就是说如果Student stu = new Person() 是会报错的。在进行对象的向下转型之前,必须先发生对象的向上转型,否则会报错。即,Person per = new Student()创建子类Student的实例并且赋值给父类Person引用,在Student stu = (Student)per中强制将per转换为子类对象stu实现向下转型。

只需要记住,最后相关联的一定都是要以实例化后的实例为标准,那才是真实存在的东西,其他的都只是简单的引用罢了

特例:

  • 子类重写父类的静态方法和子类重写父类的实例方法
class Person2{
    int i1=1;
    static int i2=10;
    public void tell(){
        System.out.println("父类person的实例方法tell");
    }
    public static void staticTell(){
        System.out.println("父类person的静态方法staticTell");
    }
}
class Student2 extends Person2{
    int i1=2;
    static int i2=20;
    public void tell(){
        System.out.println("子类Student的实例方法tell");
    }
    public static void staticTell(){
        System.out.println("子类Student的静态方法staticTell");
    }
}
public class test2 {
    public static void main(String []args){
        Person2 per=new Student2();
        System.out.println("i1="+per.i1+",i2="+per.i2);
        per.tell();
        per.staticTell();
        Student2 stu=(Student2)per;
        System.out.println("i1="+stu.i1+",i2="+stu.i2);
        stu.tell();
        stu.staticTell();
    }
}

运行结果:

这里写图片描述

分析:根据向上转型的规则,转型为父类的实例原则上应该是调用子类重写的父类方法的,但是上图中的红线箭头处调用的却是父类的方法。敲黑板了!
注意:

在运行时Java虚拟机把静态方法和所属的类绑定,而把实例方法和所属的实例绑定,成员变量(包括静态变量和实例变量)与所属的类绑定。

所以,上述的Java向上向下转型都需要遵循Java虚拟机的绑定规则。

封装类的继承关系

Character和Boolean类属于Object类的子类
Byte、Short、Integer、Long、Float和Double均属于Number类的子类

封装类属于引用数据类型,具有属性和方法,使用这些方法可以实现很多基本数据类型所没有的功能。封装类主要提供以下两个功能:
1、将基本数据类型封装后,可当作对象进行使用。
2、为基本数据类型提供各种转换功能,如将数值转换为字符串、将字符串转换为数值等。

小结:

Java是一门充满神奇的语言,但是核心与 C语言依赖于内存一样,它的JVM才是最终的大BOSS,重点需要攻克JVM,当然现在的首要任务就是完成语言关。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值