第7章继承

旧城冷巷雨未停 提交于 2020-01-01 22:12:07

第7章继承

理解继承的基础知识、调用超类构造函数、使用super访问超类成员、创建多级类层次结构、了解何时调用构造函数、理解子类对象的超类引用、重写方法、使用重写方法实现动态方法分配、使用抽象类、使用final、了解Object类

继承的基础知识

Java不支持一个子类继承多个超类。但是,可以创建类的继承层次结构,其中的一个子类可以称为另一个子类的超类。

构造函数与继承

什么样的构造函数负责创建子类对象呢?
是超类构造函数还是子类构造函数?
超类的构造函数构造超类部分,子类的构造函数构造对象的子类部分。
因为超类并不知道或无权访问子类的任何元素。
当子类和超类都定义构造函数时,这种情况下的两个构造函数都要执行。这种情况下可以使用另外一个关键字。super
super的两种用法:第一种调用超类的构造函数,第二种用于访问被子类成员隐藏的超类成员。

使用super调用超类构造函数

super()必须是在子类中执行的第一条语句。

class A1{
    private int a;
    A1(){
        a=0;
    }
    A1(int aa){
        a=aa;
    }
    public int getA1(){
        return a;
    }
    public void setA1(int a1){
        a=a1;
    }
}
class B1 extends A1{
    private int b;
    B1(int bb){
        super();
        b=bb;
    }
    B1(int aa,int bb){
        super(aa);
        b=bb;
    }
    public int getB1() {
        return b;
    }
    public void setB1(int b) {
        this.b = b;
    }
}

这两种形式都可以。

使用super访问超类成员

这种形式多用于子类的成员隐藏了超类中同名成员的情况。

class A1{
    int a;
}
class B1 extends A1{
    private int a;
    B1(int aa,int bb){
        super.a=aa;
        a=bb;
    }
}
何时调用构造函数

当创建超类对象时,首先执行哪一个构造函数,是子类的构造函数还是超类的构造函数?
构造函数的调用是按照继承的顺序,从超类到子类来进行的。

超类引用和子类对象

1、子类对象的引用可以赋值给超类引用变量
2、哪些成员可以访问是由引用变量的类型(而不是它引用的对象的类型)决定的。当一个子类对象的引用赋值给超类引用变量时,只有权访问超类的成员。

方法重写

当子类中的方法和超类中的方法有一样的返回值类型和签名时,就说子类的方法重写了超类中的方法。
在子类中调用被重写的方法时,总是调用子类中定义的方法,超类中定义的方法被隐藏。
上面提到哪些成员可以访问是由引用变量的类型决定的,而不是它引用的对象的类型。把子类对象的引用赋值为超类引用变量时,如果出现了方法重写,超类引用变量调用该重写方法时,调用的是子类的方法。

class A1{
    int a;
    void show(){
        System.out.println(a);
    }
}
class B1 extends A1{
    private int b;
    B1(int aa,int bb){
        super.a=aa;
        b=bb;
    }
    void show(){
        //super.show();
        System.out.println(b);
    }
}
public class C1 {
    public static void main(String[] args){
        A1 b = new B1(1,2);
        b.show();
    }
}

重写方法是Java实现多态性的“单接口,多方法”的又一种方式。

重写的方法支持多态性

方法重写组成了Java最强大的概念之一:动态方法分配。
动态方法分配是一种机制,通过该机制对一个被重写方法的调用会在运行时解析,而不是在编译时解析。
我们再从超类引用变量可以引用子类对象这一重要的原理开始讨论。Java利用这一事实解决了运行时对重写方法的调用。办法如下:当通过超类引用调用被重写的方法时,Java会根据在调用发生时引用对象的类型来判断所要执行的方法。因此,这种判断发生在运行时。当引用不同类型的对象时,将调用被重写的方法的不同版本。换句话说,是被引用对象的类型(而不是引用变量的类型)决定了所要执行的被重写方法。

使用抽象类

有时,需要创建这样一个超类:该超类只定义了一个所有子类共享的一般形式,至于实现的细节则交给每一个子类去填充。这样的类决定了子类必须实现的方法的本质,而它自己则不提供其中一个或多个方法的实现。
抽象方法是通过指定abstract类型修饰符来创建的。抽象方法没有内容,一次无法被超类实现,这样,子类就必须重写它。

使用final

如果要防止方法重写或类的继承,需要使用关键字final

使用final防止重写

final void meth(){}
在超类的方法前加上关键字final就可以防止子类对该方法重写。

使用final防止继承

final class A{}
在类前加上final关键字,就可以防止该类被继承

对数据成员使用final

如果在类的变量名前使用final,它的值在程序的生命周期内就不能改变,允许为变量赋初值。final常量,习惯使用大写的标识符。

Object类

Object类是所有类的隐式超类。

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!