Java向上向下转型问题

来源:互联网 发布:北京新华电脑学校java 编辑:程序博客网 时间:2024/05/17 02:02

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

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

  • 对象方法的多态:方法的重载和重写(重载只要函数名一致即可,重写需要与父类保持一致)
  • 对象类型的多态:在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,当然现在的首要任务就是完成语言关。

原创粉丝点击