简体   繁体   English

使用具有子类变量的父类方法而不覆盖

[英]Using a method of parent class with variable of child class without overriding

I am currently designing two classes in Java, and am having some trouble with understanding my current problem of inheritance, so I've created a simple example code in hopes that someone can help me understand what is going on. 我目前正在用Java设计两个类,并且在理解我当前的继承问题时遇到了一些麻烦,因此我创建了一个简单的示例代码,希望有人可以帮助我理解正在发生的事情。

So in this example, a parent class (for general purpose, we could call it class Car) and a child class (class RedCar). 因此,在此示例中,父类(出于通用目的,我们可以将其称为Car类)和子类(RedCar类)。 The parent class, which is abstract, contains an attribute distance, and contains a method of computeVelocity, which takes input argument time (double), and returns a double value of distance divided by time (thus giving velocity). 父类是抽象的,包含一个属性距离,并包含一个computeVelocity方法,该方法采用输入参数时间(双精度),并返回距离的双精度值除以时间(从而得出速度)。

The child class has a constructor, RedCar(double inputDistance). 子类具有构造函数RedCar(double inputDistance)。 It should also have access to the computeVelocity method, without overriding it. 它也应该可以访问computeVelocity方法,而不要覆盖它。

Here's where the problem is. 这就是问题所在。 Logically, I understand that computeVelocity should not take the inputDistance variable from RedCar because its calling a method of another class. 从逻辑上讲,我知道computeVelocity不应从RedCar中获取inputDistance变量,因为它调用了另一个类的方法。 What I want to know, however, is how to bring that method into the RedCar class so that it could be used within said class with the arguments handed to the constructor. 但是,我想知道的是如何将该方法引入RedCar类,以便可以在传递给构造函数的参数的情况下在该类中使用它。

Here is an example of the code 这是代码示例

//Car Class
public abstract class Car{
  //abstract variable
  private double distance;
  //compute velocity method
  public double computeVelocity(double time){
     return distance/time;
  }
 }




 //RedCar Class
 public class RedCar extends Car{
   public double distance;

   public RedCar (double inputDistance){
      this.distance = inputDistance;
   }
  //This is currently my method but I believe this already constitutes as overridding
  public double computeVelocity(double hours){
      Car.super.computeVelocity(hours);
  }
 }

As stated in some of the comments to you answer, you don't really need and shouldn't have the distance twice (once in the parent class and once in the child class). 正如对您的回答的一些评论中所述,您实际上并不需要两次间隔(一次在父类中,一次在子类中)。 Use the distance parameter from the parent class and there is no reason to override your method. 使用父类的distance参数,没有理由覆盖您的方法。 You can call your parent class method using the super keyword. 您可以使用super关键字调用父类方法。

Hope this helps. 希望这可以帮助。

Since the private instance variable is inherited in the subclass but not accessible in subclass(You can use the reflection to access it). 由于私有实例变量是在子类中继承的,但不能在子类中访问(您可以使用反射来访问它)。 You have two way to provide value in Car instance variable private double distance by providing the public setter or getter method or provide the protected or public constructor and call that constructor from the subclass. 通过提供公共setter或getter方法或提供受保护的或公共的构造函数并从子类调用该构造函数,您可以通过两种方式在Car实例变量私有双倍距离中提供值。

See the link Do subclasses inherit private fields? 参见链接子类是否继承私有字段? inherit-private-fields 继承私有字段

Constructor in the super class which set the value in the private distance variable because private member only accessible by there own member means by their own method and constructor. 超类中的构造函数会在私有距离变量中设置值,因为私有成员只能通过其自身的成员通过自己的方法和构造函数来访问。

    protected Car(double distance){
     this.distance = distance;
     }

And also you have no need to define the distance variable again in the subclass because you are not using it in your method computeVelocity (of subclass). 同样,您也不需要在子类中再次定义距离变量,因为您没有在(子类的)方法computeVelocity中使用它。 Since subclass method call the super class method and the super class method use own private double distance. 由于子类方法调用,因此超类方法和超类方法使用自己的私有双倍距离。 So your distance variable define in subclass not used by the super class method. 因此,您的距离变量在超类方法未使用的子类中定义。

After providing the protected constructor in super class you can call it from subclass constructor using the super keyword.The super keyword call the constructor of the super class. 在超类中提供受保护的构造函数后,您可以使用super关键字从子类构造函数中调用它。super关键字调用超类的构造函数。 Since we provide the constructor in super class so java not add any default constructor in super class. 由于我们在超类中提供了构造函数,因此java不会在超类中添加任何默认的构造函数。 And calling that constructor from sub class using super assign the value in private double distance variable 并使用super从子类调用该构造函数,将值分配给私有double distance变量

     public RedCar(double inputDistance) {
     super(inputDistance);

      }

And correct way to call the super class method is, no need Car.super 调用super类方法的正确方法是,不需要Car.super

    public double computeVelocity(double hours) {
      return super.computeVelocity(hours);
     }

Your class RedCar inherits class Car . 您的RedCar类继承了Car类。 So Car is not just another class. 因此, Car不仅是另一类。 If you create a RedCar instance, all parts of Car are also available. 如果创建RedCar实例,则Car所有部分也都可用。 A RedCar is a Car . RedCar Car

In your solution you have created a field distance both in the super class and in the subclass. 在您的解决方案中,您已经在父类和子类中创建了一个场distance Actually you have two fields named distance in each RedCar instance. 实际上,每个RedCar实例中都有两个名为distance字段。

Here comes the visibility into account. 这里考虑了可见性。 Though the private variable distance is part of RedCar it is only visible in class Car . 尽管私有变量distanceRedCar一部分,但仅在Car类中可见。 If only methods defined in Car needs to access distance there is no need to change the visibility. 如果仅Car定义的方法需要访问distance ,则无需更改可见性。 But you need a way to set the distance . 但是您需要一种设置distance If the value doesn't change over time, you should include a constructor in class Car . 如果该值不随时间变化,则应在Car类中包含一个构造函数。

The visibility of method computeVelocity() defined in Car is public, so there is no need to repeat it in the subclass. Car定义的方法computeVelocity()的可见性是公共的,因此无需在子类中重复它。 Because a RedCar is a Car you can call computeVelocity() on each RedCar instance. 因为RedCarCar您可以在每个RedCar实例上调用computeVelocity()

public abstract class Car{
  private double distance;

  // Constructor with visibility protected.
  // So it is visible in each subclass and must be 
  // called by each subclass constructor.
  // Btw.: It is common practice to use the same name
  // for input parameters as for fields. The field
  // variable can be accessed with the "this" keyword.
  protected Car(double distance) {
    this.distance = distance;
  }

  //compute velocity method
  public double computeVelocity(double time){
     return distance/time;
  }
}


public class RedCar extends Car{
  public double distance;

  public RedCar (double distance){
    // Call the Car constructor
    super(distance)
  }

  // No need to repeat the definition of 
  // computeVelocity unless you want to redefine 
  // the behaviour..
}

Then when you create a RedCar instance: 然后,当您创建RedCar实例时:

RedCar redCar = new RedCar(100.0);

first the RedCar constructor is called which then calls the Car constructor which sets the distance field to 100.0 . 首先调用RedCar构造函数,然后调用Car构造函数,将distance字段设置为100.0

You can call the method: 您可以调用该方法:

double velocity = redCar.computeVelocity(60.0);

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM