简体   繁体   English

抽象类的方法重写和方法重载

[英]Method overriding and Method overloading from abstract class

I have to make one abstract class called Shape. 我必须制作一个称为Shape的抽象类。

This abstract class contains one method that is also abstract GetArea(double height, double width); 这个抽象类包含一个方法,它也是抽象GetArea(double height, double width); .

Then i am making inheritance as follow. 然后,我将继承如下。

Rectangle : Shape

and

Oval : Shape

so in this case i am able to override GetArea() with 2 arguments necessary in method. 所以在这种情况下,我可以使用方法中必需的2个参数覆盖GetArea()

Now i have to make Circle : Oval inheritance . 现在,我必须进行Circle : Oval inheritance

So again to calculate area i have to override GetArea method. 所以再次要计算面积,我必须重写GetArea方法。

But in this case logically it needs only one perameter for radius. 但是在这种情况下,从逻辑上讲,它的半径仅需要一个孔径。

What can i do in this case? 在这种情况下我该怎么办?

If i make one more method in shape class for overloading with one argument GetArea(double height) then in that case i have to override it in Rectangle and Oval class which is not necessary? 如果我在形状类中使用一个参数GetArea(double height)为重载提供了另一种方法,那么在这种情况下,我必须在RectangleOval类中重写它,这是不必要的吗?

what is the possible solution? 有什么可能的解决方案?

The methods in the Shape class must be abstract and methods in subclass must be parameterized. Shape类中的方法必须是抽象的,子类中的方法必须被参数化。

You could make the parameters of the shape part of the constructor, or make properties for them. 您可以将形状的参数作为构造函数的一部分,或为其创建属性。

public class Rectangle : Shape
{
    public double Width{ get; set;}

    public double Height{ get; set;}   

    public double GetArea() {return Width * Height;}

}

The method parameters are part of the method definition, and as such cannot be altered when you override them. 方法参数是方法定义的一部分,因此,当您覆盖它们时不能更改它们。

Personally I would add a parameterless method to calculate the area, and add class-specific properties in the derived classes. 我个人将添加无参数方法来计算面积,并在派生类中添加特定于类的属性。

public abstract class Shape {
    public abstract double GetArea();
}

public class Rectangle : Shape {
    public double Height { get; set; }
    public double Width { get; set; }
    public override double GetArea() {
        return Height * Width;
    }
}

public class Oval : Shape {
    public double Radius { get; set; }
    public override double GetArea() {
        return ...;
    }    
}

If the method absolutely has to have parameters (which somewhat defeats the purpose of using OOP here, since the shape's dimensions should be defined in the object and not passed in as parameters), then you've got to go with something, and I guess width and height as good as anything (though this excludes having the design work with a wide variety of shapes). 如果该方法绝对必须具有参数(这在某种程度上违背了使用OOP的目的,因为形状的尺寸应在对象中定义而不是作为参数传递),那么您就必须要考虑一些问题,我猜宽度和高度与其他任何东西一样好(尽管这不包括具有多种形状的设计工作)。

Here's one approach you could take: 您可以采用以下一种方法:

public abstract class Shape
{
    public abstract double GetArea(double width, double height);
}

public class Oval : Shape
{
    public override double GetArea(double width, double height)
    {
        return Math.PI * width * height / 4;
    }
}

public class Circle : Oval
{
    public override double GetArea(double width, double height)
    {
        if (width != height)
        {
            throw new ArgumentException("width and height of a circle must be equal");
        }
        return base.GetArea(width, height);
    }

    // Class-specific convenence method. 
    // Completely separate from two-parameter version of GetArea
    public double GetArea(double diameter)
    {
        return GetArea(diameter, diameter);
    }
}

As noted in the comments, the single-parameter version of GetArea here is completely disconnected from the inherited two-parameter version, but this does demonstrate the use of the inheritance chain and avoiding duplicate code. 如注释中所述,这里的GetArea的单参数版本与inherited两参数版本完全断开连接,但这确实说明了继承链的使用并避免了重复代码。

In your case you're dealing with class instances, so each GetArea method should not receive parameters. 在您的情况下,您正在处理类实例,因此每个GetArea方法都不应接收参数。 Instead they should be properties of the corresponding classes: 相反,它们应该是相应类的属性:

abstract class Shape
{
    abstract int GetArea();
}

class Circle : Shape
{
    public double Radius {get; set;}
    public override int GetArea(){ return Math.PI * Radius * Radius;}
}

class Rectangle : Shape
{
    public double Width{ get; set;}    
    public double Height{ get; set;}   
    public double GetArea() {return Width * Height;}
}

I'd rather implement an interface instead of abstract class and use explicit interface implementation where it's convenient: 我宁愿实现一个接口而不是抽象类,并在方便的地方使用显式接口实现

public interface IShape {
  ... 
  Double GetArea(Double width, Double height);
}

// Abstract class
// It's redundant and here is because it required by the task
public abstract class Shape: IShape {
}

public class Oval: Shape {
  ...
  public Double GetArea(Double width, Double height) {
    return Math.PI * width * height / 4; 
  }
}

public class Circle: Shape {
  ...
  // This method's more convenient
  public Double GetArea(Double diameter) {
    return Math.PI * diameter * diameter * 4;
  }

  // Explicit interface implementation: 
  // We have to implement two arguments method
  // however, it's combersome that's why we hide it under
  // explicit interface implementation
  Double IShape.GetArea(Double width, Double height) {
    return this.GetArea(width / 2);
  }
}

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

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