51工具盒子

依楼听风雨
笑看云卷云舒,淡观潮起潮落

面向对象之继承

1.类与类之间的三种关系

is a :继承关系,例如:公共汽车 is a 汽车
use a:使用关系,例如:人 use a 钳子
has a:包含关系,例如:人has a 胳膊

2.为什么要继承

继承的出现提高了代码的复用性,提高软件开发效率。
继承的出现让类与类之间产生了关系,提供了多态的前提。

3.继承的定义格式

在程序中,如果想声明一个类继承另一个类,需要使用extends关键字。
class 子类 extends 父类 {
    
}

4.继承的使用

案例:公司有2个部门,人事部和研发部,各自属性如下

  • 定义人事部类:

    /*

    • 人事部 */ public class PersonalDepartment { private int ID;// 部门编号 private String name = "待定";// 部门名称 private int amount = 0;// 部门人数 private String responsibility = "待定";// 部门职责 private String manager = "无名氏";// 部门经理 private int count;//招聘人数

      public PersonalDepartment() { }

      public PersonalDepartment(int ID, String name, int amount, String responsibility, String manager, int count) { this.ID = ID; this.name = name; this.amount = amount; this.responsibility = responsibility; this.manager = manager; this.count = count; } }

  • 定义研发部类

    /**

    • 研发部 */ public class ResourceDepartment { private int ID;// 部门编号 private String name = "待定";// 部门名称 private int amount = 0;// 部门人数 private String responsibility = "待定";// 部门职责 private String manager = "无名氏";// 部门经理 private String speciality =null;//研发方向

      public ResourceDepartment() { }

      public ResourceDepartment(int ID, String name, int amount, String responsibility, String manager, String speciality) { this.ID = ID; this.name = name; this.amount = amount; this.responsibility = responsibility; this.manager = manager; this.speciality = speciality; } }

发现问题了:两个类中的属性有许多相同的部分,代码冗余太多,此时就需要定义一个包含他们相同部分的父类,再让整两个类来继承。

定义父类

/**
 * 部门父类:存放所有子类共性的内容
 */
public class Debarment {
    private int ID;// 部门编号
    private String name = "待定";// 部门名称
    private int amount = 0;// 部门人数
    private String responsibility = "待定";// 部门职责
    private String manager = "无名氏";// 部门经理

    public Debarment() {
    }

    public Debarment(int ID, String name, int amount, String responsibility, String manager) {
        this.ID = ID;
        this.name = name;
        this.amount = amount;
        this.responsibility = responsibility;
        this.manager = manager;
    }

    @Override
    public String toString() {   //重写父类object的toString()方法
        return "Debarment{" +
                "部门编号:" + ID +
                ", 部门名称:'" + name + '\'' +
                ", 部门人数:" + amount +
                ", 部门职责:'" + responsibility + '\'' +
                ", 部门经理:'" + manager + '\'' +
                '}';
    }
}

重构人事部

/**
 * 人事部
 */
public class PersonalDepartment extends Debarment {  // PersonalDepartment继承 Deparment
    private int count;//招聘人数

    public PersonalDepartment() {
    }

    public PersonalDepartment(int count) {
        this.count = count;
    }

    public PersonalDepartment(int ID, String name, int amount, String responsibility, String manager, int count) {
        super(ID, name, amount, responsibility, manager);
        this.count = count;
    }

    @Override
    public String toString() {
        //通过super调用父类的toString()
        return super.toString() + "人事部{" +
                "招聘人数:" + count +
                '}';
    }
}

重构研发部

/**
 * 研发部
 */
public class ResourceDepartment extends Debarment {   // ResourceDepartment 继承Deparment

    private String speciality =null;//研发方向

    public ResourceDepartment() {
    }

    public ResourceDepartment(String speciality) {
        this.speciality = speciality;
    }

    public ResourceDepartment(int ID, String name, int amount, String responsibility, String manager, String speciality) {
        super(ID, name, amount, responsibility, manager);
        this.speciality = speciality;
    }

    @Override
    public String toString() {
        //通过super调用父类的toString()
        return super.toString() + "研发部{" +
                "研发方向:'" + speciality + '\'' +
                '}';
    }
}
这样之后两个部门相同部分就只写一份就可以了

子类通过关键字super()调用父类构造函数和方法。

super()必须放在子类构造函数的第一行代码

测试:

/**
 * 公司类
 */
public class Company {
    public static void main(String[] args) {
        //创建人事部对象
        PersonalDepartment personalDepartment = new PersonalDepartment(110,"人事部",10,"负责招聘","暂定",50);
        //创建研发部对象
        ResourceDepartment resourceDepartment = new ResourceDepartment(120,"研发部",20,"研发芯片","暂定","芯片");
        //调用父类的方法
        System.out.println(personalDepartment);
        System.out.println(resourceDepartment);

    }
}

5.继承的注意事项

类只支持单继承,不允许多继承
class A{} 
class B{}
class C extends A,B{}  // C类不可以同时继承A类和B类
  • 多个类可以继承一个父类

    class A{} class B extends A{} class C extends A{} // 类B和类C都可以继承类A

  • 允许多层继承

    class A{} class B extends A{} // 类B继承类A,类B是类A的子类 class C extends B{} // 类C继承类B,类C是类B的子类,同时也是类A的子类

6.子类和父类是一种相对概念

也就是说一个类是某个类父类的同时,也可以是另一个类的子类。例如上面的这种情况中,B类是A类的子类,同时又是C类的父类。

7.继承的体系 之 Object类

  • Object是所有类的父类

  • 如果一个类没有显示定义父类,那么默认继承Object类

  • Object类中没有定义属性,但是定义了12个方法,并且这些方法都是实例方法。因此每个对象都拥有这14个方法。

8.继承后子类的成员的变化

了解了继承给我们带来的好处,提高了代码的复用性。继承让类与类或者说对象与对象之间产生了关系。那么,当继承出现后,类的成员之间产生了那些变化呢?
子类中的成员包括

  • 子类自己定义的属性和方法

  • 从父类继承的属性和方法

  • 子类不能使用从父类继承的私有成员,因为被封装了。

9.方法重写(方法覆盖|override)

1.什么是方法重写

答:在子类中将父类的方法再重新定义一遍。

2.为什么要方法重写

如果子类从父类继承的方法不能满足子类的需要,或者不适合子类的需要。

此时子类可以将从父类继承的方法重写定义成满足自己需要的方法。

重新定义称为重写。 就像上面的toString()方法。

3.方法重写的注意事项

  • 方法重写时,方法的返回值类型 方法名 参数列表都要与父类一样。(同名,同参,同返回)

  • 子类方法覆盖父类方法,必须要保证权限大于等于父类权限。

10.## 方法重载(overload)和方法重写(override)的区别

1. 方法重载:

在同一个类中(包括从父类继承的) 方法 同名 不同参 与返回值无关

2. 方法重写:

  1. 方法重写存在于继承关系中

  2. 父子类之间的方法 同名,同参,同返回

赞(9)
未经允许不得转载:工具盒子 » 面向对象之继承