在本教程中,我们将借助示例学习 Java 中的继承。
继承是 OOP(面向对象编程)的关键功能之一,它使我们能够从现有类中定义一个新类。 例如,
class Animal{// eat() method// sleep() method}class Dog extends Animal{// bark() method}
在 Java 中,我们使用extends关键字从类继承。 在这里,我们从Animal类继承了Dog类。
Animal是超类(父类或基类),Dog是子类(子类或派生类)。 子类继承超类的字段和方法。

IS-A 关系
继承是 is-a 关系。 仅当两个类之间存在 is-a 关系时才使用继承。
这里有些例子:
- 汽车是车辆。
- 橙色是水果。
- 外科医生是医生。
- 狗是动物。
示例 1:Java 继承
class Animal {public void eat() {System.out.println("I can eat");}public void sleep() {System.out.println("I can sleep");}}class Dog extends Animal {public void bark() {System.out.println("I can bark");}}class Main {public static void main(String[] args) {Dog dog1 = new Dog();dog1.eat();dog1.sleep();dog1.bark();}}
输出
I can eatI can sleepI can bark
在这里,我们从超类Animal继承了子类Dog。Dog类继承了Animal类的方法eat()和sleep()。
因此,Dog类的对象可以访问Dog类和Animal类的成员。

protected关键字
在先前的教程中,我们了解了private和public访问修饰符。
private成员只能在类内访问public成员可以从任何地方访问
您还可以分配方法和字段protected。 受保护的成员可以访问
- 从类内部
- 在其子类中
- 在同一包内
这是可以访问访问修饰符的摘要。
| 类 | 包 | 子类 | 全局 | |
|---|---|---|---|---|
public |
Yes | Yes | Yes | Yes |
private |
Yes | No | No | No |
protected |
Yes | Yes | Yes | No |
示例 2:protected关键字
class Animal {protected String type;private String color;public void eat() {System.out.println("I can eat");}public void sleep() {System.out.println("I can sleep");}public String getColor(){return color;}public void setColor(String col){color = col;}}class Dog extends Animal {public void displayInfo(String c){System.out.println("I am a " + type);System.out.println("My color is " + c);}public void bark() {System.out.println("I can bark");}}class Main {public static void main(String[] args) {Dog dog1 = new Dog();dog1.eat();dog1.sleep();dog1.bark();dog1.type = "mammal";dog1.setColor("black");dog1.displayInfo(dog1.getColor());}}
输出:
I can eatI can sleepI can barkI am a mammalMy color is black
在此,Animal类内部的type字段受到保护。 我们已经使用Main类访问了此字段,
dog1.type = "mammal";
可能是因为Animal和Main类都在同一包(同一文件)中。
Java 方法覆盖
从上面的示例中,我们知道子类的对象也可以访问其超类的方法。
如果在超类和子类中定义了相同的方法,会发生什么?
好吧,在这种情况下,子类中的方法将覆盖超类中的方法。 例如,
示例 3:方法覆盖示例
class Animal {protected String type = "animal";public void eat() {System.out.println("I can eat");}public void sleep() {System.out.println("I can sleep");}}class Dog extends Animal {@Overridepublic void eat() {System.out.println("I eat dog food");}public void bark() {System.out.println("I can bark");}}class Main {public static void main(String[] args) {Dog dog1 = new Dog();dog1.eat();dog1.sleep();dog1.bark();}}
输出:
I eat dog foodI can sleepI can bark
在此,eat()存在于超类Animal和子类Dog中。 我们创建了子类Dog的对象dog1。
当我们使用dog1对象调用eat()时,将调用Dog内部的方法,而不会调用相同的超类方法。 这称为方法覆盖。
在上面的程序中,我们使用了@Override注解来告诉编译器我们正在覆盖方法。 但是,这不是强制性的。 在下一个教程中,我们将详细了解方法覆盖。
如果需要从其子类中调用Animal的eat()方法,则可以使用super关键字。
示例 4:super关键字
class Animal {public Animal() {System.out.println("I am an Animal");}public void eat() {System.out.println("I can eat");}}class Dog extends Animal {public Dog(){super();System.out.println("I am a dog");}@Overridepublic void eat() {super.eat();System.out.println("I eat dog food");}public void bark() {System.out.println("I can bark");}}class Main {public static void main(String[] args) {Dog dog1 = new Dog();dog1.eat();dog1.bark();}}
输出:
I am an AnimalI am a dogI can eatI eat dog foodI can bark
在这里,我们使用super关键字使用super()调用构造器。 此外,我们使用super.eat()调用了Animal超类的eat()方法。
请注意,在调用构造器和方法时,super的用法有所不同。 要了解更多信息,请访问 Java super关键字 。
继承类型
继承有五种类型。
- 单一继承 - 类
B仅从类A扩展。 - 多级继承 - 类
B从类A扩展而来; 然后C类从B类扩展。 - 层次继承 - 类
A充当类B,C和D的超类。 - 多重继承 - 类
C从接口A和B扩展。 - 混合继承 - 两种或更多种继承的混合。
Java 不支持通过类的多重继承和混合继承。 但是,我们可以通过接口在 Java 中实现多重继承。 我们将在后面的章节中了解接口。
为什么要使用继承?
- 最重要的用途是代码的可重用性。 父类中存在的代码无需在子类中再次编写。
- 通过方法覆盖实现运行时多态。 在后面的章节中,我们将学习有关多态的更多信息。
