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

时间:2014-02-06 12:17:57

标签: c# inheritance polymorphism overloading method-overriding

我必须创建一个名为Shape的抽象类。

此抽象类包含一个也是抽象GetArea(double height, double width);的方法。

然后我按照以下方式继承。

Rectangle : Shape

Oval : Shape

因此,在这种情况下,我可以使用方法中必需的2个参数覆盖GetArea()

现在我必须Circle : Oval inheritance

再次计算区域我必须覆盖GetArea方法。

但在这种情况下逻辑上它只需要一个半径的参数。

在这种情况下我该怎么办?

如果我在形状类中再创一个方法以使用一个参数GetArea(double height)进行重载,那么在这种情况下我必须在RectangleOval类中重写它,这是不必要的?< / p>

可能的解决方案是什么?

Shape类中的方法必须是抽象的,并且子类中的方法必须参数化。

5 个答案:

答案 0 :(得分:1)

您可以创建构造函数的形状部分的参数,或为它们创建属性。

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

    public double Height{ get; set;}   

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

}

答案 1 :(得分:1)

方法参数是方法定义的一部分,因此在覆盖它们时不能更改。

我个人会添加一个无参数的方法来计算区域,并在派生类中添加特定于类的属性。

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

答案 2 :(得分:1)

如果方法绝对必须有参数(这在某种程度上违背了在这里使用OOP的目的,因为形状的尺寸应该在对象中定义而不作为参数传递),那么你必须使用某些东西,我猜宽度和高度与任何东西一样好(虽然这不包括设计工作的各种形状)。

以下是您可以采取的一种方法:

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

正如评论中所指出的,GetArea的单参数版本与inherited双参数版本完全断开,但这确实证明了继承链的使用并避免了重复的代码

答案 3 :(得分:0)

在您的情况下,您正在处理类实例,因此每个GetArea方法都不应该接收参数。相反,它们应该是相应类的属性:

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

答案 4 :(得分:0)

我宁愿实现接口而不是抽象类,并在方便的地方使用显式接口实现

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