1、定义:
当多个类存在相同的属性和方法时,可以将这些公共的属性和方法抽取到父类中,子类可以不用在定义这些方法和属性,使用 extends来声明继承父类即可。
2、细节:
1、子类继承了父类的所有属性和方法,非私有的属性和方法可以在子类直接访问,但是私有的属性和方法不能在子类直接访问,要通过父类提供的公共方法去访问。
2、子类必须调用父类的构造器,完成父类的初始化。
3、当创建子类对象时,不管使用子类哪个构造器,默认情况下都会去调用父类的无参构造器,如果父类没有无参构造器,则必须在子类构造器中使用 super 去指定使用父类的哪个构造器来完成父类的初始化。
4、如果希望去调用父类某个构造器,要显示的调用一下:super(参数列表);
5、super()只能在构造器中使用,必须放在第一行。
6、super() 和 this() 都只能放在构造器第一行,因此两个方法不能共存。
7、父类的构造器的调用不限于直接父类,将一直往上追溯到Object类。
8、子类只能继承一个父类,即单继承机制。
9、子类和父类之间必须满足is-a的逻辑关系。
父类
package com.hsf.extends_;
public class Student {
public String name;
public int age;
private double grade;
public Student() {
System.out.println("父类无参构造器");
}
public Student(String name) {
System.out.println("父类有一个参数构造器");
}
public Student(String name, int age) {
System.out.println("父类2个参数构造器");
}
public double printGrade() {
return grade;
}
}
子类
package com.hsf.extends_;
public class Graduate extends Student{
public Graduate() {
super("smith");
System.out.println("子类无参构造器");
}
public Graduate(String name) {
super("jack", 20);
System.out.println("子类有一个参数构造器");
}
public Graduate(String name, int age) {
super();
System.out.println("子类2个参数构造器");
}
public void Test() {
System.out.println(name);
System.out.println(age);
double Grades = printGrade();
System.out.println(Grades);
}
}
测试类
package com.hsf.extends_;
public class Text {
public static void main(String[] args) {
Graduate graduate = new Graduate();
System.out.println("==========");
Graduate graduate2 = new Graduate("Lola");
System.out.println("==========");
Graduate graduate3 = new Graduate("Lola",20);
}
}
继承本质:
1、继承访问规则
(1)、首先看子类是否有该属性,有且可以访问,返回子类属性。
(2)、子类没有,往上看父类,父类有且可以访问,返回父类属性。
(3)、一直往上查找。
package com.hsf.extends_;
public class Detail {
public static void main(String[] args) {
Son son = new Son();
System.out.println(son.name);
// System.out.println(son.age);
System.out.println(son.getAge());
}
}
class GrandFather {
String name = "爷爷";
String hobby = "旅游";
}
class Father extends GrandFather {
String name = "爸爸";
private int age = 30;
public int getAge() {
return age;
}
}
class Son extends Father {
String name = "儿子";
}
继承练习题:
package com.hsf.extends_;
public class Exercise {
public static void main(String[] args) {
B b = new B(); // 调用B类的无参构造器
}
}
class A {
A() {
System.out.println("a");
}
A(String name) {
System.out.println("a name");
}
}
class B extends A {
B() {
// this可以在构造器中访问另一个构造器,但是必须放在第一条语句。
this("abc");
System.out.println("b");
}
B(String name) {
// 默认super();
System.out.println("b name");
}
}
1、super关键字:
1、super代表父类的引用,用于访问父类的属性、方法、构造器。
2、注意事项:
1、可以访问父类的属性(super.属性名),但是不能访问父类的private属性。
2、可以访问父类的方法(super.方法名(参数列表)),但不能访问父类的private方法。
3、访问父类的构造器,只能放在构造器第一行。
4、当子类中和父类中的成员(属性和方法)重名时,如果要访问父类成员,必须使用super。
如果没有重名,则super、this直接访问都是一样的。
3、super和this:
1、方法重写(覆盖):
当父类中继承过来的方法无法满足当前子类业务需求的时候,子类有必要将父类中继承过来的方法进行覆盖/重写
1、就是子类有一个方法,和父类的某个方法名称、返回类型、参数都一样。
2、注意事项:
1、子类的参数、方法名要和父类完全一致。
2、子类方法的返回类型要和父类方法返回类型一致,或者是父类返回类型的子类。
如父类返回类型为 Object,子类返回类型为 String。
3、子类方法不能缩小父类方法的访问权限。
如父类是public,子类是private。
覆盖之后的方法与原方法具有相同的返回值类型、相同的方法名、相同的形式参数列表。