首页 > 编程知识 正文

父类引用指向子类对象有什么用,子类的引用指向父类对象

时间:2023-05-05 03:42:45 阅读:181599 作者:4635

试着从对象的内存角度来理解。

现在,假设有父级Father,其中的变量消耗1M的内存。假设有其子级Son,其中的变量消耗0.5M的内存。

在代码中看看内存的分配:

Father f=new Father (; //系统分配1M的内存。

Son s=new Son (; //系统分配1.5M的内存! 因为子类中有隐藏的引用super指向父类的实例,所以首先执行实例化子类之前会先实例化一个父类,即父类的构造函数。s包含父类的实例,所以s是父类的方法

Son s1=s; //s1是指其1.5M的内存。

fatherF1=(father ) s; Father f1=new Son (相当于; 对于向上类型转换,子类是父类,例如猫是动物,因此可以省略

//此时,f1指向其1.5M内存中的1M内存。 也就是说,因为f1只指向s中实例的父类实例对象,所以f1只能调用父类的方法(存储在1M存储器中),不能调用子类的方法(存储在0.5M存储器中)

sonS2=(son ) f; 不要直接将//Error转换为类型

//代码在运行时报告ClassCastException。 f只有1米的内存,子类引用都需要1.5M的内存,因此无法转换。

sonS3=(son ) f1; 强制类型转换。 对于低级类型转换,假定父类引用先指向子类对象

//此语句可执行,此时s3指向其1.5M的内存。因为f1是从s转换而来的,所以有1.5M的内存,但指向的只是1M的内存。

例如:

1 .想要实现多态性,需要三个条件。 父类的引用、子类的对象和方法覆盖你。 在此,如果Fathor类中有show (方法,则在形成方法涵盖后,此时可以写入:obj.show )。 现在多态性正在形成。

2 .无法掩饰。 那么,在这里只能解释为父类的引用访问一个子类的方法。 当然,对父类的引用没有这么大范围的权限。 当然,我会弄错报告说PS:多态性实际上是一种机制。 在编译时,会生成一个虚拟表以记录所有复盖方法,而不在该表中记录任何未复盖的方法。 如果调用的子类方法不包含对父类的引用,则会报告错误的编译时间。 运行程序时,虚拟机会去此虚拟表中寻找覆盖方法。 例如,如果引用实际上包含子类对象引用,请找到并执行子类的相应覆盖方法

class Father{void print () }; } classonextendsfather { void print () {System

.out.println("子类中!");}void show(){System.out.println("show 中!");}}class Demo{public static void main(String args[]){Father obj=new Son();obj.print();obj.show(); //这个调用会报错!,即指向子类对象的父类引用不能调用父类有而子类没有的方法}}

定义一个父类类型的引用指向一个子类的对象既可以使用子类强大的功能,又可以抽取父类的共性。
所以,父类类型的引用可以调用父类中定义的所有属性和方法,而对于子类中定义而父类中没有的方法,它是无可奈何的;
同时,父类中的一个方法只有在在父类中定义而在子类中没有重写的情况下,才可以被父类类型的引用调用;
看下面这段程序:

    上面的程序是个很典型的多态的例子。子类Child继承了父类Father,并重载了父类的func1()方法,重写了父类的func2()方法。重载后的func1(int i)和func1()不再是同一个方法,由于父类中没有func1(int i),那么,父类类型的引用child就不能调用func1(int i)方法。而子类重写了func2()方法,那么父类类型的引用child在调用该方法时将会调用子类中重写的func2()。
那么该程序将会打印出什么样的结果呢?
很显然,应该是“CCC”。

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();//打印结果将会是什么? }}

变量是不存在重写覆盖的!

public class A { int a = 1; }public class B extends A { int a = 2; }测试类里调用了这个方法void compare(){if(super.a == this.a)System.out.println("not overrided");elseSystem.out.println("overrided");}控制台出来的是overrided

类中的属性是没有多态性的,即你在引用上面使用属性时,系统只会去找引用的静态类型中的那个属性,而与它的实际类型无关。
静态方法也是没有多态性的。

版权声明:该文观点仅代表作者本人。处理文章:请发送邮件至 三1五14八八95#扣扣.com 举报,一经查实,本站将立刻删除。