Java基础12-继承(思想、覆盖、super,子类初始化)

.1.什么是继承?为什么要继承?

从字面意思上来看,继承是孩子从父母哪里继承得到的东西,或是徒弟从师傅哪里得到的技能或手艺。java中继承就是子类继承父类的特征和行为,使得子类对象(实例)具有父类的实例域和方法,或子类从父类继承方法,使得子类具有父类相同的行为。

还记得我们的DOTA英雄吗?

DOTA英雄可以攻击和释放技能,所以继承了它特性的天辉和夜魇英雄都可以攻击和释放技能,但天辉和夜魇英雄都可以拥有自己的独特属性和行为(方法)。

我们看到,无论是天辉还是夜魇英雄都有名字年龄种族和信仰的属性,都有攻击和释放技能的行为,但是天辉独有选举的方式产生领导者,而夜魇凭借的是力量上位,

那么我们就可以用extends关键字把它写成

dota英雄就是天辉和夜魇英雄的父类,天辉和夜魇英雄就是dota英雄的子类

注意:在java中,只允许单继承,也就是说 一个类最多只能显示地继承于一个父类。但是一个类却可以被多个类继承,也就是说一个类可以拥有多个子类。简单地说就是一个爹可以有多个孩子,但是一个孩子只能有一个爹(隔壁老王的微笑)

从上可以看到,父类存放共性,子类存放特性,所以它的作用是

1.解决了代码重复问题,提高代码的维护性和复用性。

2.更多的是表现出一个体系。

 在Java中,除了object类,每一个类都有一个直接父类,object类是java语言的根类,也就是说object是老祖宗。

 二、方法重写/覆盖

1.当在程序中通过对象调用方法时,会先在子类中查找有没有对应的方法,若子类中存在就会执行子类中的方法,若子类中不存在就会执行父类中相应的方法。

 当调用自子类中的方法时,如果子类中没有这个方法,可以直接访问父类中的同名方法。

子类中出现与父类一模一样的方法时,会出现覆盖操作,也称为override重写、复写或者覆盖。

 

当子类需要父类的功能,而功能主体子类有自己特有内容时,可以重写父类中的方法,这样,即沿袭了父类的功能,又定义了子类特有的内容。

 2.方法覆盖的原则

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

 private修饰的方法不能被子类所继承,也就不存在覆盖的概念

当父类方法大于访问权限大于子类,编译报错

写法上必须一模一样:方法的返回值类型 方法名 参数列表都要一样。

 注意:

  1)只有方法有覆盖的概念,字段没有,方法覆盖解决了,父类的某一个行为不符合子类的特征,例如,鱼是鲸鱼的父类,鱼的呼吸行为是用鳃呼吸,而鲸鱼不是

  2)对于父类的包访问权限成员变量,如果子类和父类在同一个包下,则子类能够继承;否则,子类不能够继承;

  3)对于子类可以继承的父类成员变量,如果在子类中出现了同名称的成员变量,则会发生隐藏现象,即子类的成员变量会屏蔽掉父类的同名成员变量。如果要在子类中访问父类中同名成员变量,需要使用super关键字来进行引用。

  4)对于父类的包访问权限成员方法,如果子类和父类在同一个包下,则子类能够继承;否则,子类不能够继承;

  5)对于子类可以继承的父类成员方法,如果在子类中出现了同名称的成员方法,则称为覆盖,即子类的成员方法会覆盖掉父类的同名成员方法。如果要在子类中访问父类中同名成员方法,需要使用super关键字来进行引用。

三、super关键字

1.重写后我们怎么去调用父类中的方法呢?

当我们重写后,用子类的某一方法去调用父类被重写后的方法时效果如下

这里其实在子类中skill()方法中默认的是 this.atack();

 那我们怎么办呢?

用super关键字就可以访问父类中被重写的方法

 四、子类初始化过程

即创建子类对象的过程

在创建子类对象之前会先创建父类对象,调用子类构造器之前,在子类构造器中会先调用父类的构造器,默认无参。

如果父类不存在可以被子类访问的构造器,则不能存在子类,也就是全是私有的,则不能有子类。

public static void main(String[] args) {
//创建子类对象
    TianHuiHero th=new TianHuiHero();
}
class DotaHero {
    String name;
    int    age;
    String race;
    String belive;
//父类的无参构造,打印文字方便观察
    public DotaHero() {
        System.out.println("倒不了的塔");
    }
}
class TianHuiHero extends DotaHero {
//子类的无参构造
    public TianHuiHero() {
//这里隐藏一个 super();
        System.out.println("天辉胜利");
    }
    
}

执行打印,先调用了父类的构造函数,其实父类构造函数也有一个默认super()。

如果父类没有提供无参数的构造器,此时子类必须显示通过super语句,去调用父类带有参数的构造器。

 

父类无无参构造,而子类调用的是无参构造时,此时编译器报错。而通过显示super()语句来调用父类有参构造时程序可以编译执行。

 

public class JiCheng {
public static void main(String[] args) {
    TianHuiHero th=new TianHuiHero("剑圣",45,"黄色");
}
}
class DotaHero {
    //当父类中的成员变量设为私有,创建子类时无法直接访问,所以需要调用父类的有参构造器间接访问。
    private String name;
    private int    age;
    String race;
    String belive;
    public DotaHero(String name,int age) {
        this.name=name;
        this.age=age;
    }
}
class TianHuiHero extends DotaHero {
    String color;
    public TianHuiHero(String name,int age,String color) {
//调用父类构造,super必须作为第一句话
        super(name,age);
        this.color=color;
    }
}
原文地址:https://www.cnblogs.com/LuckyGJX/p/8908969.html