继承
当类与类之间存在所属关系时就可以定义继承。单继承:一个子类只能有一个父类。多继承:一个子类可以有多个父类。Java中不支持多继承,但支持多层继承,即A继承B,B继承C,构成了继承体系。为什么Java不支持多继承呢?因为若继承的多个父类中有相同的成员,子类在调用时会产生不确定性,在Java中采用“多实现”的方式来体现。
(1)成员变量
在使用类时,当成员变量和局部变量重名时,用this来区分。而在子父类继承体系中若子类和父类成员变量重名时用super关键字进行区分。this代表本类对象的引用,而super代表子类所继承的父类空间。
(2)成员函数
在子父类的继承体系中,若子类中出现了和父类函数相同的方法,则运行子类中的函数方法,这种现象称为函数的覆盖。在覆盖时,子类函数的权限必须大于或等于父类中函数的权限,而静态方法只能覆盖静态,或者说被静态所覆盖。
在哪种情况下需要用到覆盖操作呢?当对一个类进行子类扩展时,子类需要保留父类的功能声明,但在子类中又要有该类的特有功能时,需要用到覆盖。即当对功能进行升级时,需要对父类的函数方法进行覆盖。
class Phone
{
void call()
{}
void show()
{
System.out.println("number");
}
}
class NewPhone extends Phone
{
void show()
{
System.out.println("name");
System.out.println("pic");
super.show();
}
}
(3)构造函数
在子类构造对象时,访问子类构造函数时,父类的构造函数要先于子类的构造函数运行。因为在子类的构造函数第一行有一个默认的隐式语句super(),子类在实例化的过程中,子类所有的构造函数默认都会访问父类空参数的构造函数,如果父类中没有定义空参数的构造函数,子类的构造函数中就需要用super(参数)函数明确要访问的是父类中哪一个构造函数。
由于this()和super()只能定义在构造函数的第一行,那么当构造函数第一行定义this()时,super()就没有了,但可以保证的是在子类的其他构造函数中肯定有一个能访问父类的构造函数。
那么为什么父类的构造函数要先执行?因为子类继承了父类的成员,子类在使用父类的内容前需要先让父类进行初始化操作。
class Fu
{
int num = 10;
Fu(){
System.out.println("A Fu run...");
}
Fu(int x){
System.out.println("B Fu run..."+x);
}
}
class Zi extends Fu
{
int num = 8;
Zi(){
System.out.println("C Zi run...");
}
Zi(int x){
//super(); 此处有默认的super()语句
System.out.println("D Zi run..."+x);
}
}
class ExtendsDemo2
{
public static void main(String[] args)
{
new Zi(6);
}
}
该程序运行的结果是:
A Fu run...
D Zi run...6