章
目
录
Java中的继承是指子类可以继承或获取父类的所有非私有属性和行为。继承是面向对象编程的四大特性之一,用于提高层次结构中类之间的代码可重用性。
在本教程中,我们将了解Java 支持的继承类型以及如何在应用程序中实现继承。
1. Java中的继承是什么?
在继承中,默认情况下,一个类扩展另一个类以继承其所有非私有成员。这个类称为子类或子类。子类扩展自的类称为父类或超类。
在Java中,extends关键字用于类之间的继承。
public class Parent {
}
public class Child extends Parent { //Child 类继承 Parent 类
}
2.继承的实际应用
假设我们有一个Employee类。Employee类具有一些属性和方法,所有员工在组织内都必须具备。
在同一个应用程序中,还可以有其他特殊的员工,例如Manager(经理)。经理是组织的普通员工,但另外,他们还有一些其他员工没有的属性,例如下属或部下。
public class Employee {
private Long id;
private String firstName;
private String lastName;
//Getters and Setters
}
public class Manager extends Employee {
private List<Employee> subordinates;
public Manager(long id, String firstName, String lastName, List<Employee> subordinates) {
super(id, firstName, lastName);
this.subordinates = subordinates;
}
}
在上述实现中,员工拥有共同的属性,如id、firstName和lastName;而经理(Manager)仅具有特殊的subordinates属性。为了继承Employee类中的所有非私有成员(在这种情况下,getter和setter方法),Manager类扩展了Employee类。
让我们验证一下Manager类是否也继承了Employee的属性。
Manager manager = new Manager(1l, "Lokesh", "Gupta", List.of(new Employee(2l, "Alex", "Dave")));
System.out.println(manager);
程序输出:
Manager{id=1, firstName='Lokesh', lastName='Gupta', subordinates=[Employee{id=2, firstName='Alex', lastName='Dave'}]}
显然,Manager类能够使用Employee类的属性和方法。
现在考虑一下,如果我们不使用继承。那么我们将不得不在两个类中都维护id、firstName和lastName字段。这将导致代码重复,而代码重复总是会在代码维护中造成问题
3. 继承的类型
在 Java 中,继承可以是四种类型之一——具体取决于类层次结构。
- 单一继承
- 多级继承
- 层次继承
- 多重继承
3.1. 单一继承
在单继承中,一个子类继承一个父类。上面的示例代码(Employee和Manager)是单继承的示例。
在上面的例子中,B类扩展了A类,所以B类是A类的子类。但是C扩展了B,所以B是A类的父类C
。父类也是如此B
,子类也是如此。
3.3. 分层继承
在层次继承中,有一个超类,并且有多个子类扩展超类。
这些子类B
, C
,D
将共享从 继承的公共成员A
,但它们不会知道彼此的成员。
3.4. 多重继承
在图中,类D继承了类A和类B。通过这种方式,D可以继承这两个类的非私有成员。但是,在Java中,我们不能使用extends关键字来继承两个类。那么,多重继承如何实现呢?
在JDK 1.7之前,Java中是不支持多重继承的。但从JDK 1.8开始,可以通过使用带有默认方法的接口来实现多重继承。
4. 访问父类的成员
在子类中,我们可以访问父类的非私有成员。让我们看看如何访问私有成员。
4.1. 构造函数
父类的构造函数可以通过关键字调用super
。只有两条规则:
super()
必须从子类构造函数进行调用。super()
call 必须是构造函数内的第一个语句。
public class Manager extends Employee {
public Manager() {
super(); //在构造函数中必须在第一行调用
//Other statements
}
}
4.2. 作用域
非私有成员字段可以在子类中继承。我们可以使用点运算符访问它们,例如manager.id
。这里的id
属性是从父类继承的Employee
。
私有成员字段必须通过公共getter 和 setter 方法访问。
Manager manager = new Manager(...);
manager.getId();
manager.getFirstName();
manager.getLastName();
在处理父类和子类中同名的字段时,我们必须小心。请记住,成员字段不能被覆盖。具有相同名称的字段将从父类中隐藏该字段,同时通过子类访问。
在这种情况下,将根据引用类型决定访问的属性。例如,假设Employee和Manager有一个共同的属性rating。当我们调用manager. rating时,接收到的值将由引用类型决定。
class Employee {
int rating = 100;
}
class Manager extends Employee {
int rating = 200;
}
Manager manager = new Manager();
System.out.println(manager.rating); //200
Employee mgrEmployee = new Manager();
System.out.println(mgrEmployee.rating); //100
在上面的示例中,即使我们两次创建Manager实例,但rating的值是不同的,因为它是从引用类型引用的。
4.3. 方法
子类可以使用this关键字直接访问父类的非私有方法。子类不能访问父类的私有方法。
在下面的示例中,Manager类能够访问toString()方法中的公共 getter 和 setter 方法。
public class Manager extends Employee {
private List<Employee> subordinates;
@Override
public String toString() {
return "Manager{" +
"id=" + getId() +
", firstName='" + getFirstName() + '\'' +
", lastName='" + getLastName() + '\'' +
", subordinates=" + subordinates +
'}';
}
}
请注意,如果父类和子类具有相同名称的非私有方法,则访问的方法将来自实际的实例类型。
class Employee {
public int getRating() {
return 100;
}
}
class Manager extends Employee {
public int getRating() {
return 200;
}
}
Manager manager = new Manager();
System.out.println(manager.getRating()); //200
Employee mgrEmployee = new Manager();
System.out.println(mgrEmployee.getRating()); //200
5. 结论
让我们总结一下我们对 Java 继承的了解:
- 继承也称为IS-A 关系。
- 它允许子类继承父类的非私有成员。
- 在java中,继承是通过
extends
关键字来实现的。 - 从Java 8开始,您可以使用带有默认方法的接口来实现多重继承。
- 从引用类型类访问成员字段。
- 成员方法是从实际实例类型访问的。
文章目录前言 第1章 Java语言基础 第2章 流程控制语句 第3章 面向对象编程 第4章 Java 字符串 […]