你好!在前面的课程中,我们已经简要地熟悉了继承的概念。今天,我们将再次讨论这个话题,但不会太深入。以后我们还会有更详细的教训。今天,我们将快速浏览几个实际示例,并熟悉 Java 中一个有趣的运算符。

遗产

那么,什么是继承? instanceof 和继承 101 - 1 继承是一种编程机制(包括在 Java 中),它允许您在现有类的基础上声明一个新类。然后派生类可以访问父类的字段和方法。我们为什么需要这个?好吧,假设您需要在一个程序中创建多个汽车类:Truck、RaceCar、Sedan、Pickup 等。甚至在编写任何代码之前,您就可以肯定地知道所有这些类有很多共同点:所有汽车都有一个模型名称、制造年份、发动机尺寸、最大速度等(更不用说它们都有共同的车轮和其他部件)。在这种情况下,您可以:
  • 在每个类中创建这些字段(在创建时将它们添加到每个新汽车类中)
  • 将所有汽车共有的字段放入一个Car父类中,然后使用关键字extends从该类中派生出特定类型汽车的所有类Car
当然,第二种选择更方便:

public class Car {

   private String model;
   private int maxSpeed;
   private int yearOfManufacture;

   public Car(String model, int maxSpeed, int yearOfManufacture) {
       this.model = model;
       this.maxSpeed = maxSpeed;
       this.yearOfManufacture = yearOfManufacture;
   }
}

public class Truck extends Car {

   public Truck(String model, int maxSpeed, int yearOfManufacture) {
       super(model, maxSpeed, yearOfManufacture);
   }
}

public class Sedan extends Car {
   public Sedan(String model, int maxSpeed, int yearOfManufacture) {
       super(model, maxSpeed, yearOfManufacture);
   }
}
至少,我们避免了不必要的代码重复(我们在编写程序时应该始终努力做到这一点)。另外,我们有一个简单易懂的类结构,所有汽车共有的所有字段都合并到一个类中。如果卡车有任何其他汽车没有的特殊字段,可以在Truck类中声明。方法也是如此。所有的汽车都有一些共同的行为,可以用方法来描述,例如启动汽车,加速/刹车等。这些共同的方法可以合并到父类中,每个特定类型的Car汽车都可以在其派生类中定义其独特的行为.

public class Car {

   public void gas() {
       // Accelerate
   }

   public void brake() {
       // Brake
   }
}


public class F1Car extends Car {

   public void pitStop() {
      
       // Only race cars make pit stops
   }

   public static void main(String[] args) {
      
       F1Car formula1Car = new F1Car();
       formula1Car.gas();
       formula1Car.pitStop();
       formula1Car.brake();
   }
}
我们将所有汽车通用的方法添加到类中Car。但是,看看F1Car代表“一级方程式”赛车的级别。进站(因紧急汽车维修而停止)仅在比赛中进行,因此我们将此特定功能添加到相关的派生类中。 instanceof 和继承 101 - 2

instanceof 运算符

在 Java 中,有一个特殊的运算符instanceof用于检查对象是否是基于特定类创建的。它根据检查结果返回truefalse 。让我们使用汽车示例中的类看看它是如何工作的:

public class Truck extends Car {

   public static void main(String[] args) {

       Truck truck = new Truck();
       System.out.println(truck instanceof Car);
   }
}
输出: true 运算instanceof符返回true,因为我们有一个Truck对象,所有卡车都是汽车。类Truck派生自Car类。所有卡车都是基于共同的父类创建的Car。仔细查看instanceof运算符的使用方式。你写的时候没有句点,因为它是一个运算符,而不是一个方法(“object instanceof Class”)。让我们尝试另一种方式:

public static void main(String[] args) {

   Car car = new Car();
   System.out.println(car instanceof Truck);
}
输出: false 该类Car(和汽车对象)不是从该类派生的Truck。所有卡车都是汽车,但并非所有汽车都是卡车。Car对象不基于类Truck。再举一个例子:

public static void main(String[] args) {

   Car car = new Car();
   Truck truck = new Truck();
   System.out.println(car instanceof Object && truck instanceof Object);
}
输出: True 这里的逻辑也很简单:Java 中的所有类,包括您创建的类,都是该类的后代Object(即使您没有写“extends Object”——它已经暗示了)。这将如何以及何时有用?instanceof重写方法时最常使用运算符equals()。例如,下面是该equals方法在类中的实现方式String

public boolean equals(Object anObject) {
   if (this == anObject) {
       return true;
   }
   if (anObject instanceof String) {
       String anotherString = (String) anObject;
       int n = value.length;
       if (n == anotherString.value.length) {
           char v1[] = value;
           char v2[] = anotherString.value;
           int i = 0;
           while (n-- != 0) {
               if (v1[i] != v2[i])
                       return false;
               i++;
           }
           return true;
       }
   }
   return false;
}
在将 aString与传递的对象进行比较之前,该方法会测试对象是否为字符串?只有这样它才开始比较两个对象的属性。如果此测试不存在,则可以将任何具有长度字段的对象传递给该方法并与 String 进行比较,这当然是错误的。