当前位置: 首页 > 知识库问答 >
问题:

派生不同类型的封装类

闾丘德业
2023-03-14

假设我有一个从Point2D继承的类Point3D和一个从Drawing2D继承的类Drawing3D。

我希望两个类Drawing2D和Drawing3D具有相同的属性名Points,这将是Drawing2D的Point2D列表,以及Drawing3D的Point3D列表。

由于具有相同的属性名,我希望Drawing3D能够在属性点上受益于Drawing2D方法。问题是我不能使用覆盖,因为类型不同。而且关键字new不起作用,因为Drawing3D似乎有两个属性点(一个Point2D的列表和一个Point3D的列表)。在Drawing3D上使用base方法,它将遍历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();
    }
}

基于二维类的三维类

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。

共有1个答案

韦澄邈
2023-03-14

使point2dpoint3d实现相同的接口,比方说iPoint。然后在这两个类中都可以创建IPoint类型的字段。然后您可以在这里保留对两种对象类型的引用:point2dpoint3d

这是一般规则:

Porgram到接口,而不是到实现。

在接口中,您将实现方法print()(它将在具体类中适当实现),而来自drawing类的方法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) { }
}
 类似资料:
  • 我试图反序列化2种不同类型的列表,包括它们的派生类 为了更好地解释它,我做了下面的例子 我有2个系统: API系统 与下列实体合作: 应用系统 使用以下DTO 使用此示例,API系统返回一个

  • 数据结构是指若干个数据的连接方式,一个复杂的数据往往是由若干个不同类型数据形成的结构。派生类型是指用户利用FORTRAN系统内部类型,如数值型、逻辑型、字符型等自行设计出一个新的数据类型,它们实际上是由内部类型数据形成的某种结构。本章主要目的是学会按复杂数据的客观结构形态,由程序员定义出一种派生类型,再结合上将在后面叙述的模块后,可将该类型必需的操作写成内部子程序,连同派生类型一起写在模块中,供程

  • 本文向大家介绍Fortran 派生数据类型,包括了Fortran 派生数据类型的使用技巧和注意事项,需要的朋友参考一下 示例 定义一个新类型mytype: 声明一个mytype类型的变量: 派生类型的组件可以使用%运算符1进行访问: Fortran 2003功能(尚未由所有编译器实现)允许定义参数化数据类型: 派生类型matrix具有以下的类型名称(它们是列在括号中列出了三个类型参数rows,co

  • 如果基类A有一个“public synchronized void method(){}”没有被它的派生类B重写,那么用来访问类B中的synchronized方法的锁是什么(即是派生类对象还是基类对象)?

  • 封箱包装器 这些对象包装器服务于一个非常重要的目的。基本类型值没有属性或方法,所以为了访问 .length 或 .toString() 你需要这个值的对象包装器。值得庆幸的是,JS 将会自动地 封箱(也就是包装)基本类型值来满足这样的访问。 var a = "abc"; a.length; // 3 a.toUpperCase(); // "ABC" 那么,如果你想以通常的方式访问这些字符串值上的

  • 如果我声明以下密封层次结构 没有使用模块(没有module-info.java),并尝试用Maven编译它 我知道https://openjdk.java.net/jeps/409和这个部分: 许可指定的类必须位于超类附近:在同一个模块中(如果超类在命名模块中)或在同一个包中(如果超类在未命名模块中)。 然而,Maven在编译时不应该默认使用类路径吗?这一限制是否可以避免? 如果没有,这是否开创了