-
2021-03-06 18:06:02
继承和方法重写已经很熟悉了,这次
主要验证一下,当一个父类的引用指向一个对象的时候,它会调用子类的方法,而不是父类的。
引用在栈内存中存在对象的内存地址。真正的对象(通过 new Student()创建的)存放在堆内存里。
在这块堆内存区域内,存在的是子类的属性(包括自己特有的,以及通过super()构造方法中从父类获得的)
和方法(继承父类但没有覆盖的,以及覆盖父类的方法和自己特有的),尽管引用是声明为父类的引用,
但是它指向的子类的对象,在执行方法的时候,是通过引用指向的堆内存区域内执行的。也就是到底执行父类
方法还是子类方法是由对象决定的,跟引用没有直接关系。
演示代码如下:
Person.java
public class Person{
private String name;
public Person(){}
public void setName(String name){
this.name = name;
}
public String getName(){
return this.name;
}
public void introduce(){
System.out.println("Hello, I'm a Person object, and my name is "
+getName());
}
}
Student.java
public class Student extends Person{
public Student(){
super();
}
public void introduce(){
System.out.println("I'm a Student object and my name is "
+getName());
}
}
Test.java
public class Test{
public static void main(String[] args){
Person p = new Student();
p.setName("^-^");
p.introduce();
}
}
输出结果为:
I'm a Student object and my name is ^-^
更多相关内容 -
父类引用指向子类对象
2015-06-25 16:56:18父类引用子类对象,父类对象和子类对象之间的引用关系和区别 -
Java多态 父类引用指向子类对象
2021-03-06 18:05:04Java多态的三个必要条件:1、 继承2、 子类重写父类方法3、 父类引用指向子类对象然后看一个例子输出结果为:给出结论:Father c = new Child() 在c的眼里只能看到 child 里面的 father 属性!当满Java多态的三个...Java多态的三个必要条件:
1、 继承
2、 子类重写父类方法
3、 父类引用指向子类对象
然后看一个例子
输出结果为:
给出结论:Father c = new Child() 在c的眼里只能看到 child 里面的 father 属性!
当满Java多态的三个条件时,可以发现c.eat()调用的实际上是子类的eat(是因为子类重写覆盖了父类方法),
但c.age调用的还是父类的age(属性/变量不存在重写和覆盖),而c.play()则不会通过编译。
但是在java的引用中Father不但指定了c以何种方式访问内存,也规定了能够访问内存空间的大小。
我们看Father实例对象的大小是占两行,但Child实例对象占三行(这里就是简单量化一下)。
所以虽然c指向的是Child实例对象,但是前面有Father修饰它,它也只能访问两行的数据,也就是说c根本访问不到Child类中的age!!!只能访问到Father类的age,所以输出40
我们看到Parent的方法表占三行,Child的方法表占4行,c虽然指向了Child类的实例对象,
而对象中也有指针指向Child类的方法表,但是由于c受到了Father的修饰,通过c也只能访问到Child方法表中前3行的内容!!!!
然而前面说过,在方法表的形成过程中,子类重写的方法会覆盖掉表中原来的数据,也就是Child类的方法表的第三行是指向Child.eat的引用,
而不是指向Parent.eat(因为方法表产生了覆盖),所以c访问到的是Child.eat。也就是子类的方法!!!这种情况下,c是没有办法直接访问到父类的eat方法的。
-
java 父类引用指向子类对象
2021-03-21 10:06:071. 无论是泛型还是普通父类引用指向子类对象,父类引用可见范围都是父类自己的变量或函数2. 说明见注释代码如下:父类package com.atguigu.spring.beans;public class Father {public String fatherName;public ...1. 无论是泛型还是普通父类引用指向子类对象,父类引用可见范围都是父类自己的变量或函数
2. 说明见注释
代码如下:父类
package com.atguigu.spring.beans;
public class Father {
public String fatherName;
public String fatherGetName(){
return "";
}
public void sonUnImplementMethod(){
}
}子类
package com.atguigu.spring.beans;
import java.util.ArrayList;
import java.util.List;
/**
*
* @author jaloLi
* @usage 综上所述(无论泛型,还是普通引用),如果父类引用指向子类对象,父类引用可见范围都是父类自己的变量或函数
*
*/
public class Son extends Father{
public String sonName;
public Son(String name){
this.sonName = name + fatherName;//正确,子类直接使用,父类的字段
sonUnImplementMethod();//正确,子类直接使用,父类的函数,即使子类未实现的父类函数,子类也可以调用
}
@Override
public String fatherGetName() {
return super.fatherGetName() + sonName;
}
public String sonGetName() {
return sonName;
}
public static void main(String args[]){
List list = new ArrayList();
Son son = new Son("aaa");
Son son1 = new Son("bbb");
Son son2 = new Son("ccc");
list.add(son);
list.add(son1);
list.add(son2);
System.out.println(list.get(0).fatherGetName());//正确,list 中是father 类引用,father 引用的可见范围只是子类的继承函数
System.out.println(list.get(0).sonGetName());//错误,father 类引用无法引用非继承函数
System.out.println(list.get(0).fatherName);//正确,father 引用的可见范围只是子类的继承字段
System.out.println(list.get(0).sonName);//错误
}
}
-
java多态,如何理解父类引用指向子类对象
2021-03-06 16:57:01java多态,如何理解父类引用指向子类对象要理解多态性,首先要知道什么是“向上转型”。我定义了一个子类Cat,它继承了Animal类,那么后者就是前者是父类。我可以通过 Cat c = new Cat(); 实例化一个Cat的对象,这个...java多态,如何理解父类引用指向子类对象
要理解多态性,首先要知道什么是“向上转型”。
我定义了一个子类Cat,它继承了Animal类,那么后者就是前者是父类。我可以通过 Cat c = new Cat(); 实例化一个Cat的对象,这个不难理解。
但当我这样定义时: Animal a = new Cat();
表示定义了一个Animal类型的引用,指向新建的Cat类型的对象。由于Cat是继承自它的父类Animal,所以Animal类型的引用是可以指向Cat类型的对象的。
那么这样做有什么意义呢?因为子类是对父类的一个改进和扩充,所以一般子类在功能上较父类更强大,属性较父类更独特, 定义一个父类类型的引用指向一个子类的对象既可以使用子类强大的功能,又可以抽取父类的共性。
所以,父类类型的引用可以调用父类中定义的所有属性和方法,而对于子类中定义而父类中没有的方法,它是无可奈何的; 同时,父类中的一个方法只有在父类中定义而在子类中没有重写的情况下,才可以被父类类型的引用调用; 对于父类中定义的方法,如果子类中重写了该方法,那么父类类型的引用将会调用子类中的这个方法,这就是动态连接。也可以叫做动态绑定。
动态绑定是指”在执行期间(而非编译期间)“判断所引用对象的实际类型,根据实际的类型调用其相应的方法。
看下面这段程序:
class Father {
public void func1()
{
func2();
}
// 这是父类中的func2()方法,因为下面的子类中重写了该方法 ,所以在父类类型的引用中调用时,这个方法将不再有效,取而代之的是将调用子类中重写的func2()方法
public void func2() {
System.out.println("AAA");
}
}
class Child extends Father { // func1(int i)是对func1()方法的一个重载
由于在父类中没有定义这个方法,所以它不能被父类类型的引用调用
所以在下面的main方法中child.func1(68)是不对的
public void func1(int i) {
System.out.println("BBB");
} // func2()重写了父类Father中的func2()方法 如果父类类型的引用中调用了func2()方法,那么必然是子类中重写的这个方法
public void func2() {
System.out.println("CCC");
}
}
public class PolymorphismTest {
public static void main(String[] args) {
Father child = new Child();
child.func1();// 打印结果将会是什么? } }
上面的程序是个很典型的多态的例子。子类Child继承了父类Father,并重载了父类的func1()方法,重写了父类的func2()方法。重载后的 func1(int i)和func1()不再是同一个方法,由于父类中没有func1(int i),那么,父类类型的引用child就不能调用func1(int i)方法。而子类重写了func2()方法,那么父类类型的引用child在调用该方法时将会调用子类中重写的func2()
}
}
那么该程序将会打印出什么样的结果呢? 很显然,应该是“CCC”。
对于多态,可以总结它为:
一、使用父类类型的引用指向子类的对象;
二、该引用只能调用父类中定义的方法和变量;
三、如果子类中重写了父类中的一个方法,那么在调用这个方法的时候,将会调用子类中的这个方法;(动态连接、动态调用)
四、变量不能被重写(覆盖),”重写“的概念只针对方法,如果在子类中”重写“了父类中的变量,那么在编译时会报错。
多态的3个必要条件:
1.继承 2.重写 3.父类引用指向子类对象。
-
父类引用指向子类对象的注意点
2021-11-05 14:59:12父类引用指向子类对象的注意点 首先看一段代码: Father类 package JavaSE.lu.duotai; public class Father { static int b=7; int a=5; public void say(){ System.out.println("父亲say"); } public void ... -
多态之父类引用指向子类对象
2021-09-06 19:31:56继承 , 重写父类的方法 , 父类引用指向子类对象 以下是我对于多态的一些理解,如有不当,还请指正! 一,多态的概念与特征; 1.什么多态 多态是同一个行为具有多个不同表现形式或形态的能力。 多态就是同一个接口... -
父类引用指向子类对象详解
2020-04-24 09:47:36父类引用指向子类对象 父类引用指向子类对象指的是: 例如父类Animal,子类Cat,Dog。其中Animal可以是类也可以是接口,Cat和Dog是继承或实现Animal的子类。 Animal animal = new Cat(); 即声明的是父类,实际指向的... -
父类引用指向子类对象的问题,即父类 对象名=new 子类
2021-12-30 17:15:28父类引用指向子类对象的问题,即父类 对象名=new 子类 -
父类对子类的引用(父类引用指向子类对象)
2021-11-19 19:33:54Animal类是Dog类的父类,声明的是一个Animal类,实际上它指向的是子类的一个对象 也就是new 关键字后的。 关键字: 多态,动态链接,向上转型 1、多态 方法的重写与重载和动态链接构成多态性,在父类对子类的引用中... -
Java 理解点整理:父类引用指向子类对象(多态)
2021-06-10 17:31:071、父类引用指向子类对象代码演示 1. 代码:父类Animal,子类Dog,子类Cat //父类:动物 public class Animal{ //动物的叫声 public void shout(){ } } //子类:狗 public class Dog extends Animal{ //狗的... -
父类引用指向子类对象的方法调用问题
2021-03-28 21:37:54} } 运行结果为: 解释:当子类没有重写父类的方法时,父类引用指向子类对象的时候,父类引用所能看到的只是属于父类的那部分属性和方法。 在父类方法shout()中,打印的是父类的属性name,所以输出结果为父类的属性... -
C# 多态 如何理解父类引用指向子类对象 里式转换原则
2021-06-17 00:13:19从对象的内存角度来理解试试. ...因为子类中有一个隐藏的引用super会指向父类实例,所以在实例化子类之前会先实例化一个父类,也就是说会先执行父类的构造函数.由于s中包含了父类的实例,所以s可以调用父类的方法. Son s -
如何理解父类引用指向子类对象
2019-04-28 12:17:11java多态,如何理解父类引用指向子类对象 要理解多态性,首先要知道什么是“向上转型”。 我定义了一个子类Cat,它继承了Animal类,那么后者就是前者是父类。我可以通过 Cat c = new Cat(); 实例化一个Cat的对象... -
从JVM理解父类引用指向子类对象
2020-11-23 12:22:15关键字:多态、动态链接和向上转型 方法的重写、重载与动态链接构成多态性。 什么是动态链接?当父类中的一个方法只有在父类中定义而在子类中没有重写的情况下...定义一个Animal类型的引用,指向新建的Cat类型的对象。 -
父类引用指向子类对象[归纳].pdf
2021-10-28 18:00:18父类引用指向子类对象[归纳].pdf -
java -----多态:父类引用指向子类对象
2020-11-02 20:56:41概念:父类引用指向子类对象,从而产生多种形态 比如:dog继承了animal 怎么来理解这句代码的意思呢? 举一个例子: short s = 10; int num = s; 这两行代码的意思是:创建了个s变量,short类型的占2个... -
多态中,父类引用指向子类对象的代码执行顺序
2021-03-29 09:29:49父类引用指向子类对象,执行顺序为:父-子-父-父-子-子。 解释:若存在静态代码块,则先执行父类的静态代码块,再执行子类的静态代码块(父子); 然后执行父类的非静态代码块,父类的构造方法->子类的非静态代码... -
Java中父类引用指向子类对象好处
2019-09-09 04:22:45父类引用指向子类对象的好处: 好处一:降低代码耦合度,让程序员关注业务的时候,更加关注父类能做什么,而不去关心若干个子类具体是怎么做的 如果我需要实现两个方法:喂猫和喂狗 feed(Cat cat){ .... -
Java多态----父类引用指向子类对象的内存情况
2020-07-02 13:11:50Java多态----父类引用指向子类对象 多态: 一定是发生在 子父类/接口和实现类 之间。 首先,Java多态有三个必要条件: 1、 继承 2、 子类重写父类方法 3、 父类引用指向子类对象 然后看一个例子: 输出结果为: ... -
java多态性,父类引用指向子类对象
2019-02-27 19:29:40父类引用指向子类对象指的是: 例如父类Animal,子类Cat,Dog。其中Animal可以是类也可以是接口,Cat和Dog是继承或实现Animal的子类。 Animal animal = new Cat(); 即声明的是父类,实际指向的是子类的一个... -
从内存角度来理解父类引用指向子类对象
2022-03-11 16:41:46如何理解父类引用指向子类对象 转载自作者:乔你那熊色 从对象的内存角度来理解试试. 假设现在有一个父类Father,它里面的变量需要占用1M内存.有一个它的子类Son,它里面的变量需要占用0.5M内存. 现在通过... -
JAVA父类引用指向子类对象
2018-07-24 21:07:31如果子类继承的超类是一个抽象类,虽然抽象类不能通过new操作符实例化,但是可以创建抽象类的对象引用指向子类对象,以实现运行时多态性,不过,抽象类的子类必须覆盖实现超类中的所有的抽象方法 , 否则子类必须被...