黑马程序员技术交流社区

标题: 转型 [打印本页]

作者: 何武    时间: 2013-7-27 17:58
标题: 转型
本帖最后由 杨兴庭 于 2013-7-29 11:06 编辑

什么情况下使用转型,怎么进行转型?
作者: の放下执著    时间: 2013-7-27 19:19
转型用在有继承关系的子父类中:
如:定义了一个Animal类,再定义了一个Dog类,Dog类继承了Animal类。
Animal a = new Dog();//多态,向上转型,不用强转。
if(a instanceof Dog)
  Dog d  =  (Dog) a;//当父类转向子类时,向下转型,用强转。
作者: 黑马李昂    时间: 2013-7-29 00:52
当父类的引用指向子类对象时,子类会自动向父类转型,又叫作是向上转型,其作用是限制对特有功能的访问。
当想要调用子类的特有方法时,就需要该子类对象进行手动的向下转型。数据类型的转换格式就是:(目标类型)被转的数据。
当对象需要向下转型之前,需要对该对象进行判断,判断传入的对象是否是父类的子类对象,用instancsof进行判断,用于判断对象的具体类型,目的是提高代码的健壮性。
可以参考以下例子:
abstract class Animal{
abstract void eat();
}
class Dog extends Anima{
void eat(){
  System.out.println("goutou");
}
void lookHome(){
  System.out.println("kanjia");
}
}
class Cat  extends Animal{
void eat(){
  System.out.println("xiaoyu");
}
void play(){
  System.out.println("piqiu");
}
}
class  DuoTaiDemo{
public static void main(String[] args) {
    Cat c = new Cat();
    Animal a = new Cat();//自动类型提升,猫提升为动物类型。
       //作用就是限制对特有功能的访问。
       //向上转型。
     a.eat();
  //如果还想用具体动物的特有功能。
  //将该对象进行向下转型。
    Cat c  = (Cat)a;//向下转型的目的是为了实现子类的特有方法。
    c.play();
     //注意:对于转型,自始至终都是子类对象在做着类型的变化。
  method(new Dog());
}
public static void method(Animal a) {
  a.eat();
  if (a instanceof Cat)//用于判断对象的具体类型。只能用于引用数据类型的判断。
       //通常用在向下转型前健壮性的判断。
  {
   Cat c =(Cat)a;
   c.play();
  }
  else if (a instanceof Dog){
   Dog d = (Dog)a;
   d.lookHome();
  }
}
  希望对您有所帮助{:soso_e100:}


作者: Mr_Free    时间: 2013-7-29 04:22
本帖最后由 Mr_Free 于 2013-7-29 04:25 编辑
  1. package wenti;
  2. //转型分向上转型 和向下转型;
  3. //写个例子:

  4. class wenti5{
  5.         public static void main(String[] args){
  6.                 Fu erzi = new Zi();//这是你如果要调用儿子的特有的方法,就必须向下转型
  7.                 Zi er =(Zi)erzi;
  8.                 er.erziteyou();
  9. //                至于为什么要向上转型是这样的,一般父类是一些大家共有的方法,现在我想让所有子
  10. //                类都做同样父类有的方法,而你每次执行的话创建对象,然后用对象一个一个调用写起来有些麻烦,
  11. //                所以,你可以考虑把父类的方法执行,封装成一个类中的静态方法,在传入参数的时候写你要执行的对象
  12. //                这样的好处是避免了代码重复。下面我写一个例子
  13.                 Fu fuDo = (Fu)er;//向上转型。为了调用function方法
  14.                 Fu nver =new daughter();
  15.                 function.fufunctionDo(fuDo);//执行父类方法
  16.                 function.fufunctionDo(nver);//执行父类方法
  17.         }
  18.         
  19. }
  20. class daughter extends Fu{
  21.         public  void nverteyou(){
  22.                 System.out.println("这方法女儿特有,爹爹没有");
  23.         }
  24.       public  void showzi(){
  25.              System.out.print("showzi");
  26.     }
  27.           public  void chi(){
  28.                 System.out.println("女儿chi");
  29.         }
  30.         public  void he(){
  31.                 System.out.println("女儿he");
  32.         }
  33.         public  void shui(){
  34.                 System.out.println("女儿shui");
  35.         }
  36. }
  37. class Fu{


  38.         public  void chi(){
  39.                 System.out.println("chi");
  40.         }
  41.         public  void he(){
  42.                 System.out.println("he");
  43.         }
  44.         public  void shui(){
  45.                 System.out.println("shui");
  46.         }
  47.     public  void showfu(){
  48.                 System.out.print("showfu");
  49.      }
  50. }
  51. class Zi extends Fu{
  52.                 public  void erziteyou(){
  53.                         System.out.println("这方法儿子特有,爹爹没有");
  54.                 }
  55.           public  void showzi(){
  56.                  System.out.print("showzi");
  57.         }
  58.               public  void chi(){
  59.                     System.out.println("zichi");
  60.             }
  61.             public  void he(){
  62.                     System.out.println("zihe");
  63.             }
  64.             public  void shui(){
  65.                     System.out.println("zishui");
  66.             }
  67. }
  68. class function{
  69.         public static void fufunctionDo(Fu fu){
  70.                 fu.chi();
  71.                 fu.he();
  72.                 fu.shui();
  73.         }
  74. }
复制代码

作者: Hello_world_    时间: 2013-7-29 07:25
父子类之间实例方法采用的是动态绑定,即运行时绑定类型而非编译时,所以f在运行时指向的是Child对象,所以调用子类方法,而对于实例变量则采用静态绑定,即编译时决定的,编译做的事主要是就是把java文件编译成.class文件,而接下来Java虚拟机会把.class文件装载到虚拟机中进行包括验证,静态变量初始化,符号引用转直接引用等,做好了这些,执行器会执行.class文件,相应的会有对象的初始化等,说了这么多有点跑题的话,我只想说的是编译时是不知道f实际的指向的,只知道f是Father类型的,所以f.a拿到的是父类的变量a的值。这是JAVA的多态特征

希望你能看明白!
作者: Hello_world_    时间: 2013-7-29 08:39
a)  向上类型转换(upcast):比如说将Cat 类型转换为 Animal 类型,即将子类型
转换为父类型。对于向上类型转换,不需要显式指定。
b)  向下类型转换(downcast):比如将Animal 类型转换为 Cat 类型。即将父类型
转换为子类型。对于向下类型转换,必须要显式指定(必须要使用强制类型
转换)
作者: 續寫↖完羙↘    时间: 2013-7-29 11:42
当你想要调用子类的特有方法时,使用下转型。强制父类的引用,转成子类的类型,即为下转型。




欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/) 黑马程序员IT技术论坛 X3.2