A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© 与梦逆风而行 中级黑马   /  2014-11-29 21:05  /  962 人查看  /  0 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

本帖最后由 与梦逆风而行 于 2014-11-29 21:18 编辑

多态1.多态性
在继承关系中,一个子类对象不仅具有其本身类所具有的形态,还具有其父类对象所具有的形态,成该对象具有多种形态,这种关系叫做多态

JAVA引用变量有两个类型,一个是编译时类型,一个是运行时类型,编译时类型由声明该变量时使用的类型决定,运行时类型由实际赋值给该变量的对象决定。如果编译时类型和运行时类型不一致,就可能出现所谓的多态。

相同类型的变量,调用同一个方法时呈现出多种不同的行为特征,这就是多态。
与方法不同的是,对象的Field则不具备多态性。

引用变量在编译时只能调用其编译时类型所具有的方法,但运行时则执行它运行时类型所具有的方法,因此,编写JAVA代码时,引用变量只能调用声明该变量时所用类里的方法,例如:Object p = new Person();
代码定义了一个变量p,则这个p只能调用Object类的方法,而不能调用person类里定义的方法。

通过引用变量来访问其包含的实例Field时,系统会试图访问它编译时类型所定义的Field,而不是它运行时类型所定义的Field。



举例

class BaseClass
{
       public int book=6;
       public void base(){
              System.out.println("父类的普通方法");
       }
       public void test(){
              System.out.println("父类的被覆盖的方法");
       }
}
public classSubClass extends BaseClass
{
       //重新定义一个book实例Field,隐藏父类的book实例Field
       public String book="轻量级JAVA";
       public void test(){
              System.out.println("子类的覆盖父类的方法");
       }
       public void sub(){
              System.out.println("子类的普通方法");
       }
       public static void main(String[] args){
              //下面编译时类型和运行时类型完全一样,不存在多态
              BaseClass b = new BaseClass();
              System.out.println(b.book);
              //下面两次调用将执行BaseClass方法
              b.base();
              b.test();
              //下面编译时类型和运行时类型不一样,多态发生
              BaseClass p = new SubClass();
              //输出6-----表明访问的是父类的Field
              System.out.println(p.book);
              //下面调用将执行从父类继承到的base方法
              p.base();
              //下面调用将执行当前类的test方法
              p.test();
              //因为p的编译时类型是BaseClass
              //BaseClass没有提供sub方法,所以下面的代码编译时会出现错误
              //p.sub();
       }
}



2.引用变量的强制类型转换
强制类型转换时需要注意:
1.基本数据类型之间的转换只能在数值类型之间进行,这里所说的数值类型包括整数型,字符型和浮点型,但数值型和布尔类型之间不能进行类型转换。
2.引用类型之间的转换只能在具有继承关系的两个类型之间进行,如果是两个没有任何继承关系的类型,则无法进行转换。如果试图把一个父类实例转换成子类类型,则这个对象必须实际上是子类实例才行(即编译时类型为父类类型,运行时类型为子类类型),否则将在运行时引发ClassCastException异常。


3.面试题
/*
*1.使用创建对象时候new先在堆内存中进行内存空间的分配,并对结构进行初始化
*2.初始化父类的对象super
*3.实例代码块
*4.初始化子类的对象,执行构造方法
*/

class Father{
       int a = 1;
       Father(){                      //----------------------(1)
              show();                 //---------------------(2)将执行(3)的结果  son 0
       }
       void show(){
              System.out.println("father"+a);
       }
}
class Son extendsFather{
       Son(){
              super();
              System.out.println("-----------------------");
              show();                        //---------------------------------------(4)son 10
       }
       int a = 10;
       /*
       int a = 10;
       int a;                                   //创建对象,内存空间分配时完成的
       //初始化super
       a = 10;                                //父类对象创建完毕后做的  
       */
       void show(){
              System.out.println("son"+a);//----------------(3)  son 0
       }
}
public classDemo1{
       public static void main(String[] args){
              Father f = new Son();
       }
}



Java的子类不能获得父类的构造器?但子类构造器里可以调用父类构造器的初始代码块。


0 个回复

您需要登录后才可以回帖 登录 | 加入黑马