[英]Hide Public Properties of Base Class in Derived Class
I was wondering if we could hide public
properties of Base Class
in Derived Class
. 我想知道我们是否可以在Derived Class
隐藏Base Class
public
属性。
I have following sample problem statement for calculating Area
of different shapes - 我有以下样本问题陈述用于计算不同形状的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;
}
}
Now interesting part is here that in Square
class Height
& Width
properties are no more required (as it is replaced by Side
property) to expose to outer wold so I am using new
keyword to hide them. 现在有趣的部分是,在Square
类中, Height
& Width
属性不再需要(因为它被Side
属性替换)以暴露给外部wold所以我使用new
关键字来隐藏它们。 But it is not working and user now can set Height
and Width
- 但它不起作用,用户现在可以设置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());
}
}
Does anyone know in C# is it possible to hide properties of derived class which are not required? 有没有人知道在C#中是否可以隐藏不需要的派生类的属性?
Important Note: One might point out that Shape -> Rectangle -> Square
is not a suitable design of inheritance. 重要说明:有人可能会指出Shape -> Rectangle -> Square
不是一种合适的继承设计。 But I would like to keep it that way because I do not want to write "not exact" but similar code again in Square
class (note: Square
class makes use of Area
method of its base class Rectangle
. In real world, in case of such type of inheritance that method logic may be more complicated) 但是我想保持这种方式,因为我不想在Square
类中再次编写“不完全”但类似的代码(注意: Square
类使用其基类Rectangle
的Area
方法。在现实世界中,如果是这种类型的继承,方法逻辑可能更复杂)
Any sub-type is still fundamentally capable of being treated an instances of the base-type. 任何子类型仍然基本上能够被处理为基类型的实例。 You certainly can't hide the members if someone has a variable typed as the base-type . 如果某人有一个类型为基类型的变量,你肯定无法隐藏成员。 The most you can do would be to make them really annoying to use when using the derived type , for example: 你能做的最多就是在使用派生类型时使它们真的很烦人,例如:
[Obsolete, Browsable(false), EditorBrowsable(EditorBrowsableState.Never)]
public new float Width { get { return base.Width;} }
You could also do something similar with override
, and possibly even throw
if the accessors (the set
in particular) are used inappropriately. 您也可以使用override
执行类似的操作,如果访问器(特别是set
)使用不当,甚至可能throw
。
However, it sounds more like you should be changing the inheritance model such that you never want to try to remove members. 但是,听起来更像是应该更改继承模型,以便您永远不想尝试删除成员。
I still think that Shape -> Rectangle -> Square
is the source of all problems. 我仍然认为Shape -> Rectangle -> Square
是所有问题的根源。 Inheritance is not just about code reuse. 继承不仅仅是代码重用。 If you have similar code to compute area, you can compose the logic: ie externalize the logic of area computation to a separate class, and reuse that in Square and Rectangle. 如果你有相似的代码来计算区域,你可以组成逻辑:即将区域计算的逻辑外部化为一个单独的类,并在Square和Rectangle中重用它。
Coming back to your original question, the fact that you need to hide properties in the base class from the child classes is a big design smell - and the language designers would most definitely not have wanted such a feature. 回到你原来的问题,你需要从子类中隐藏基类中的属性这一事实是一个很大的设计气味 - 语言设计者绝对不会想要这样的功能。
(You may also want to read about Liskov Substitution Principle ) (您可能还想了解Liskov替代原则 )
At first thought, I think I would declare Rectangle
's Height
and Width
as virtual and override it in the Square
class, instead of trying to hide them : 首先想到的是,我认为我会将Rectangle
的Height
和Width
声明为virtual并在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;
}
}
What is an advantage of Square inheritance from Rectangle ? Rectangle的Square继承有什么优势? Maybe you need a new class like: 也许你需要一个新的类,如:
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);
}
then your square can look like following 然后你的广场看起来像下面
class RectangleSquare: Square<Rectangle>
{
public RectangleSquare() : base (new Rectangle(){Height = 1, Width = 2})
{
}
public override float GetStereotypeSide(Rectangle stereotype)
{
return stereotype.Height*stereotype.Width;
}
}
in case you still need a common object for Square and Shape than you can define 如果您仍然需要Square和Shape的公共对象,那么您可以定义
interface IGeometry{
}
and then add the interface inheritance to both classes 然后将接口继承添加到这两个类
class Shape : IGeometry
....
and 和
abstract class Square<TFigure> : IGeometry where TFigure : Shape
I echo @aquaraga. 我回应@aquaraga。 If you desire to hide what's public in a base class then derivation is not right. 如果你想隐藏基类中的公共内容,那么推导是不对的。 Composition is a better solution, delegating to the the other (base) class when necessary. 组合是一种更好的解决方案,必要时委托给另一个(基类)。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.