精华内容
下载资源
问答
  •   向上转型——用父类的引用变量去引用子类的实例(或者说子类对象给父类引用变量赋值),这是允许的。   向上转型之后,父类引用变量只能调用父类中的属性方法,不能访问子类独有的属性方法。如果父类访问...

    向上转型(隐式)

      向上转型——用父类的引用变量去引用子类的实例(或者说子类对象给父类引用变量赋值),这是允许的。
      向上转型之后,父类引用变量只能调用父类中的属性和方法,不能访问子类独有的属性和方法。如果父类访问的方法是子类重写的方法,则访问重写之后的方法。

      向上转型的前提要求是:在发生直接(间接)的继承(实现关系)的时候,才可以发生向上转型。

    class Animal {
    	public void move() {
    		System.out.println("移动");
    	}
    	public void sound() {
    		System.out.println("wuwu");
    	}
    }
    class Dog extends Animal {
    	@Override
    	public void sound() {
    		System.out.println("汪汪");
    	}
    }
    
    public static void main(String[] args) {
    	Animal animal = new Dog();// 子类实例化父类
    	animal.move();// 输出 汪汪
    	animal.sound(); // 输出 移动
    }
    

      animal是Animal类的对象,但是它是指向Animal子类Dog类实例化对象引用变量,Dog类重写了move()方法,所以animal调用move()的时候输出的是汪汪。

      向上转型在Java中非常非常常见,比如在使用集合的时候,经常写成List<T> list = new ArrayList<T>();的形式。另外说一句,集合体系是Java中超级经典的设计,从中可以学到我们面向对象中需要学习的大部分知识,要经常看看集合的源码。


    PS:向上转型之后的父类变量和普通父类变量只是在调用子类重写的方法上有区别其他地方没有区别
      向上转型之后的父类变量可以访问所有的父类属性和方法,包括private修饰的变量和方法,但是想要直接访问private修饰的变量和方法的前提是在父类中,因为private访问修饰符控制的范围就是一个类中可以访问。

      将子类对象向上转型赋值给父类变量,这个父类变量依旧不能直接访问父类中私有的部分,这里父类变量不能访问私有变量a的原因是定义这个父类变量的类是在Father类之外的Test类,在Father类外访问Father中的私有成员自然是不可以的了。
    在这里插入图片描述
      如果是在Father类中,定义一个父类变量指向子类对象,这个父类变量是可以直接访问父类中的私有成员。向上转型的父类变量和父类对象之间的区别是在调用父类中被重写的方法时,父类对象调用的是父类的方法,而子类向上转型得到的父类变量是调用子类中重写的方法在这里插入图片描述

    小结:

    • 向上转型:子类对象给父类引用变量赋值
    • 赋值规则:必须存在直接或间接的继承或实现关系,即上下级关系
    • 调用规则:父类对象仅能调用父类中的方法和属性(PS:若调用的是重写方法,那么调用的是子类中重写了的方法)

    向下转向(显式)

      向上转型是可以省略转换的类型,但是向下转型必须显示写出类型,如Fahter f = new Son(); Son s = (Son) f; 可有和基本数据类型相互转换中的自动类型转换和强制类型转换对比记忆。
      所有子类实例都可以向上转型赋值给父类引用变量,但是在向下转型的过程中,必须必须必须要考虑的问题是是否可以转换?只有通过向上转型的父类引用变量可以向下转型;如果父类引用的对象是父类本身,那么在向下转型的过程中是不安全的,编译不会出错,但是运行时会出现java.lang.ClassCastException异常——类型转换异常。这个异常可以通过instanceof关键字避免,如果左边的对象可以给右边的类赋值,返回true,否则返回false。

    public static void main(String[] args) {
    	Animal a = new Animal();
    	Animal b = new Dog();
    	Object c = new Dog();
    	Dog d = new Dog();
    	System.out.println(a instanceof Dog); // false
    	System.out.println(b instanceof Dog); // true
    	System.out.println(c instanceof Dog); // true
    	System.out.println(c instanceof Animal);// true
    	System.out.println(d instanceof Dog);// true
    }
    

    为什么要向上转型和向下转型?

      可以对一个父类的所有子类进行通用操作,减少重载方法的声明,提高效率。
      比如,现在有两个集合的数据想要输出到文本中保存,一个是ArrayList集合,另一个是HashSet集合,那我们定义输出方法的时候就需要定义两个方法,一个方法的参数是ArrayList集合,一个方法的参数是HashSet集合

    public void output (ArrayList <T>) {
    	// 将ArrayList集合输出到文本中的代码
    }
    public void output (HashSet <T>) {
    	// 将HashSet集合输出到文本中的代码
    }
    

      可以看到上面两种代码中必将有大量的相似代码,如果我们使用向上转型只需要声明一个方法,方法参数是Collection。

    public void output (Collection <T>) {
    	// 将Collection集合输出到文本中的代码
    }
    

      向上向下转型可以帮我们减少很多代码,具体如何输出引用数据类型的对象到文本中需要学习IO那一部分的知识,这里简单说一下,需要使用ObjectOutputStream
    向上转型和向下转型的意义

    展开全文
  • 今天做了一个测试的题目,发现自己还是很多问题没有静下心...java中对象的转型分为向上转型和向下转型 一、对象向上转型  1.1、定义  子类引用的对象转换为父类类型称为向上转型。通俗地说就是是将子类对象转...

    今天做了一个测试的题目,发现自己还是很多问题没有静下心来做。很多问题是可以自己解决的但是自己一是没有读清题意,二是自己心里太急躁了。所以这个要自己应以为鉴!

     对象的转型问题其实并不复杂,我们记住一句话:“父类引用指向子类对象”。

    java中对象的转型分为向上转型和向下转型

    一、对象的向上转型

      1.1、定义

        子类引用的对象转换为父类类型称为向上转型。通俗地说就是是将子类对象转为父类对象。此处父类对象可以是接口

      1.2、解释

        比如说我有两个类,一个是父类Animal,另一个是Bird类为子类。

        Animal b = new Bird();

        这就是upcasting,向上转型。这时b就是执行以恶搞Bird对象。

      1.3、实例

     

    package com.zyh.test;
    
    public class Animal {
        public void eat(){
            System.out.println("animal eating....");
        }
    }
    class Bird extends Animal{
        public void eat(){
            System.out.println("Bird eating...");
        }
        public void fly(){
            System.out.println("Bird flying...");
        }
    }
    class Main{
        public static void main(String[] args){
            Animal b1 = new Bird();
            b1.eat();
    //        b1.fly();  b虽然指向子类对象,但此时丢失了fly方法
            doSleep(new Male());
            doSleep(new Female());
            
        }
        public static void doSleep(Human h){
            h.sleep();
        }
    }
    Animal.java
    package com.zyh.test;
    
    public class Animal {
        public void eat(){
            System.out.println("animal eating....");
        }
    }
    class Bird extends Animal{
        public void eat(){
            System.out.println("Bird eating...");
        }
        public void fly(){
            System.out.println("Bird flying...");
        }
    }
    class Main{
        public static void main(String[] args){
            Animal b1 = new Bird();
            b1.eat();
    //        b1.fly();  b虽然指向子类对象,但此时丢失了fly方法
            doSleep(new Male());
            doSleep(new Female());
            
        }
        public static void doSleep(Human h){
            h.sleep();
        }
    }
    Huamn

     

      注意:

        这里的向上转型:

          Animal b = new Bird();

           b.eat();

        这里调用的eat方法是子类的。因为b实际指向的是Bird子类,故调用时会调用子类本身的方法。

        要记住向上转型时父类的引用会遗失除与父类共有的其他方法。在上面的例子中b不能调用fly方法。

        向上转型时,父类指向子类引用对象会遗失除与父类对象共有的其他方法,也就是在转型过程中,子类的新有的方法都会遗失掉,在编译时,系统会提供找不到方法的错误。

      1.4、向上转型的优点 

        public static void dosleep(Human h) {
        h.sleep();
          }

        这里以父类为参数,调有时用子类作为参数,就是利用了向上转型。这样使代码变得简洁。不然的话,
        如果dosleep以子类对象为参数,则有多少个子类就需要写多少个函数。这也体现了JAVA的抽象编程思想。

    二、对象的向下转型

      1.1、定义

        父类引用的对象转换为子类类型成为向下转型

      1.2、解释

        Son s = (Son)f1;

        这就是downcasting,向下转型。

      1.3、实例

    package com.zyh.test;
    
    public class Person {
        public void play(){
            System.out.println("Person play...");
        }
    }
    class Boy extends Person{
        public void play(){
            System.out.println("boy play...");
        }
        public void run(){
            System.out.println("run play...");
        }
    }
    class RunMain{
        public static void main(String[] args){
            Person b = new Boy();//向上转型
            b.play();
            System.out.println("-------------------------");
            Boy b1 =(Boy)b;//向下转型
            b1.play();
            b1.run();
            
        }
    }

      结果:

        

      在这个程序中       

        Girl g1=new MMGirl(); //向上转型
        g1.smile();
        MMGirl mmg=(MMGirl)g1; //向下转型,编译和运行皆不会出错

        这里的向下转型是安全的。因为g1指向的是子类对象。

            而
        Girl g2=new Girl();
        MMGirl mmg1=(MMGirl)g2; //不安全的向下转型,编译无错但会运行会出错

        运行出错:

        Exception in thread "main" java.lang.ClassCastException: com.wensefu.other1.Girl
        at com.wensefu.other1.Main.main(Girl.java:36)

      所以向下转型过程中要注意的是:     

        情况一:如果父类引用的对象如果引用的是指向的子类对象,那么在向下转型的过程中是安全的。也就是编译是不会出错误的。

        情况二:如果父类引用的对象是父类本身,那么在向下转型的过程中是不安全的,编译不会出错,但是运行时会出现java.lang.ClassCastException错误。它可以使用instanceof来避免出错此类错误。

     三、总结

    1、父类引用可以指向子类对象,子类引用不能指向父类对象。

    2、把子类对象直接赋给父类引用叫upcasting向上转型,向上转型不用强制转型。

       如Father father = new Son();

    3、把指向子类对象的父类引用赋给子类引用叫向下转型(downcasting),要强制转型。

       如father就是一个指向子类对象的父类引用,把father赋给子类引用son 即Son son =(Son)father;

       其中father前面的(Son)必须添加,进行强制转换。

    4、upcasting 会丢失子类特有的方法,但是子类overriding 父类的方法,子类方法有效

    5、向上转型的作用,减少重复代码,父类为参数,调有时用子类作为参数,就是利用了向上转型。这样使代码变得简洁。体现了JAVA的抽象编程思想。

     

     

     

    转载于:https://www.cnblogs.com/cxyzyh2017/p/7215430.html

    展开全文
  • 向下转型:多态回归 如何才能知道一个父类引用的对象,本来是什么子类? 格式:对象 instanceof 类名称 返回值:boolean,判断前面的对象能不能当作后面类型的实例 /*Demo.java*/ public class Demo { public ...

    多态:Animal animal = new Dog();
    左父右子
    向上转型:多态
    向下转型:多态回归

    如何才能知道一个父类引用的对象,本来是什么子类?

    格式:对象 instanceof 类名称
    返回值:boolean,判断前面的对象能不能当作后面类型的实例

    /*Demo.java*/
    public class Demo {
        public static void main(String[] args) {
            Animal animal = new Dog(); // 本来是一只狗
            animal.eat(); // 狗吃SHIT
    
            // 如果希望掉用子类特有方法,需要向下转型
            // 判断一下父类引用animal本来是不是Dog
            if (animal instanceof Dog) {
                Dog dog = (Dog) animal;
                dog.watchHouse();
            }
            // 判断一下animal本来是不是Cat
            if (animal instanceof Cat) {
                Cat cat = (Cat) animal;
                cat.catchMouse();
            }
    
            giveMeAPet(new Dog());
        }
    
        public static void giveMeAPet(Animal animal) {
            if (animal instanceof Dog) {
                Dog dog = (Dog) animal;
                dog.watchHouse();
            }
            if (animal instanceof Cat) {
                Cat cat = (Cat) animal;
                cat.catchMouse();
            }
        }
    }
    
    
    /*Cat.java*/
    public class Cat extends Animal{
        @Override
        public void eat() {
            System.out.println("猫吃鱼");
        }
        public void catchMouse() {
            System.out.println("猫抓老鼠");
        }
    }
    
    
    /*Dog.java*/
    public class Dog extends Animal{
        @Override
        public void eat() {
            System.out.println("狗吃骨头");
        }
        public void watchHouse() {
            System.out.println("狗看家");
        }
    }
    
    
    /*Animal.java*/
    public abstract class Animal {
        public abstract void eat();
    }
    
    

    参考连接:https://www.bilibili.com/video/BV1uJ411k7wy
    p190-192

    展开全文
  • 在一个子类被创建的时候,首先会在内存中创建一个父类对象,然后在父类对象外部放上子类独有的属性,两者合起来形成一个子类的对象,所以子类可以继承父类中所有的属性方法,包括private修饰的属性方法,但是...

    前言:Java中的继承机制使得一个类可以继承另一个类,继承的类称为子类,被继承的类称为父类。在一个子类被创建的时候,首先会在内存中创建一个父类对象,然后在父类对象外部放上子类独有的属性,两者合起来形成一个子类的对象,所以子类可以继承父类中所有的属性和方法,包括private修饰的属性和方法,但是子类只是拥有父类private修饰的属性和方法,却不能直接使用它,也就是无法直接访问到它(子类可以通过调用父类的public声明的get方法来获取父类的private属性,但无法访问父类的private方法)。同时子类可以对继承的方法进行重写(@Override),并且新建自己独有的方法。

    一、转型的分类和动态绑定介绍

    1、转型的分类

    转型是在继承的基础上而言的,继承是面向对象语言中,代码复用的一种机制,通过继承,子类可以复用父类的功能,如果父类不能满足当前子类的需求,则子类可以重写父类中的方法来加以扩展。

    向上转型:子类引用的对象转换为父类类型称为向上转型。通俗地说就是用父类的引用变量去引用子类的实例对象,此处父类对象可以是接口。向上转型属于自动类型转换。

    向下转型:父类引用的对象转换为子类类型称为向下转型。向下转型属于强制类型转换。

    2、动态绑定介绍

    程序绑定的概念:绑定指的是一个方法的调用与方法所在的类(方法主体)关联起来。对Java来说,绑定分为静态绑定和动态绑定,或者叫做前期绑定和后期绑定

    静态绑定:在程序执行前方法已经被绑定,此时由编译器或其它连接程序实现。例如:C。针对Java简单的可以理解为程序编译期的绑定;这里特别说明一点,Java当中的方法只有final,static,private和构造方法是前期绑定
    动态绑定:

    动态绑定:在运行时根据具体对象的类型进行绑定。若一种语言实现了后期绑定,同时必须提供一些机制,可在运行期间判断对象的类型,并分别调用适当的方法。也就是说,编译器此时依然不知道对象的类型,但方法调用机制能自己去调查,找到正确的方法主体。不同的语言对后期绑定的实现方法是有所区别的。但我们至少可以这样认为:它们都要在对象中安插某些特殊类型的信息。

    动态绑定的过程:JVM虚拟机提取对象的实际类型的方法表—>JVM虚拟机搜索方法签名—>调用方法。

    二、向上转型

    1、前篇文章提到过,在多态中需要将子类的引用赋给父类对象,只有这样该引用才能够具备调用该子类的方法的能力,其实这就是向上转型。

    向上转型,就是用父类的引用变量去引用子类的实例,这是允许的。当向上转型之后,父类引用变量可以访问子类中属于父类的属性和方法,但是不能访问子类独有的属性和方法,因为向上转型后子类对象会丢失身份。

    2、举个栗子:

    假设有一个Fruit类,Fruit类中有一个show()方法,代码如下:

    class Fruit{
    	public void show() {
    		System.out.println("this is a fruit");
    	}
    }

    有一个Apple类继承自Fruit类,该类有自己的方法test(),并且重写了父类的show()方法,代码如下:

    class Apple extends Fruit{
        @Override
        public void show() {
    	System.out.println("this is a apple");
        }
        public void test() {
    	System.out.println("I am a apple");
        }
    }

    实例化Apple类,并新建一个Fruit类的引用变量引用该实例,调用实例的show()方法:

    Fruit fruit = new Apple();//自动类型转换
    fruit.show();

    运行结果如下图所示:

    向上转型需要注意的问题:

    向上转型时,父类指向子类引用对象会遗失除与父类对象共有的其他方法,也就是在转型过程中,子类的新有的方法都会遗失掉,在编译时,系统会提供找不到方法的错误。

    所以,子类对象当成父类对象,只能调用父类的成员,如果子类重写了父类的方法,就根据这个引用指向调用子类重写的这个方法。这个调用过程就称为“动态绑定”。

    三、向下转型

    并不是所有的对象都可以向下转型,只有当这个对象原本就是子类对象通过向上转型得到的时候才能够成功转型。

    /*
    *  第一段代码
    **/
    Fruit fruit = new Apple();
    Apple apple = (Apple) fruit;//强制类型转换
    
    /*
    *  第二段代码
    **/
    class Orange extends Fruit{
        @Override
        public void show() {
    	System.out.println("this is a Orange");
        }
        public void test() {
    	System.out.println("i am a Orange");
        }
    }
    
     Fruit fruit = new Apple();
     Orange orange = (Orange) fruit;//强制类型转换

    代码分析:

    第一段代码向下转型成功:因为fruit引用的对象原本就是Apple对象向上转型得到的,在对fruit向下转型后得到的还是Apple类的对象,能够被Apple类的引用变量引用;

    第二代码向下转型失败:上述代码虽然能够编译成功,但是在运行的时候会报错,因为fruit对象是由Apple对象向上转型得到的,只能够向下转型成Apple对象,不能够向下转型成Orange对象。

    总结:

    情况一:如果父类引用的对象如果引用的是指向的子类对象,那么在向下转型的过程中是安全的。也就是编译是不会出错误的。

    情况二:如果父类引用的对象是父类本身或者原本不是子类对象,那么在向下转型的过程中是不安全的,编译不会出错,但是运行时会出现java.lang.ClassCastException错误。它可以使用instanceof来避免出错此类错误。

    四、转型的好处

    通过向上向下转型肯定是有好处的,比如可以减少编程代码。

    假设在主类中定义了一个run()方法,该方法传入一个Fruit参数,并调用了Fruit对象的show()方法,代码如下:

    public static void run(Fruit fruit) {
    	fruit.show();
       }

    在main()方法中的代码如下:

    public static void main(String[] args) {
        run(new Fruit());
        run(new Apple());
        run(new Orange());
        }

    上述代码中,调用run()方法时的参数不仅是Fruit对象,也可以是Apple对象和Orange对象,当传入的是Apple对象和Orange对象时,就会向上转型成Fruit对象,但是调用的show()方法还是Apple对象和Orange对象的show()方法。这样就不需要在主类中同时重载三个run()方法,减少了代码量
     

    注意:向上转型常用于多态中,既能减少代码量,又能提高程序的扩展性。

    展开全文
  • 今天做了一个测试的题目,发现自己还是很多问题没有静下心来做。...java中对象的转型分为向上转型和向下转型 一、对象向上转型  1.1、定义  子类引用的对象转换为父类类型称为向上转型。通俗地说就是是将...
  • 对象向上转型 对象向上转型,就是多态的写法。 格式: 父类名称 对象名 = new 子类对象名称(); Animal animal = new Cat(); 含义: 右侧创建一个子类对象,把它当做父类来看。 注意事项: 向上转型一定是...
  • 一、对象向上转型  1.1、定义  子类引用的对象转换为父类类型称为向上转型。通俗地说就是是将子类对象转为父类对象。此处父类对象可以是接口  1.2、解释  比如说我有两个类,一个是父类Animal,另一个是...
  • 对象向上转型和向下转型

    千次阅读 2018-07-13 15:17:16
    对象向上转型 对象向上转型,就是多态的写法。 格式: 父类名称 对象名 = new 子类对象名称(); Animal animal = new Cat(); 含义: 右侧创建一个子类对象,把它当做父类来看。 注意事项: 向上转型一定是...
  • Java对象类型向上转型和向下转型

    万次阅读 多人点赞 2019-03-20 19:16:43
    在一个子类被创建的时候,首先会在内存中创建一个父类对象,然后在父类对象外部放上子类独有的属性,两者合起来形成一个子类的对象,所以子类可以继承父类中所有的属性方法,包括private修饰的属性方法,但是...
  • Java向上转型和向下转型

    千次阅读 多人点赞 2017-07-20 15:43:38
    Java向上转型和向下转型
  • java面向对象向上转型和向下转型

    千次阅读 2016-03-08 16:42:01
    转型是在继承的基础上而言的,继承是面向对象语言中,代码复用的一种机制,通过继承,子类可以复用父类的功能,...向下转型:父类引用的对象转换为子类类型称为向下转型。 前者是一个向上转型,Animal dog 引用指向
  • 对象转型分为两种:一种叫向上转型(父类对象的引用或者叫基类对象的引用指向子类对象,这就是向上转型),另一种叫向下转型。转型的意思是:如把float类型转成int类型,把double类型转成float类型,把long类型转成int...
  • 向上转型和向下转型

    2018-07-14 09:27:49
    1、向上转型:子类对象赋值给父类类型的变量,即父类对象引用,指向子类对象;2、向下转型:是将抽象类转换为较具体的类。在执行向下转型时,需用instanceof操作符判断父类对象是否为子类对象的实例。...
  • 2.对象的转型 面向对象程序设计的特点:分装,继承,多态 多态分为对象多态行为多态 对象多态是指对象具有不同的状态 ...对象向下转型对象向上转型的逆操作. 先有向上转型才能向下转型 2.3 instanceof
  • 1.向上转型:本质是多态的体现 格式:父类名称 对象名 = new 子类名称(); Animal animal = new Cat(); 含义:右侧创建一个子类对象,把它当成父类来看待使用。 创建一支猫,把它当成动物来看。 注意事项:...
  • 多态的好处和弊端以及对象向上转型和向下转型 多态的好处 提高了代码的可维护性(继承保证) 2.提高了代码的扩展性(由多态保证) // An highlighted block var foo = 'bar';
  • 多态首先什么是多态?...3.最重要的是一定要有父类的指针指向子类的对象或者说父类的引用指向子类的空间 下面我们举个例子,动物是父类,猫是子类class Animal { String name = "动物"; String color
  • 向上转型和向下转型是在JAVA继承操作中用到的东西,在讲到转型之前我们需要认识到继承过程中的对象类型转换,这种转换有两个特点: 1.这是继承过程中发生的操作 2.新类是现有类的一种类型。这种说法主要是因为...
  • 1.向上转型:就是你定义了一个子类对象但是...2.向下转型向下转型就相反,创建父类的对象,声明为子类类型 Child obj = (child)object ;object 是刚才创建的父类对象 强制转换 注意: 1.向上转型的父类类...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 30,211
精华内容 12,084
关键字:

对象的向上转型和向下转型