Java 简明教程
Java - Inheritance
Java Inheritance
在 Java 编程中,继承是 Java OOPs 一个重要的概念。继承是一个类获取另一个类的属性 ( methods 和 attributes ) 的过程。通过使用继承,可以在分层顺序中管理信息。
继承其他类属性的类称为子类(派生类、子类),而其属性被继承的类称为超类(基类、父类)。
Need of Java Inheritance
-
Code Reusability :继承的基本需求是重用特征。如果您已经定义了一些功能,那么通过使用继承,您可以轻松地在其他类和软件包中使用它们。
-
Extensibility :继承有助于扩展类的功能。如果您有一个具有某些功能的基本类,您可以使用继承在派生类中扩展这些功能。
-
Implantation of Method Overriding :需要继承来实现多态性,这是一个方法重写的概念。
-
Achieving Abstraction :抽象这一面向对象编程 (OOP) 的另一个概念也需要继承。
Implementation of Java Inheritance
要在 Java 中实现 (使用) 继承,请使用 extends 关键字。它将基类的属性(属性或/和方法)继承到派生类。单词“extends”表示扩展功能,即功能的可扩展性。
Java Inheritance Example
以下是展示 Java 继承的示例。在此示例中,你可以观察到两个类,即 Calculation 和 My_Calculation。
通过使用 extends 关键字,My_Calculation 从 Calculation 类继承 addition() 和 Subtraction() 方法。
将以下程序复制并粘贴到一个名为 My_Calculation.java 的文件中:
Java Program to Implement Inheritance
class Calculation {
int z;
public void addition(int x, int y) {
z = x + y;
System.out.println("The sum of the given numbers:"+z);
}
public void Subtraction(int x, int y) {
z = x - y;
System.out.println("The difference between the given numbers:"+z);
}
}
public class My_Calculation extends Calculation {
public void multiplication(int x, int y) {
z = x * y;
System.out.println("The product of the given numbers:"+z);
}
public static void main(String args[]) {
int a = 20, b = 10;
My_Calculation demo = new My_Calculation();
demo.addition(a, b);
demo.Subtraction(a, b);
demo.multiplication(a, b);
}
}
按如下所示编译并执行上述代码。
javac My_Calculation.java
java My_Calculation
执行程序后,它将生成以下结果 -
Output
The sum of the given numbers:30
The difference between the given numbers:10
The product of the given numbers:200
在给定的程序中,当创建 My_Calculation 类的对象时,超类的内容的副本在其内部生成。这就是为什么,使用子类的对象可以访问超类的成员的原因。
超类引用变量可以保存子类对象,但是仅使用该变量,你可以访问超类的成员,因此为了访问两个类的成员,建议始终为子类创建引用变量。
如果你考虑上述程序,你可以按如下所示实例化类。但是使用超类引用变量(在这种情况下为 cal),你不能调用属于子类 My_Calculation 的方法 multiplication()。
Calculation demo = new My_Calculation();
demo.addition(a, b);
demo.Subtraction(a, b);
Note - 子类会从超类中继承所有成员(字段、方法和嵌套类)。构造函数不是成员,因此不会被子类继承,但可以从子类调用超类的构造函数。
Java Inheritance: The super Keyword
super 关键字类似于 this 关键字。以下是使用 super 关键字的场景。
-
如果超类和子类的成员具有相同名称,则用于从子类的成员中访问 differentiate the members 超类。
-
用于从子类中调用 invoke the superclass 构造函数。
Differentiating the Members
如果一个类正在继承另一个类的属性。并且如果超类的成员与子类的名称相同,则使用 super 关键字区分这些变量,如下所示。
super.variable
super.method();
Sample Code
本节提供了一个演示了 super 关键字用法的程序。
在给定的程序中,你有两个类,即 Sub_class 和 Super_class,它们都具有一个名为 display() 的方法(具有不同的实现)以及一个具有不同值的变量名为 num。我们正在调用两个类的 display() 方法并打印两个类的 num 变量的值。此处你可以观察到,我们使用了 super 关键字以将超类的成员与子类区分开来。
将程序复制并粘贴到名为 Sub_class.java 的文件中。
Example
class Super_class {
int num = 20;
// display method of superclass
public void display() {
System.out.println("This is the display method of superclass");
}
}
public class Sub_class extends Super_class {
int num = 10;
// display method of sub class
public void display() {
System.out.println("This is the display method of subclass");
}
public void my_method() {
// Instantiating subclass
Sub_class sub = new Sub_class();
// Invoking the display() method of sub class
sub.display();
// Invoking the display() method of superclass
super.display();
// printing the value of variable num of subclass
System.out.println("value of the variable named num in sub class:"+ sub.num);
// printing the value of variable num of superclass
System.out.println("value of the variable named num in super class:"+ super.num);
}
public static void main(String args[]) {
Sub_class obj = new Sub_class();
obj.my_method();
}
}
使用以下语法编译并执行上述代码。
javac Super_Demo
java Super
执行程序后,你将获得以下结果 -
Output
This is the display method of subclass
This is the display method of superclass
value of the variable named num in sub class:10
value of the variable named num in super class:20
Invoking Superclass Constructor
如果一个类正在继承另一个类的属性,则子类会自动获得超类的默认构造函数。但是如果你希望调用超类的参数化构造函数,则需要使用 super 关键字,如下所示。
super(values);
Sample Code
本节中给出的程序演示了如何使用 super 关键字调用超类的参数化构造函数。该程序包含一个超类和一个子类,其中超类包含一个接受整数值的参数化构造函数,且我们使用 super 关键字调用超类的参数化构造函数。
将以下程序复制并粘贴到名为 Subclass.java 的文件中
Example
class Superclass {
int age;
Superclass(int age) {
this.age = age;
}
public void getAge() {
System.out.println("The value of the variable named age in super class is: " +age);
}
}
public class Subclass extends Superclass {
Subclass(int age) {
super(age);
}
public static void main(String args[]) {
Subclass s = new Subclass(24);
s.getAge();
}
}
使用以下语法编译并执行上述代码。
javac Subclass
java Subclass
Output
The value of the variable named age in super class is: 24
IS-A Relationship
IS-A 是一种表示方式:此对象是该对象的一种类型。让我们看看 extends 关键字如何用于实现继承。
public class Animal {
}
public class Mammal extends Animal {
}
public class Reptile extends Animal {
}
public class Dog extends Mammal {
}
现在,根据上述示例,按面向对象术语,以下为真 -
-
动物是哺乳动物类的超类。
-
动物是爬行动物类的超类。
-
哺乳动物和爬行动物是动物类的子类。
-
狗既是哺乳动物类的子类,也是动物类的子类。
现在,如果我们考虑 IS-A 关系,我们可以说 −
-
Mammal IS-A Animal
-
Reptile IS-A Animal
-
Dog IS-A Mammal
-
因此:狗也属于动物
通过使用 extends 关键字,子类将能够继承超类的所有属性,除了超类的私有属性。
我们可以使用 instance 运算符来确保哺乳动物实际上是动物。
Example
class Animal {
}
class Mammal extends Animal {
}
class Reptile extends Animal {
}
public class Dog extends Mammal {
public static void main(String args[]) {
Animal a = new Animal();
Mammal m = new Mammal();
Dog d = new Dog();
System.out.println(m instanceof Animal);
System.out.println(d instanceof Mammal);
System.out.println(d instanceof Animal);
}
}
Output
true
true
true
由于我们对 extends 关键字有了很好的理解,让我们研究如何使用 implements 关键字来获取 IS-A 关系。
通常,implements 关键字用于类来继承接口的属性。类永远不能扩展接口。
Example
public interface Animal {
}
public class Mammal implements Animal {
}
public class Dog extends Mammal {
}
Java Inheritance: The instanceof Keyword
让我们使用 instanceof 运算符来检查确定哺乳动物是否实际上是动物,狗是否实际上是动物。
Example
interface Animal{}
class Mammal implements Animal{}
public class Dog extends Mammal {
public static void main(String args[]) {
Mammal m = new Mammal();
Dog d = new Dog();
System.out.println(m instanceof Animal);
System.out.println(d instanceof Mammal);
System.out.println(d instanceof Animal);
}
}
Output
true
true
true
HAS-A relationship
这些关系主要基于使用情况。这确定了某个类是否 HAS-A 某些事情。这种关系有助于减少代码冗余和错误。
让我们看一个例子 −
Example
public class Vehicle{}
public class Speed{}
public class Van extends Vehicle {
private Speed sp;
}
这表明类 Van HAS-A Speed。通过为 Speed 单独创建一个类,我们不必将属于 speed 的所有代码都放入 Van 类中,这使得可以在多个应用程序中重用 Speed 类。
在面向对象特性中,用户不需要操心由哪个对象来完成实际工作。要实现此点,Van 类对 Van 类用户隐藏实现细节。因此,基本上发生的事情是用户会要求 Van 类执行某个动作,而 Van 类会自己完成工作或要求另一个类执行此动作。
Types of Java Inheritance
在 Java 中,主要有三种类型的继承 Single、Multilevel 和 Hierarchical。Java 不支持 Multiple 和 Hybrid 继承。
要记住的一件非常重要的事情是 Java 不支持多重和混合继承。这意味着一个类不能扩展多个类。因此以下是非法的 −
1. Java Single Inheritance
只有一个基类和一个派生类的继承称为单一继承。单一(或单级)继承仅从一个基类继承数据到一个派生类。
class One {
public void printOne() {
System.out.println("printOne() method of One class.");
}
}
public class Main extends One {
public static void main(String args[]) {
// Creating object of the derived class (Main)
Main obj = new Main();
// Calling method
obj.printOne();
}
}
Output
printOne() method of One class.
2. Java Multilevel Inheritance
一个基类继承到一个派生类,而该派生类又进一步继承到另一个派生类的继承称为多级继承。多级继承涉及多个基类。
class One {
public void printOne() {
System.out.println("printOne() method of One class.");
}
}
class Two extends One {
public void printTwo() {
System.out.println("printTwo() method of Two class.");
}
}
public class Main extends Two {
public static void main(String args[]) {
// Creating object of the derived class (Main)
Main obj = new Main();
// Calling methods
obj.printOne();
obj.printTwo();
}
}
Output
printOne() method of One class.
printTwo() method of Two class.
3. Java Hierarchical Inheritance
其中一个基类和多个派生类的继承称为分层继承。
// Base class
class One {
public void printOne() {
System.out.println("printOne() Method of Class One");
}
}
// Derived class 1
class Two extends One {
public void printTwo() {
System.out.println("Two() Method of Class Two");
}
}
// Derived class 2
class Three extends One {
public void printThree() {
System.out.println("printThree() Method of Class Three");
}
}
// Testing CLass
public class Main {
public static void main(String args[]) {
Two obj1 = new Two();
Three obj2 = new Three();
//All classes can access the method of class One
obj1.printOne();
obj2.printOne();
}
}
Output
printOne() Method of Class One
printOne() Method of Class One