继承与多态
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了继承与多态相关的知识,希望对你有一定的参考价值。
- 1.为什么子类的构造方法在运行之前,必须调用父类的构造方法?能不能反过来?为什么不能反过来?
答:由于子类是继承父类的,所以想用子类创建对象时,必须先创建父类的对象,这样子类才能有父类的属性和方法。在创建对象时如果父类的数据需要进行初始化,那么就需要调用父类的构造函数。不能反过来,因为父类不知道子类有什么属性,而且反过来子类也不能得到父类初始化的变量。
2.参看ExplorationJDKSource.java示例
此示例中定义了一个类A,它没有任何成员:
class A { }
示例直接输出这个类所创建的对象
public static void main(String[] args) {
System.out.println(new A());
}
我们得到了一个奇特的运行结果:
为什么?
答:函数实际上是继承了Object类中的toString方法,因此会有结果输出。
- 3.动手动脑:请自行编写代码测试以下特性:
- 在子类中,若要调用父类中被覆盖的方法,可以使用super关键字。
答:源代码:
//信1603班 20163514 周志慧
package test1_3;
class Fruit1
{
public void show()
{
System.out.println("Fruit");
}
}
class Fruit2 extends Fruit1
{
public void show()
{
super.show();
System.out.println("Pear");
}
}
public class Test {
public static void main(String[] args) {
// TODO 自动生成的方法存根
Fruit2 f=new Fruit2();
f.show();
}
}
- 4.现在有三个类:
class Mammal{}
class Dog extends Mammal {}
class Cat extends Mammal{}
- 针对每个类定义三个变量并进行初始化
Mammal m=null ;
Dog d=new Dog();
Cat c=new Cat();
下列语句哪一个将引起编译错误?为什么?哪一个会引起运行时错误?为什么?
m=d;
d=m;
d=(Dog)m;
d=c;
c=(Cat)m;
答:第二句,第四句会出现运行错误。
由于Dog和Cat都是继承的Mammal类,Mammal类是Dog类和Cat类的父类,由于基类对象要赋值给子类必须进行强制类型转换,因此第二句会运行错误;两个子类的类型也不一样因此也不能进行赋值语句。
- 5.运行以下测试代码
回答问题:
1. 左边的程序运行结果是什么?
2. 你如何解释会得到这样的输出?
3. 计算机是不会出错的,之所以得
到这样的运行结果也是有原因的,
那么从这些运行结果中,你能总
结出Java的哪些语法特性?
答:1.运行结果:
Parent.printValue(),myValue=100
Child.printValue(),myValue=200
Child.printValue(),myValue=200
Child.printValue(),myValue=200
Child.printValue(),myValue=201
2.
运行结果解释:
Parent类中myValue值为100;Child类中myValue值为200;
因此第一句Parent parent=new Parent();是创建了Parent类的对象parent
parent.printValue();对象parent调用了printValue函数,由于Parent类中myValue值为100,因此此时myValue值为100;
第二句Child child=new Child();创建了Child的对象child
child.printValue();对象parent调用了printValue函数,由于Child类中myValue值为200,因此此时myValue值为200;
第三局parent=child;是将子类child赋值给基类parent
parent.printValue();调用的是Child类中的printValue函数,Child类中的myValue值为200,因此此时输出值为200;
第四句parent.myValue++;parent中已经被child赋值,执行myValue++;
parent.printValue();由于在第三句中已经将对象child赋值给parent因此此时的操作应该是对于child对象的操作,执行myValue++后myValue值并没有改变,因此输出值为200;
第五句((Child)parent).myValue++;将对象parent进行强制性转换为Child类,执行的为parent对象的操作;此时myValue值为201;
parent.printValue();执行myValue++后myValue值依旧为201;
- 6.请使用javap查看编译器为TestPolymorphism.java生成的字节码指令,然后通过互联网搜索资料,尝试从底层开始理解Java编译器是如何为多态代码生成字节码指令,在程序运行过程中,多态特性又是如何实现的。
答: 在 java 语言中,多态性体现在两个方面:由方法重载实现的静态多态性(编译时多态)和方法重写实现的动态多态性(运行时多态)。
(1)编译时多态
在编译阶段,具体调用哪个被重载的方法,编译器会根据参数的不同来静态确定调用相应的方法。
(2)运行时多态
由于子类继承了父类所有的属性(私有的除外),所以子类对象可以作为父类对象使用。程序
中凡是使用父类对象的地方,都可以用子类对象来代替。一个对象可以通过引用子类的实例来调用
子类的方法。
重写方法的调用原则(为重点):java 运行时系统根据调用该方法的实例,来决定调用哪个方法。
对子类的一个实例,如果子类重写了父类的方法,则运行时系统调用子类的方法;如果子类继承了
父类的方法(未重写),则运行时系统调用父类的方法。
以上是关于继承与多态的主要内容,如果未能解决你的问题,请参考以下文章