1.
运行 TestInherits.java 示例,观察输出,注意总结父类与子类之间构造方法的调用关系修改Parent构造方法的代码,显式调用GrandParent的另一个构造函数,注意这句调用代码是否是第一句,影响重大!
运行结果:
运行结果:
程序不能运行
结论:通过 super 调用基类构造方法,必须是子类构造方法中的第一个语句。
2.为什么子类的构造方法在运行之前,必须调用父类的构造方法?能不能反过来?为什么不能反过来?
构造函数主要用来在创建对象时初始化对象, 即为对象成员变量赋初始值,总与new运算符一起使用在创建对象的语句中 。特别的一个类可以有多个构造函数 ,可根据其参数个数的不同或参数类型的不同来区分它们 即构造函数的重载。构造函数的功能主要用于在类的对象创建时定义初始化的状态。
构造一个对象,先调用其构造方法,来初始化其成员函数和成员变量。
子类拥有父的成员变量和成员方法,如果不调用,则从父类继承而来的成员变量和成员方法得不到正确的初始化。
不能反过来调用也是这个原因,因为父类不知道子类有什么变量而且这样子类也得不到初始化的父类变量,导致程序运行出错
4.请自行编写代码测试以下特性(动手动脑):
在子类中,若要调用父类中被覆盖的方法,可以使用super关键字。
代码如下:
package test;
public class test {
public test()
{System.out.println("test1 创建");
}
public test(String string)
{System.out.println("test创建.String"+string);
}
}
class test2 extends test{
public test2(){
//super("hahaha");
System.out.println("test2创建");
}
}
class test3 extends test2{
public test3() {
System.out.println("test3创建");
}
}
class AAA{
public static void main(String[] args)
{
test3 t=new test3();
}
}
注释掉super后运行结果:
不注释掉super运行结果
现在有三个类:
class Mammal{}
class Dog extends Mammal {}
class Cat extends Mammal{}
5.针对每个类定义三个变量并进行初始化
Mammal m=null ;
Dog d=new Dog();
Cat c=new Cat();
下列语句哪一个将引起编译错误?为什么?哪一个会引起运行时错误?为什么?
m=d;
d=m;
d=(Dog)m;
d=c;
c=(Cat)m;
代码
class Mammal{}
class Dog extends Mammal {}
class Cat extends Mammal{}
public class TestCast
{
public static void main(String args[])
{
Mammal m;
Dog d=new Dog();
Cat c=new Cat();
m=d;
//d=m;
d=(Dog)m;
//d=c;
//c=(Cat)m;
}
}
结果://d=m;//d=c;//c=(Cat)m;出现错误
d=m显示错误:类型不匹配:不能从mammal转换为dog
d=c显示错误:类型不匹配:不能从cat转换为dog
6
①左边的程序运行结果是什么
②.你如何解释会得到这样的输出?
a.创建父类对象parent,parent调用父类printValue方法,输出100。
b.创建子类对象child,child调用子类printValue方法,输出200。
c.把子类对象赋值给父类对象,赋值后的parent.printValue();相当于child.printValue();所以输出200。
d.被赋值后的父类对象对数据成员的操作依然是对父类的数据成员进行操作,并没有对子类数据成员进行操作,只是将父类的myValue值+1,而子类的myValue值并没有改变,所以 parent.printValue();输出200。
e.使用了强制类型转换,结果是对子类的myValue+1,而parent已经被子类对象赋值,所以输出201。
③计算机是不会出错的,之所以得到这样的运行结果也是有原因的,那么从这些运行结果中,你能总结出Java的哪些语法特性?
当子类与父类拥有一样的方法,并且让一个父类变量引用一个子类对象时,到底调用哪个方法,由对象自己的“真实”类型所决定,这就是说:对象是子类型的,它就调用子类型的方法,是父类型的,它就调用父类型的方法。
如果子类与父类有相同的字段,则子类中的字段会代替或隐藏父类的字段,子类方法中访问的是子类中的字段(而不是父类中的字段)。如果子类方法确实想访问父类中被隐藏的同名字段,可以用super关键字来访问它。如果子类被当作父类使用,则通过子类访问的字段是父类