我有3种不同类型的形状图说Rectangle
,Cube
,Circle
,我想为它们定义类,以便
所有课程都有Title&颜色属性/方法,
Circle& Rectangle将有另外的方法Area,
类似地,Cube将使用Volume方法而不是Area方法。
有一种方法可以获得'对象'的引用,下面是示例方法
public void ShapeClicked(object obj)
{
// Check the type of obj & type cast it accordingly & call the method on that object
object obj = new Circle();
if (obj is Circle)
{
Circle circleObj = (Circle)obj;
circleObj.GetArea();
}
else if (obj is Rectangle)
{
Rectangle rectangleObj = (Rectangle)obj;
rectangleObj.GetArea();
}
else if (obj is Cube)
{
Cube cubeObj = (Cube)obj;
cubeObj.GetVolume();
}
}
如何在'ShapeClicked(object obj)'方法
中设计我的类a)我不需要每次检查类型(应该在运行时发生),(这对我很重要,因为我有很多方法,比如'ShapeClicked'需要我检查类型)
b)如果对象是Circle,那么它只会获得Area方法,类似于Cube对象,它只能得到Volume方法。
我可以想到两种方法
放入所有方法&基类中的属性&只覆盖派生类中的必需方法。创建一个Factory方法/类,它将返回Base类的引用。使用这种方法,我的'b'要求不符合
只在基类和放大器中放置常用的方法/属性(如颜色)。在derive类中添加其他方法。这不能解决#a:(
有人能给我一些解决方案吗?#a& amp; #B
答案 0 :(得分:3)
介绍一个新界面。
public interface IMeasurable
{
someReturnType GetMeasure();
}
public class Circle : IMeasurable
{
//some other methods
public someReturnType GetMeasure() { return GetArea(); }
}
public class Cube : IMeasurable
{
//some other methods
public someReturnType GetMeasure() { return GetVolume(); }
}
更新
您的方法如下:
public void ShapeClicked(object obj)
{
var measurable = obj as IMeasurable;
if (measurable == null)
throw new InvalidOperationException(string.Format("We can only work with measurable types, which {0} is not.", obj.GetType());
var measure = measurable.GetMeasure();
}
答案 1 :(得分:0)
是
您应该拥有所有形状的基类,并且在基类中有一个方法ShapeClicked()
。
class Shape
{
-tile
-color
ShapeClicked()
}
class PlanarShape extends Shape
{
-area
Area()
}
class SpatialShape extends Shape
{
-volume
Volume()
}
class Circle extends PlanarShape
{
ShapeClicked()
}
class Rectangle extends PlanarShape
{
ShapeClicked()
}
class Cube extends SpatialShape
{
ShapeClicked()
}
然后将函数修改为:
public void ShapeClicked(Shape obj)
{
obj.ShapeClicked();
}
通过多态性,您的呼叫将被定向到正确的类。
答案 2 :(得分:0)
当您有要继承的常见行为时,使用基类型是很好的。在您的情况下,您确实有一种与您的类型进行交互的常用方法,但这些行为的类型是完全不同的。
在这种情况下,您真正想要做的是定义一个通用界面,以便您可以类似地处理您的类型。
我会定义以下内容:
public interface IShape
{
string Title { get; }
string Color { get; }
}
public interface I2DShape : IShape
{
int GetArea();
}
public interface I3DShape : IShape
{
int GetVolume();
}
然后,您可以在I2DShape
和Circle
以及Rectangle
I3DShape
上实施Cube
。然后您的方法可以这样实现:
public void ShapeClicked(IShape shape)
{
var shape2d = shape as I2DShape;
if(shape2d != null)
{
shape2d.GetArea();
return;
}
var shape3d = shape as I3DShape;
if(shape3d != null)
{
shape3d.GetVolume();
}
}
您仍然需要检查形状是2D还是3D,但这仅仅是因为我们将区域和体积定义为单独的东西。如果你想将它们定义为一个单一的东西,你可以把它放在基础接口上,让所有类型实现该接口。