Java 教程

Java 控制语句

面向对象编程

Java 内置类

Java 文件处理

Java 错误和异常

Java 多线程

Java 同步

Java 网络

Java 集合

Java 接口

Java 数据结构

Java 集合算法

高级 Java

Java 杂项

Java API 和框架

Java 类引用

Java 有用资源

Java - 继承



Java 继承

在 Java 编程中,继承是 Java OOPs 的一个重要概念。继承是一个类获取另一个类属性(方法属性)的过程。通过使用继承,信息以分层的方式进行管理。

继承其他类属性的类称为子类(派生类、子类),而其属性被继承的类称为超类(基类、父类)。

Java 继承的必要性

  • 代码重用:继承的基本需求是重用功能。如果您已经定义了一些功能,通过使用继承,您可以在其他类和包中轻松地使用它们。
  • 可扩展性:继承有助于扩展类的功能。如果您有一个具有某些功能的基类,您可以通过在派生类中使用继承来扩展它们。
  • 方法覆盖的实现:实现多态性的一个概念,即方法覆盖,需要继承。
  • 实现抽象:OOPs 的另一个概念,即抽象,也需要继承。

Java 继承的实现

要在 Java 中实现(使用)继承,使用 extends 关键字。它将基类的属性(属性或/和方法)继承到派生类。单词“extends”表示扩展功能,即功能的可扩展性。

实现继承的语法

请考虑以下语法在 Java 中实现(使用)继承

class Super {
   .....
   .....
}
class Sub extends Super {
   .....
   .....
}

Java 继承示例

以下是一个演示 Java 继承的示例。在此示例中,您可以观察到两个类,即 Calculation 和 My_Calculation。

使用 extends 关键字,My_Calculation 继承了 Calculation 类的 addition() 和 Subtraction() 方法。

复制并粘贴以下程序到名为 My_Calculation.java 的文件中

实现继承的 Java 程序

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

执行程序后,将产生以下结果:

输出

The sum of the given numbers:30
The difference between the given numbers:10
The product of the given numbers:200

在给定的程序中,当创建 My_Calculation 类的对象时,其内部会创建超类内容的副本。因此,使用子类对象可以访问超类的成员。

Inheritance

超类引用变量可以保存子类对象,但使用该变量只能访问超类的成员,因此要访问两个类的成员,建议始终创建子类的引用变量。

如果您考虑上述程序,您可以如下所示实例化类。但是,使用超类引用变量(在本例中为 cal)无法调用属于子类 My_Calculation 的方法 multiplication()

Calculation demo = new My_Calculation();
demo.addition(a, b);
demo.Subtraction(a, b);

注意 - 子类继承其超类中的所有成员(字段、方法和嵌套类)。构造函数不是成员,因此不会被子类继承,但可以从子类调用超类的构造函数。

Java 继承:super 关键字

super 关键字类似于 this 关键字。以下是使用 super 关键字的场景。

  • 它用于区分超类的成员与子类的成员,如果它们具有相同的名称。

  • 它用于从子类调用超类的构造函数。

区分成员

如果一个类继承了另一个类的属性。并且如果超类的成员与子类具有相同的名称,为了区分这些变量,我们使用 super 关键字,如下所示。

super.variable
super.method();

示例代码

本节为您提供了一个演示 super 关键字用法的程序。

在给定的程序中,您有两个类,即 Sub_classSuper_class,它们都具有名为 display() 的方法,但实现不同,并且变量 num 的值也不同。我们调用两个类的 display() 方法并打印两个类的变量 num 的值。在这里您可以观察到我们使用了 super 关键字来区分超类的成员与子类的成员。

复制并粘贴程序到名为 Sub_class.java 的文件中。

示例

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

执行程序后,您将获得以下结果:

输出

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

调用父类构造函数

如果一个类继承了另一个类的属性,子类会自动获取父类的默认构造函数。但是,如果你想调用父类的带参数构造函数,你需要使用 super 关键字,如下所示。

super(values);

示例代码

本节提供的程序演示了如何使用 super 关键字调用父类的带参数构造函数。该程序包含一个父类和一个子类,其中父类包含一个接受整数值的带参数构造函数,我们使用 super 关键字调用了父类的带参数构造函数。

复制并粘贴以下程序到一个名为 Subclass.java 的文件中。

示例

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

输出

The value of the variable named age in super class is: 24

IS-A 关系

IS-A 是一种说法:这个对象是那个对象的一种类型。让我们看看如何使用extends关键字来实现继承。

public class Animal {
}

public class Mammal extends Animal {
}

public class Reptile extends Animal {
}

public class Dog extends Mammal {
}

现在,根据上面的例子,在面向对象的术语中,以下为真 -

  • Animal 是 Mammal 类的父类。
  • Animal 是 Reptile 类的父类。
  • Mammal 和 Reptile 是 Animal 类的子类。
  • Dog 是 Mammal 和 Animal 类的子类。

现在,如果我们考虑 IS-A 关系,我们可以说 -

  • Mammal IS-A Animal
  • Reptile IS-A Animal
  • Dog IS-A Mammal
  • 因此:Dog IS-A Animal 也是如此

通过使用 extends 关键字,子类将能够继承父类所有属性,除了父类的私有属性。

我们可以通过使用 instanceof 运算符来确保 Mammal 实际上是一个 Animal。

示例

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);
   }
}

输出

true
true
true

既然我们已经很好地理解了extends关键字,让我们看看如何使用implements关键字来获得 IS-A 关系。

通常,implements关键字用于类继承接口的属性。接口不能被类扩展。

示例

public interface Animal {
}

public class Mammal implements Animal {
}

public class Dog extends Mammal {
}

Java 继承:instanceof 关键字

让我们使用instanceof运算符来检查确定 Mammal 是否实际上是 Animal,以及 dog 是否实际上是 Animal。

示例

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);
   }
}

输出

true
true
true

HAS-A 关系

这些关系主要基于用法。这决定了某个类是否HAS-A某个东西。这种关系有助于减少代码重复和错误。

让我们来看一个例子 -

示例

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 类会自行执行该操作或要求另一个类执行该操作。

Java 继承的类型

在 Java 中,主要有三种类型的继承:单一多层层次。Java 不支持多重混合继承。

Types of Inheritance

需要记住的一个非常重要的点是,Java 不支持多重和混合继承。这意味着一个类不能扩展多个类。因此,以下是非法的 -

1. Java 单一继承

只有一个基类和一个派生类的继承称为单一继承。单一(或单层)继承仅从一个基类继承数据到一个派生类。

Java 单一继承的示例

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();
  }
}

输出

printOne() method of One class.

2. Java 多层继承

基类被继承到派生类,并且该派生类进一步被继承到另一个派生类的继承称为多层继承。多层继承涉及多个基类。

Java 多层继承的示例

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();
  }
}

输出

printOne() method of One class.
printTwo() method of Two class.

3. Java 层次继承

只有一个基类和多个派生类的继承称为层次继承。

Java 层次继承的示例

// 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();
  }
}

输出

printOne() Method of Class One
printOne() Method of Class One

示例

public class extends Animal, Mammal{} 

但是,一个类可以实现一个或多个接口,这帮助 Java 摆脱了多重继承的不可能。

广告