JAVA基础复习与总结<一>(2) 父类引用指向子类对象(向上转型、动态链接)


public class Animal {    public static void main(String[] args){      Animal animal = new Cat();      animal.voice();      drinkWater(animal);                         //调用静态方法,传入的是父类引用的子类对象

}

String str;    public void voice(){        System.out.println("普通动物叫声!");    }    public static void drinkWater(Animal animal){    //静态方法,传入的是animal父类对象        System.out.println(animal.getClass().getName() +" drink water!");    }

}

class Cat extends Animal {    public void voice(){        System.out.println("喵喵喵");    }    public void catchMouse(){        System.out.println("抓老鼠");    }

p.p1 { margin: 0.0px 0.0px 0.0px 0.0px; line-height: 16.0px; font: 14.0px "PingFang SC"; color: #000000 }
p.p2 { margin: 0.0px 0.0px 0.0px 0.0px; line-height: 16.0px; font: 18.0px "PingFang SC"; color: #000000 }
p.p3 { margin: 0.0px 0.0px 0.0px 0.0px; line-height: 16.0px; font: 14.0px "Courier New"; color: #000000 }
span.s1 { }
span.s2 { font: 18.0px "Courier New" }
span.s3 { font: 14.0px "PingFang SC" }
span.s4 { font: 12.0px "Courier New" }
span.s5 { font: 14.0px "Courier New" }

声明的是父类,实际上指向的却是子类,主要思想是:多态、动态链接、向上转型。

向上转型:

定义了子类对象Cat,Cat对象继承了Animal类,Animal是Cat的父类。当我们使用Aniaml cat = new Cat();的时候,Animal类型的引用是可以指向Cat类型的对象的。

子类是对父类的扩充,一般在子类中具有父类没有的属性和方法。当我们使用向上转型之后,定义的一个父类类型的引用指向一个子类的对象既可以使用子类对象的强大功能,又直接实现父类的共性。

这样做的好处是当我们在处理大型工程时会遇到一个父类中继承出多个子类。而且不可避免的会使用到相当多的static方法,而static方法的参数最好传入一个父类对象。

当我们需要重新添加一种子类的时候,使用向上转型,就可以直接将这个子类对象丢进static方法了,而不用担心不兼容。否则不使用向上转型的话,每出现一个新的子类,我们要调用已经存在的方法,都要将方法再重写一遍,加上新的参数类,这样得不偿失,重用性差,代码长度过长。

我们也不能把static方法丢进父类里面去,虽然这样做会使得子类可以直接继承父类方法而不考虑向上转型的问题,但是这样会造成父类过于臃肿,是设计模式的问题。

动态链接:

当父类的一个方法只有在父类中定义而在子类中没有重写的情况下,才可以被父类类型的引用调用;对于父类中定义的方法,如果子类中重写了该方法,那么父类类型的引用将会调用子类中的这个方法,这就是动态链接。


 

原文地址:https://www.cnblogs.com/ErictChandler/p/9571635.html

时间: 2024-08-29 04:05:25

JAVA基础复习与总结<一>(2) 父类引用指向子类对象(向上转型、动态链接)的相关文章

java父类引用指向子类对象

父类引用指向子类对象指的是: 例如父类Animal,子类Cat,Dog.其中Animal可以是类也可以是接口,Cat和Dog是继承或实现Animal的子类. Animal animal = new Cat(); 即声明的是父类,实际指向的是子类的一个对象. 那这么使用的优点是什么,为什么要这么用?可以用这几个关键词来概括:多态.动态链接,向上转型 也有人说这是面向接口编程,可以降低程序的耦合性,即调用者不必关心调用的是哪个对象,只需要针对接口编程就可以了,被调用者对于调用者是完全透明的.让你更关

java多态,如何理解父类引用指向子类对象

摘录 要理解多态性,首先要知道什么是“向上转型”. 我定义了一个子类Cat,它继承了Animal类,那么后者就是前者是父类.我可以通过   Cat c = new Cat(); 实例化一个Cat的对象,这个不难理解. 但当我这样定义时:   Animal a = new Cat(); 表示定义了一个Animal类型的引用,指向新建的Cat类型的对象.由于Cat是继承自它的父类Animal,所以Animal类型的引用是可以指向Cat类型的对象的. 那么这样做有什么意义呢?因为子类是对父类的一个改进

理解父类引用指向子类对象

java多态,如何理解父类引用指向子类对象 要理解多态性,首先要知道什么是“向上转型”. 我定义了一个子类Cat,它继承了Animal类,那么后者就是前者是父类.我可以通过   Cat c = new Cat(); 实例化一个Cat的对象,这个不难理解. 但当我这样定义时:   Animal a = new Cat(); 这代表什么意思呢? 很简单,它表示我定义了一个Animal类型的引用,指向新建的Cat类型的对象.由于Cat是继承自它的父类Animal,所以Animal类型的引用是可以指向C

【转】父类引用指向子类对象

父类引用指向子类对象指的是: 例如父类Animal,子类Cat,Dog.其中Animal可以是类也可以是接口,Cat和Dog是继承或实现Animal的子类. Animal animal = new Cat(); 即声明的是父类,实际指向的是子类的一个对象. 那这么使用的优点是什么,为什么要这么用?可以用这几个关键词来概括:多态.动态链接,向上转型 也有人说这是面向接口编程,可以降低程序的耦合性,即调用者不必关心调用的是哪个对象,只需要针对接口编程就可以了,被调用者对于调用者是完全透明的.让你更关

父类引用指向子类对象

1 public class Test { 2 /** 3 * 对于多态,可以总结它为: 4 5 一.使用父类类型的引用指向子类的对象: 6 7 二.该引用只能调用父类中定义的方法和变量: 8 9 三.如果子类中重写了父类中的一个方法,那么在调用这个方法的时候,将会调用子类中的这个方法:(动态连接.动态调用) 10 11 四.变量不能被重写(覆盖),”重写“的概念只针对方法,如果在子类中”重写“了父类中的变量,那么在编译时会报错. 12 13 多态的3个必要条件: 14 15 1.继承 2.重写

关于父类引用指向子类对象

例如: 有以下2个类 public class Father { public int age = 70; public static string name = "父亲"; } public class Son : Father { public int age = 30; public static string name = "儿子"; } Father f=new Son(); 这种用法叫做“父类引用指向子类对象,或者叫“父类指针指向子类对象”,指的是定义一

父类引用指向子类对象--面向对象的多态

先上代码 package com.fuzi.demo; public class FuZi { public static void main(String[] args) { FuLei fuLei = new ZiLei(); fuLei.print_info(); } } class FuLei { public void print_info() { System.out.println("父类的print_info"); System.out.println(this.get

理解多态AND理解父类引用指向子类对象

假设现在有一个父类Father,它里面的变量需要占用1M内存.有一个它的子类Son,它里面的变量需要占用0.5M内存. 现在通过代码来看看内存的分配情况: Father f = new Father();//系统将分配1M内存. Son s = new Son();//系统将分配1.5M内存. 因为子类中有一个隐藏的引用super会指向父类实例,所以在实例化子类之前会先实例化一个父类,也就是说会先执行父类的构造函数. 由于s中包含了父类的实例,所以s可以调用父类的方法. Son s1 = s;/

多态父类引用指向子类对象时,如何调用子类的独有方法?

父类:A 子类:Person A a1 = new Person(); if(a1 instanceof Person) { System.out.println("true"); ((Person) a1).getPersonName();      //调用子类独有的方法 }