java面向对象之继承

一、概述

1.定义:

面向对象三大特征之一,可以把多个子类中重复的代码抽取到父类中,子类可以使用,减少代码冗余,提高代码的复用性

2.特点:

①子类可以得到父类的属性和行为,子类可以使用。

②子类可以在父类的基础之上新增其他功能,子类更强大。

③java只支持单继承:一个类只能继承一个直接父类。不支持多继承,但支持多层继承

④java中所有的类都直接或间接的继承于Object类。(Object类是java中所有类的祖先)

⑤子类可以访问父类中非私有的成员。(注意:访问 ≠ 继承)

继承:父类中的成员,子类可以拷贝一份过来,相当于子类也有。但有些时候,子类虽然拿过来了,但不一定能够调用/访问。

3.使用场景:

当类与类之间,存在相同(共性)的内容并满足子类是父类的一种,就可以考虑使用继承,来优化代码。

二、继承内容

1.构造方法

父类的构造方法不能被子类继承,子类构造方法需要手动重新创建

构造方法的方法名是要和类名一致的,如果继承了父类的构造方法,那就会发生冲突。

2.成员变量

成员变量不管是私有的还是非私有的,在子类中都是可以继承下来的。只不过,私有的虽然继承下来了,但是不能直接去使用。

注:

①子类在加载字节码文件时,会把父类的字节码文件一同加载到方法区当中。

②在创建对象时,会有一部分空间存储从父类继承下来的成员变量,还有一部分是自己的成员变量

非私有:

私有:

访问 ≠ 继承

父类成员变量私有时,子类也能够继承下来,在堆中其内存空间中也存放着父类的私有成员变量。但由于私有,无法直接访问,会报错。如果要用,需要使用对应的get和set方法。

3.成员方法

如果该成员方法是虚方法,则能被子类继承下来,否则不能。

虚方法:非private,非static,非final修饰的成员方法

java会从最高的父类(Object类)开始,依次抽取虚方法放入虚方法表中,然后继承给下一个子类。子类在该基础上,继续抽取,再继承给下一个子类。

访问 ≠ 继承

Demo1不能访问也不能继承

在Object类中有5个虚方法,继承给Fu后,加上fushow1一共6个虚方法。再继承给Zi,加上zishow一共七个虚方法,所以Zi类的虚方法表长度为7。

fushow1和zishow由于是虚方法,会直接去Zi类的虚方法表中查找。

由于fushow2是private修饰,是非虚方法,不能继承,调用时不会去Zi类的虚方法表中找,而去所有的成员方法中找,找不到再去Fu类的所有成员方法中找。这时发现是private修饰,不能够访问,报错。

Demo2:可以访问但不能继承

class Fu{
    public void fushow1(){
        System.out.println("public-------fushow1");
    }

    public static void fushow2(){
        System.out.println("static-------fushow2");
    }
}

class Zi extends Fu{
    public void zishow(){
        System.out.println("public-------zishow");
    }
}


public class Test {
    public static void main(String[] args) {
        Zi z= new Zi();
        z.zishow();
        z.fushow1();
        z.fushow2();
    }
}

运行结果:

fushow2不是虚方法,不能添加到虚方法表中,也就不能继承

但子类发现不是虚方法之后,就不会去虚方法表中找。先去子类自己的所有成员方法中找,没找到再去父类,最后发现是public修饰,可以访问。

三、this与super关键字

1.就近原则

继承中,成员变量的访问特点:就近原则

class Fu{
    String name="fu";
    String school="DHU";
}

class Zi extends Fu{
    String name="zi";
    public void zishow(){
        String name="zishow";
        System.out.println(name);
        System.out.println(this.name);
        System.out.println(super.name);

        System.out.println("-----------------");

        System.out.println(school);
        System.out.println(this.school);
        System.out.println(super.school);
    }

}
public class Test {
    public static void main(String[] args) {
        Zi z=new Zi();
        z.zishow();
    }
}

运行结果:

不加this和super,会先在函数的局部变量里面找,没有再往上找。

this代表方法调用者的地址值,也就是再本类的成员变量里面找,如果没有再往上找。

super表示父类,会去父类的成员变量中找,如果没有再往上找

2.方法重写

在继承体系中,子类出现了和父类一模一样的方法声明,就就称子类的这个方法是重写的方法。

应用场景:当父类的方法不能满足子类现在的需求时,需要进行方法重写

格式:加上@Override重写注解(虽然不加也可以,但是加了可以校验重写是否正确,同时可读性好,所以建议加上)

本质:覆盖虚方法表中的方法。(只有被添加到虚方法表中的方法才能被重写)

注意事项:

①重写方法的名称、形参列表必须与父类中的一致

②子类重写父类方法,访问权限必须大于等于父类

③子类重写方法时,返回值类型必须小于等于父类(先了解)

// 父类
class SuperClass{
    public People create(){
        return new People();
    }
}
// 子类
class SubClass extends SuperClass{
    @Override
    public Student create(){
        return new Student();
    }
}

class People{
}

class Student extends People{
}

建议:重写的方法尽量和父类保持一致

只有被添加到虚方法表中的方法才能被重写

四、继承中的构造方法

1.访问特点:

①父类的构造方法不会被子类所继承

②子类中所有的构造方法默认先访问父类的无参构造,在执行自己

2.原因:

子类在初始化的时候,有可能会用到父类中的数据,如果父类没有完成初始化,子类将无法使用父类的数据。

注:子类初始化之前,一定要调用父类构造方法先完成父类数据空间的初始化。

3.调用方法

子类构造方法的第一行语句默认都是:super():  不写也隐含在内,且必须在第一行。

如果想调用父类的有参构造,必须手动写super进行调用

4.this和super的使用

this:本质就是一个局部变量,表示当前方法调用者的地址值

super:表示父类存储空间

 对于this访问构造方法,举个🌰🌰🌰

需求:对于没有明确给定学校名的学生,创建时默认为“清华大学”

class Student{
    String name;
    int age;
    String school;
    
    public Student(){
        //super();    报错
        //System.out.println("aaa");    报错
        this(null,0,"清华大学");
        System.out.println("aaa");
    }

    public Student(String name, int age, String school) {
        super();
        this.name = name;
        this.age = age;
        this.school = school;
    }
}

public class Test {
    public static void main(String[] args) {
        Student s=new Student();
    }
}

在Student类的无参构造中用this调用了本类的其他构造方法,

注意:当调用了本类其他构造方法,虚拟机就不会再在第一行添加super();

           因为在其他构造方法的第一行,已经隐含了一个super();  只要有一个super访问父类即可。

           所以在this调用其他构造方法的语句前,不能加其他任何语句,只能在该语句后面加。

super访问父类构造方法(员工类与经理类)

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值