1.基本介绍
两个类的属性和方法有很多相同,使用继承 extends(代码复用性)
继承可以解决代码复用,让我们的编程更加靠近人类思维.当多个类存在相同的属性(变量)和方法时,可以从这些类中抽象出父类,在父类中定义这些相同的属性和方法,所有的子类不需要重新定义这些属性和方法,只需要通过 extends 来声明继承父类即可。
继承示意图
2.基本语法
class 子类 extends 父类{
}
-
子类就会自动拥有父类定义的属性和方法
-
父类又叫超类,基类
-
子类又叫派生类
测试类
package com.zyf.erjie.extends01.improve; public class Extends01 { public static void main(String[] args) { com.zyf.erjie.extends01.improve.Pupil pupil = new Pupil(); pupil.name = "lihua"; pupil.age = 11; pupil.testing(); pupil.setScore(50); pupil.showInfo(); System.out.println("======="); com.zyf.erjie.extends01.improve.Graduate graduate = new Graduate(); graduate.name = "linda"; graduate.age = 23; graduate.testing(); graduate.setScore(80); graduate.showInfo(); } }
学生父类
package com.zyf.erjie.extends01.improve; public class Student { //共有属性 public String name; public int age; private double score;//成绩 //共有的方法 public void setScore(double score) { this.score = score; } public void showInfo() { System.out.println("学生名 " + name + " 年龄 " + age + " 成绩 " + score); } }
小学生类
package com.zyf.erjie.extends01.improve; public class Pupil extends Student { public void testing() { System.out.println("小学生 " + name + " 正在考小学数学.."); } }
大学生类
package com.zyf.erjie.extends01.improve; public class Graduate extends Student{ public void testing() {//和 Pupil 不一样 System.out.println("大学生 " + name + " 正在考大学数学.."); } }
3.好处
-
代码的复用性提高了
-
代码的扩展性和维护性提高了
4.细节问题
-
子类继承了所有的属性和方法,非私有的属性和方法可以在子类直接访问, 但是私有属性和方法不能在子类直接访问,要通过父类提供公共的方法去访问
-
子类必须调用父类的构造器(默认调用), 完成父类的初始化
-
当创建子类对象时,不管使用子类的哪个构造器,默认情况下总会去调用父类的无参构造器,如果父类没有提供无参构造器,则必须在子类的构造器中用 super 去指定使用父类的哪个构造器完成对父类的初始化工作,否则,编译不会通过
父类有参构造器
public Base(String name, int age) {//有参构造器 //默认 super() System.out.println("父类 Base(String name, int age)构造器被调用...."); }
子类构造器
public Sub() {//无参构造器 //super(); //默认调用父类的无参构造器 super("smith", 10); System.out.println("子类 Sub()构造器被调用...."); }
-
如果希望指定去调用父类的某个构造器,则显式的调用一下 : super(参数列表)
-
super 在使用时,必须放在构造器第一行(super 只能在构造器中使用)
-
super() 和 this() 都只能放在构造器第一行,因此这两个方法不能共存在一个构造器
//1. 要调用父类的无参构造器, 如下或者 什么都不写,默认就是调用 super() //super();//父类的无参构造器 //2. 要调用父类的 Base(String name) 构造器 //super("zyf"); //3. 要调用父类的 Base(String name, int age) 构造器 super("king", 20); //细节: super 在使用时,必须放在构造器第一行 //细节: super() 和 this() 都只能放在构造器第一行,因此这两个方法不能共存在一个构造器 //this() 不能再使用了 System.out.println("子类 Sub(String name, int age)构造器被调用....");
-
java 所有类都是 Object 类的子类, Object 是所有类的基类.
-
父类构造器的调用不限于直接父类!将一直往上追溯直到 Object 类(顶级父类)
-
子类最多只能继承一个父类(指直接继承),即 java 中是单继承机制。
如何让 A 类继承 B 类和 C 类?---> 【A 继承 B, B 继承 C】
-
不能滥用继承,子类和父类之间必须满足 is-a 的逻辑关系
5.本质
当子类对象创建好后,建立查找关系
要按照查找关系来返回信息
-
首先看子类是否有该属性
-
如果子类有这个属性,并且可以访问,则返回信息
-
如果子类没有这个属性,就看父类有没有这个属性(如果父类有该属性,并且可以访问,就返回信息..)
-
如果父类没有就按照(3)的规则,继续找上级父类,直到 Object...
最先加载的是Object类,然后往下加载,形成继承关系