我想重写一个具有不同类型的属性。
假设我有一个类Point3D,它继承了Point2D,而Class Drawing3D继承了Drawing2D。
我希望两个类Drawing2D和Drawing3D都有相同的属性名点,这将是Drawing2D的Point2D列表,Drawing3D的Point3D列表。
使用相同的属性名,我希望Drawing3D能够在属性点上使用Drawing2D方法。问题是我不能使用重写,因为类型不同。关键字新不起作用,因为Drawing3D似乎有两个属性点( Point2D列表和Point3D列表)。使用Drawing3D上的基本方法,它将遍历Point2D列表。
我的2D课程:
class Point2D
{
public int X { get; set; }
public int Y { get; set; }
public Point2D(int x, int y)
{
X = x;
Y = y;
}
public virtual void Print()
{
Console.WriteLine($"2D Point: [{X}, {Y}]");
}
}
class Drawing2D
{
public string Name { get; set; }
public virtual List<Point2D> Points { get; set; }
public Drawing2D(string name)
{
Name = name;
Points = new List<Point2D>();
}
public void Print()
{
Console.WriteLine($"Drawing name: {Name}");
foreach (var point in Points)
point.Print();
}
}基于2D类的3D类
class Point3D:Point2D
{
public int Z { get; set; }
public Point3D(int x, int y, int z):base(x,y)
{
Z = z;
}
public override void Print()
{
Console.WriteLine($"3D Point: [{X}, {Y}, {Z}]");
}
}
class Drawing3D : Drawing2D
{
public new List<Point3D> Points { get; set; }
public Drawing3D(string name) : base(name)
{
Points = new List<Point3D>();
}
}还有我的主程序
class Program
{
static void Main(string[] args)
{
Drawing3D myDrawing = new Drawing3D("Sketch");
myDrawing.Points.Add(new Point3D(1, 2, 3));
myDrawing.Points.Add(new Point3D(4, 5, 6));
myDrawing.Print();
Console.ReadKey();
}
}其结果是,它没有打印任何点。基本方法Print()遍历Point2D的列表,而不是Point3D。
希望你们能帮我。我喜欢有优雅的代码,也许我的方法不是正确的.
干杯
发布于 2018-06-16 05:55:07
让Point2D和Point3D实现相同的接口,比如IPoint。然后,在这两个类中,您可以创建IPoint类型的字段。然后,您可以保留对两种对象类型的引用:Point2D和Point3D。
这是一般规则:
端口到接口,而不是到实现。
这完全适用于这里。这只是设计原则中的一个,您可能想了解一下。
在接口中,您将实现方法Print() (它将在具体的类中适当地实现),来自绘图类的方法Print()应该将任务委托给IPoint.Print()。
下面是对我的评论进行重构的代码:
public interface IPoint
{
void Print();
}
class Point2D : IPoint
{
public int X { get; set; }
public int Y { get; set; }
public Point2D(int x, int y)
{
X = x;
Y = y;
}
public void Print()
{
Console.WriteLine($"2D Point: [{X}, {Y}]");
}
}
class Point3D : IPoint
{
public int X { get; set; }
public int Y { get; set; }
public int Z { get; set; }
public Point3D(int x, int y, int z)
{
X = x;
Y = y;
Z = z;
}
public void Print()
{
Console.WriteLine($"3D Point: [{X}, {Y}, {Z}]");
}
}
class Drawing2D
{
public string Name { get; set; }
public List<IPoint> Points { get; set; }
public Drawing2D(string name)
{
Name = name;
Points = new List<IPoint>();
}
public void Print()
{
Console.WriteLine($"Drawing name: {Name}");
foreach (var point in Points)
point.Print();
}
}
class Drawing3D : Drawing2D
{
public Drawing3D(string name) : base(name) { }
}发布于 2018-06-16 06:13:29
如果你必须做上面的例子,那么你可以这样做。
public abstract class Point
{
public abstract void Print();
}
class Point2D : Point
{
public int X { get; set; }
public int Y { get; set; }
public Point2D(int x, int y)
{
X = x;
Y = y;
}
public override void Print()
{
Console.WriteLine($"2D Point: [{X}, {Y}]");
}
}
class Point3D : Point2D
{
public int Z { get; set; }
public Point3D(int x, int y, int z) : base(x, y)
{
Z = z;
}
public override void Print()
{
Console.WriteLine($"3D Point: [{X}, {Y}, {Z}]");
}
}
class Drawing<T> where T:Point
{
public string Name { get; set; }
public virtual List<T> Points { get; set; }
public Drawing(string name)
{
Name = name;
Points = new List<T>();
}
public void Print()
{
Console.WriteLine($"Drawing name: {Name}");
foreach (var point in Points)
point.Print();
}
}
class Drawing3D : Drawing<Point3D>
{
public Drawing3D(string name) : base(name)
{
Name = name;
}
}
class Drawing2D : Drawing<Point2D>
{
public Drawing2D(string name) : base(name)
{
Name = name;
}
}发布于 2018-06-16 06:25:30
在您的问题中,您已经将Point2D类的方法打印覆盖到Point3D类中,这很好。
这意味着您已经在Point3D中专门实现了功能Point3D,它与Point2D的Print功能分离,应该打印有关3D点的信息。
但是,您在Print类中继承了Drawing2D类的方法Drawing3D,这意味着Drawing3D对象对Print方法的任何调用都将执行Drawring2D方法。
现在来看一下Drawing2D的方法,您正在打印关于Drawing2D类的点的信息(Drawing2D有自己的点列表,与Drwaing3D的点列表不同)。
因此,在从Drwaing3D中调用Print方法之后,您将调用Drawing2D的Print方法,并且该方法将尝试打印有关它自己的点的信息(我们还没有设置--因为我们已经设置了Drawing3D的点)。
所以你能做的就是
由于您已经重写了Point类的方法,所以还应该在Drwaing3D类中重写Drawing2D类的Print方法。
就像下面。
class Drawing2D
{
public string Name { get; set; }
public virtual List<IPoint> Points { get; set; }
public Drawing2D(string name)
{
Name = name;
Points = new List<IPoint>();
}
public virtual void Print()
{
Console.WriteLine("Drawing name: {"+Name+"}");
foreach (var point in Points)
point.Print();
}
}
class Drawing3D : Drawing2D
{
public new List<IPoint> Points { get; set; }
public Drawing3D(string name) : base(name)
{
Points = new List<IPoint>();
}
public override void Print()
{
Console.WriteLine("Drawing name: {"+Name+"}");
foreach (var point in Points)
point.Print();
}
}这里,IPoint是两个Point类应该实现的接口。
public interface IPoint
{
void Print();
}
class Point2D : IPoint
{
public int X { get; set; }
public int Y { get; set; }
public Point2D(int x, int y)
{
X = x;
Y = y;
}
public virtual void Print()
{
Console.WriteLine("2D Point: [{"+X+"}, {"+Y+"}]");
}
}
class Point3D:Point2D, IPoint
{
public int Z { get; set; }
public Point3D(int x, int y, int z):base(x,y)
{
Z = z;
}
public override void Print()
{
Console.WriteLine("3D Point: [{"+X+"}, {"+Y+"}, {"+Z+"}]");
}
}更新(这将更多地是继承而不是重写)
不过,上层代码可以正常工作。但我不认为它是完美的。
第一点:点总是一维的,所以不应该有2D点或3D点。
相反,绘图只能是2D或3D (这里根据它所拥有的点数)。
另外,在两个绘图类中,我们都有耦合的打印信息代码。这是重复的,我们可以把它们放在一个地方。
我提议进行如下代码更改。
单点类(这里不需要多个实现或继承)
class Point
{
public int Val { get; set; }
public string CordinateName {get; set;}
public Point(int val, string cordinateName)
{
Val = val;
CordinateName = cordinateName;
}
public virtual void Print()
{
Console.WriteLine(CordinateName + " Point: [{"+Val+"}]");
}
}一个基图类,它包含打印和其他公共属性的功能,如Point list和name (这将在2D或3D类中都是常见的)。
class Drawing
{
public List<Point> Points { get; set; }
public string Name {get; set;}
public Drawing(string name)
{
Name = name;
Points = new List<Point>();
}
public void Print()
{
Console.WriteLine("Drawing name: {"+Name+"} ");
foreach (var point in Points)
point.Print();
}
}从绘图中派生出来的2D绘图几乎是被理解的。
class Drawing2D : Drawing
{
public Drawing2D(string name, int xPoint, int yPoint) : base (name)
{
Points.Add(new Point(xPoint, "X"));
Points.Add(new Point(yPoint, "Y"));
}
}3D绘图源于二维绘图,因为3D绘图包含了二维绘图的所有特征(这里是X点和Y点,以及继承的绘图类特征),同时也有一些其他特性(第3点)只用于3D绘图。
class Drawing3D : Drawing2D
{
public Drawing3D(string name, int xPoint, int yPoint, int zPoint) : base(name, xPoint, yPoint)
{
Points.Add(new Point(zPoint, "Z"));
}
}最后是你的呼叫机制。
public class Program
{
public static void Main(string[] args)
{
Drawing myDrawing3D = new Drawing3D("Sketch 3D", 10, 12, 14);
myDrawing3D.Print();
Drawing myDrawing2D = new Drawing2D("Sketch 2D", 10, 12);
myDrawing2D.Print();
Console.WriteLine("Done");
}
}https://stackoverflow.com/questions/50885274
复制相似问题