2

我想知道我们是否可以隐藏in 的public属性。Base ClassDerived Class

我有以下用于计算Area不同形状的示例问题陈述 -

abstract class Shape
{
    public abstract float Area();
}

class Circle : Shape
{
    private const float PI = 3.14f;

    public float Radius { get; set; }
    public float Diameter { get { return this.Radius * 2; } }

    public Circle() { }

    public Circle(float radius)
    {
        this.Radius = radius;
    }

    public override float Area()
    {
        return PI * this.Radius * this.Radius;
    }
}

class Triangle : Shape
{
    public float Base { get; set; }
    public float Height { get; set; }

    public Triangle() { }

    public Triangle(float @base, float height)
    {
        this.Base = @base;
        this.Height = height;
    }

    public override float Area()
    {
        return 0.5f * this.Base * this.Height;
    }
}

class Rectangle : Shape
{
    public float Height { get; set; }
    public float Width { get; set; }

    public Rectangle() { }

    public Rectangle(float height, float width)
    {
        this.Height = height;
        this.Width = width;
    }

    public override float Area()
    {
        return Height * Width;
    }
}

class Square : Rectangle
{
    public float _side;

    public float Side
    {
        get { return _side; }
        private set
        {
            _side = value;
            this.Height = value;
            this.Width = value;
        }
    }

    // These properties are no more required
    // so, trying to hide them using new keyword
    private new float Height { get; set; }
    private new float Width { get; set; }

    public Square() : base() { }

    public Square(float side)
        : base(side, side)
    {
        this.Side = side;
    }
}

现在有趣的部分是在SquareHeightWidth属性中不再需要(因为它被Side属性替换)来暴露到外部世界所以我使用new关键字来隐藏它们。但它不起作用,用户现在可以设置Height-Width

class Program
{
    static void Main(string[] args)
    {
        Shape s = null;

        // Height & Width properties are still accessible :(
        s = new Square() { Width = 1.5f, Height = 2.5f };

        Console.WriteLine("Area of shape {0}", s.Area());
    }
}

有谁知道在 C# 中是否可以隐藏不需要的派生类的属性?

重要提示: 有人可能会指出这Shape -> Rectangle -> Square不是一种合适的继承设计。但我想保持这种方式,因为我不想在Square类中再次编写“不准确”但类似的代码(注意:Square类使用Area其基类的方法Rectangle。在现实世界中,如果发生这种类型的继承该方法逻辑可能更复杂)

4

5 回答 5

6

任何子类型仍然基本上能够被视为基本类型的实例。如果有人有一个类型为 base-type的变量,你当然不能隐藏成员。你能做的最多就是让它们在使用派生类型时真的很烦人,例如:

[Obsolete, Browsable(false), EditorBrowsable(EditorBrowsableState.Never)]
public new float Width { get { return base.Width;} }

您也可以使用 做类似的事情override,即使throw访问器(set特别是访问器)使用不当。

但是,这听起来更像是您应该更改继承模型,以便您永远不想尝试删除成员。

于 2013-06-07T13:16:18.587 回答
3

我仍然认为这Shape -> Rectangle -> Square是所有问题的根源。继承不仅仅是代码重用。如果你有类似的代码来计算面积,你可以组合逻辑:即将面积计算的逻辑外化到一个单独的类中,并在 Square 和 Rectangle 中重用。

回到您最初的问题,您需要从子类中隐藏基类中的属性这一事实是一种很大的设计气味 - 语言设计者绝对不会想要这样的功能。

(您可能还想了解Liskov 替换原则

于 2013-06-07T12:51:45.573 回答
1

乍一看,我想我会声明Rectangle'sHeightWidth作为虚拟并在Square类中覆盖它,而不是试图隐藏它们:

class Square : Rectangle
{    
    public float Side{get;set;}

    public override float Height { get{return Side;}; set{Side =value;} }
    public override float Width {get{return Side;}; set{Side =value;} }

    public Square() : base() { }

    public Square(float side)
    {
        this.Side = side;
    }
}
于 2013-06-07T13:16:33.567 回答
1

Square从Rectangle继承的优点是什么?也许您需要一个新课程,例如:

abstract class Square<TFigure> where TFigure : Shape
{
  public float Side {set; get;}

  protected Square(TFigure stereotype)
  {
     Side = GetStereotypeSide(stereotype) 
  }

  public abstract float GetStereotypeSide(TFigure stereotype);
}

那么你的广场看起来像下面

class RectangleSquare: Square<Rectangle>
{
  public RectangleSquare() : base (new Rectangle(){Height = 1, Width = 2})
  {
  }

  public override float GetStereotypeSide(Rectangle stereotype)
  {
     return stereotype.Height*stereotype.Width;
  }
}

如果您仍然需要SquareShape的通用对象而不是您可以定义的对象

interface IGeometry{
}

然后将接口继承添加到两个类

    class Shape : IGeometry
  ....

abstract class Square<TFigure> : IGeometry where TFigure : Shape
于 2013-06-07T13:23:01.577 回答
0

我回应@aquaraga。如果您想隐藏基类中的公共内容,那么派生是不正确的。组合是一个更好的解决方案,在必要时委托给另一个(基)类。

于 2013-06-07T15:17:36.817 回答