继承是面向对象的三大特征之一,可以使得子类具有父类的属性和方法,还可以在子类中重新定义,追加属性和方法。继承是指在原有类的基础上,进行功能扩展,创建新的类型。
概念与作用
代码复用:继承能够避免重复编写代码。当多个类存在相同的属性和方法时,可将这些共性提取到父类,子类直接继承使用,减少代码冗余。
构建层次结构:可以构建出层次分明的类结构,清晰展现类之间的 “is - a” 关系,让代码更符合现实世界的逻辑,增强代码的可维护性与可扩展性。
实现多态:继承是实现多态的基础,借助父类引用指向子类对象,能在运行时动态调用子类方法,提升代码的灵活性。
继承的语法
使用 extends
关键字来实现继承。
class ParentClass {// 父类的属性和方法public void parentMethod() {System.out.println("This is a method in the parent class.");}
}class ChildClass extends ParentClass {// 子类可以添加自己的属性和方法public void childMethod() {System.out.println("This is a method in the child class.");}
}
ChildClass 继承自 ParentClass,它可以使用 ParentClass 里的非私有属性和方法,同时还能添加自己特有的属性和方法。
访问父类成员
super 关键字:在子类里,可使用 super 关键字来访问父类的成员。例如,当子类重写父类方法后,若想调用父类的原方法,就可以用 super 关键字。
class Parent {public void printMessage() {System.out.println("Message from parent class");}
}class Child extends Parent {@Overridepublic void printMessage() {super.printMessage(); System.out.println("Message from child class");}
}
构造函数:子类的构造函数会默认调用父类的无参构造函数。若父类没有无参构造函数,子类的构造函数就需要使用 super 关键字显式调用父类的有参构造函数。
class Parent {private int value;public Parent(int value) {this.value = value;}
}class Child extends Parent {public Child(int value) {super(value); }
}
方法重写
定义:子类可以重写父类的方法,也就是在子类中定义一个和父类方法签名(方法名、参数列表、返回类型)相同的方法。重写后的方法会在调用时覆盖父类的方法。
规则:重写方法的访问权限不能比父类方法更严格,返回类型必须和父类方法的返回类型相同或者是其子类型。
class Animal {public void makeSound() {System.out.println("Animal makes a sound");}
}class Dog extends Animal {@Overridepublic void makeSound() {System.out.println("Dog barks");}
}
继承的限制
单继承:在 Java 里,一个类只能有一个直接的父类,也就是单继承。不过,一个类可以实现多个接口,以此实现类似多继承的功能。
访问权限:子类无法直接访问父类的私有成员(私有属性和私有方法),只能通过父类提供的公共方法间接访问。
示例代码
employee类:
package inheritance;import java.time.LocalDate;public class Employee {private String name;private double salary;private LocalDate hireDay;public Employee(String name, double salary, int year, int month, int day) {super();this.name = name;this.salary = salary;hireDay = LocalDate.of(year, month, day);}public String getName() {return name;}public double getSalary() {return salary;}public LocalDate getHireDay() {return hireDay;}public void raiseSalary(double byPercent) {double raise=salary*byPercent/10;salary+=raise;}}
manger类:
package inheritance;public class Manger extends Employee{private double bonus;public Manger(String name, double salary, int year, int month, int day) {super(name, salary, year, month, day);bonus=0;}public double getSalary(){double baseSalary = super.getSalary();return baseSalary + bonus;}public void setBonus(double b){bonus=b;}}
test类:
package inheritance;public class MangerTest {public static void main(String[] args) {Manger boss=new Manger("Carl Cracker", 80000, 1987, 12, 15);boss.setBonus(5000);Employee[] staff=new Employee[3];staff[0]=boss;staff[1] = new Employee("Harry Hacker", 50000, 1989, 10, 1);staff[2] = new Employee("Tommy Tester", 40000, 1990, 3, 15);// print out information about all Employee objectsfor (Employee e : staff)System.out.println("name=" + e.getName() + ",salary=" + e.getSalary());}}