子父类出现后,类成员的特点:
类中成员:
1、变量
2、函数
3、构造函数
1、变量
如果子类中出现非私有的同名的成员变量时,
子类要访问本类中的变量,用this关键字
子类要访问父类中的同名变量,用super关键字
super和this的使用几乎一致
this代表的是本类对象的引用
super代表的是父类对象的引用
如果子类和父类有相同名称的变量时,子类继承父类后,在子类中默认使用的是自己的变量,
因为在子类中是this.num省略了this。如果要用父类的变量只需要在变量前加上super
2、函数
当子类出现和父类一模一样的函数时,子类对象调用该函数,会运行子类函数的内容,如同父类的函数被覆盖了一样。
这种现象是函数的另一种特性:重写(覆盖)
当子类继承父类,沿袭了父类的功能到子类中,但是子类虽然具备该功能,但是功能的内容却和父类不一致
这个时候没有必要重新在子类中定义新功能,只需要重写父类的方法,代码如下:
class Fu
{
void show
{
System.out.println("Fu");
}
}
class Zi extends Fu
{
void show
{
System.out.println("Zi");
}
}
class Zi中的方法show就是重写了class Fu中的show
覆盖需要注意的:
1、子类覆盖父类,必须要保证子类权限大于等于父类权限,才可以覆盖,否则编译失败
2、静态只能覆盖静态
函数重载与重写的区别
重载:只看函数名的参数列表
重写:子父类方法要一模一样
3、子父类中的构造函数
在对子类对象初始化时,父类的构造函数也会运行,因为子类构造函数的第一行都有一条隐式语句super();
super();会访问父类中空参数的构造函数,而且子类中所有的构造函数默认第一行都是super();
为什么子类一定要访问父类中的构造函数
因为父类中的数据子类可以直接获取,所以子类在建立时。需要先查看父类是如何对这些数据进行初始化的
访问父类中的构造函数可以手动定义super语句的方式来定义
注意:super语句一定要定义在子类构造函数的第一行,并且不能和this();同时出现
子类实例化的过程
结论:
子类的所有的构造函数,默认都会访问父类中空参数的构造函数
因为子类的所以构造函数第一行都有一句隐式的super();语句
当父类中没有空参数的构造函数时,子类必须手动通过super语句的形式来指定要访问父类中的构造函数
子类的构造函数第一行也可以使用this来访问本类中的构造函数,因为子类中至少会有一个构造函数访问父类的构造函数
class ExtendsDemo
{
public static void main(String[] args)
{
Zi z = new Zi();
}
}
class Fu
{
Fu()
{
System.out.println("Fu");
}
}
class Zi extends Fu
{
Zi()
{
//隐式存在super();
System.out.println("Zi");
}
}
上述代码运行后结果为
Fu
Zi
this();和super();为什么不能同时存在?
因为他们都只能存在于构造函数里面的第一行
为什么都要写第一行? 因为初始化动作要先做