继承的基础知识整理

继承的概念和特点

当某个类需要继承其他类的时候,在定义当前类的地方使用extends关键字,然后让这个类去继承需要继承的其他类。此时被继承的类称为父类,实现这个继承的类称为子类。子类继承父类后,可以使用父类的成员变量和成员方法(private修饰的成员不能被子类继承)。

继承的优势:让类与类之间产生关系,父类定义好成员,子类直接使用,提高了代码的复用性。

继承的弊端:打破了封装性。

继承在内存中的加载顺序:JVM在加载子类的时候,会发现子类的字节码文件里有一个extends标识,所以JVM会先将父类加载到方法区中,再将子类加载到方法区中。

Java只支持单继承,不支持多继承,即一个子类只能由一个父类。

Java支持多层继承,即子类可以有父类,父类也可以再有父类。

成员变量重名

如果子类中出现了跟父类同名的成员变量,则在子类中可以通过super关键字来访问父类中的成员变量。

在Java中super关键字有两个作用:

①super.父类成员(变量、函数),在父类中访问父类的成员;

②super(参数),访问父类的构造函数。

this和super的区别:

①this表示本类中的成员,super表示父类中的成员;

②在Java中,this是一个引用变量,它保存的是当前调用这个函数的对象的地址值;super仅仅表示父类的内存空间,但不是父类的对象,仅仅是用来标记哪个是父类;

③this表示子类对象在堆内存中开辟的整个空间,而super标记的是子类对象开辟空间中的父类所占用的空间。

当父类中的成员变量和子类中同名时,子类对象优先调用属于子类对象自己的成员变量。

子类不能直接继承父类的私有成员变量,但是可以通过get、set方法进行调用。

方法重写

如果子类和父类中出现一模一样的成员方法,访问时则会出现一种特殊的情况:方法重写。

方法重写:子类中出现跟父类一样的成员方法时(返回值类型,方法名和参数列表都相同),则会出现覆盖效果,也称为重写或复写,声明不变,重新实现。

方法重写的应用:子类可以根据自己的需要,定义特定于属于自己的行为,这样既沿袭了父类的功能名称,又根据子类的需要重新实现了父类的方法,从而进行扩展增强。

方法重写的注意事项:

①必须有继承关系;

②父类中的private修饰的成员方法,不能被重写;

③函数的重写要求函数的返回值类型、方法名和参数列表全部相同。

继承后构造函数的特点(隐式三步)

通过学习对象的创建流程,我们知道,在使用new关键字创建对象的时候,先在堆内存中给对象分配内存空间,接着给非静态成员变量进行默认初始化,开始调用对应的构造函数。而在执行构造函数中有隐式三步:super();它是在调用父类的无参构造函数:

①非静态成员变量显示赋值;

②父类的构造代码块运行;

③父类的构造函数中的代码运行。

构造代码块:直接在类中定义且没有加入static关键字修饰的代码块称为构造代码块,构造代码块在创建对象时被调用,每次创建对象时都会被调用,且构造代码块执行的优先级高于类的构造函数。

public class Fu {
    int x = 3;

    {
        System.out.println("父类构造代码块x=" + x);
    }

    public Fu() {
        System.out.println("父类构造函数执行");
      	show();
    }

    public void show() {
        System.out.println("父类show方法执行x=" + x);
    }
}

public class Zi extends Fu {
    int y = 4;

    {
        System.out.println("子类构造代码块x=" + x);
        System.out.println("子类构造代码块y=" + y);
    }

    public Zi() {
        super();
        System.out.println("子类构造函数执行");
        show();
    }

    @Override
    public void show() {
        System.out.println("子类show方法执行x=" + x);
        System.out.println("子类show方法执行y=" + y);
    }
}

public class Demo {
    public static void main(String[] args) {
        Zi zi = new Zi();
    }
}
执行结果:
父类构造代码块x=3
父类构造函数执行
子类show方法执行x=3
子类show方法执行y=0
子类构造代码块x=3
子类构造代码块y=4
子类构造函数执行
子类show方法执行x=3
子类show方法执行y=4

每个类中都调用父类的构造函数,是因为子类继承了父类,子类要使用父类的成员变量,所以调用父类中的构造函数是为了父类中的成员变量显示初始化。

上述代码中由于父类的构造函数是子类对象来调用的,所以父类构造函数中的this记录着子类对象的内存地址,因此在执行show方法时JVM会优先在子类中去寻找,如果子类中没有show函数,则再返回父类中查找。

注意事项

①为什么任何一个类(不包括Object类)的构造函数中都有一个隐式super()语句?因为任何子类继承父类之后,都会继承到父类的成员变量,这时创建子类对象的时候,会在子类的对象空间中分配出存储空间存储父类的成员变量,而父类的成员变量显示初始化动作必须由子类自己的构造函数完成,因此任何一个类的构造函数中都有一个隐式super()语句。

②如果一个类的所有构造函数全部私有,这个类就无法再有子类。

③如果一个类没有无参构造函数,那么这个类也可以有子类,但是要求在子类的构造函数中必须手写super语句,即super(具体参数),之后会根据参数去调用父类中参数类型相同的构造函数。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值