面向对象编程(OOP)对象创建指南

5

Suppose to have a polygon class like this one:

public class Polygon 
{
   Point[] _vertices;

   public class Polygon(Point[] vertices)
   {
       _vertices = vertices;
   }
}

如果要制作三角形、正方形、六边形,你更倾向于:

  • 从 Polygon 继承 Triangle、Square 等类,提供一个特定的构造函数并通过编程生成点?
  • 添加一个名为CreateSquare的静态方法,返回一个可以直接使用的 Polygon 类?

这样做:

public class Square : Polygon
{
   public class Polygon(double size)
   {
       _vertices = new Point[]{ new Point(0,0), new Point(size,0), new Point(size,size), new Point(0,size)};
   }
}

或者这样:
public class Polygon 
{
    Point[] _vertices;

    public class Polygon(Point[] vertices)
    {
       _vertices = vertices;
    }

    public static Polygon CreateSquare(double size)
    {
        double verts = new Point[]{ new Point(0,0), new Point(size,0), new Point(size,size), new Point(0,size)};

        return new Polygon(verts);
    }  
 }

从面向对象编程的角度来看,哪种方法更正确?请注意,派生类没有添加任何内容到原始多边形类。
此外,在后一种情况下,是否有任何便捷的命名约定?
我是否还有其他不知道的方法?
谢谢。

在现实世界的编程中,还是某种测试中吗?我的答案会因情况而异。 - mjwills
4
因为“请注意它们的派生类并没有为原始多边形添加任何内容”,所以我支持第二种方法。+1 - Rand Random
我不熟悉C#,但这很有趣,因为我的第一个想法是重载构造函数,这是我认为你理想情况下想要的行为,但与传统的构造函数重载不同,参数的选择并不能很好地指示正在实例化的类型。 - slackOverflow
在现实世界中,“Polygon”可能会成为一个接口,因为特定的更专业的多边形允许许多不同的实现,这可能会使基本实现过于通用。 - poke
3个回答

3
在不知道这些类的使用上下文的情况下,这个问题没有一个明确的答案。但是,如果没有更特定的类的需求,我不会创建它们。就像你不会创建 RedPolygon 或者 BlueSquare ,而是给 Polygon 添加一个 Color 属性一样。
只有当正方形独有的行为出现时,你才需要创建子类。例如,某些数学运算(如碰撞检测)可能在正方形上比在多边形上更快。

2
遵循SOLID原则。我会选择使用继承的解决方案。 开放/封闭原则指实体应该对扩展开放,但对修改封闭。因此,要获得另一个形状,您不应该需要更改多边形类。
如果有人想添加六边形,他只需创建一个新的源文件,让六边形继承自多边形,而不是修改您现有的多边形源代码,这将需要他访问您的源代码。同时,修改现有源代码会增加引入新代码中出现错误的风险。虽然在您的简单示例中,仅创建新形状的风险不会太大,但一旦您想要添加特定于不同形状的某些计算,风险就会上升。
你可以根据YAGNI原则进行争论,该原则指出如果没有必要实现某个功能,则不应该实现。因此,如果您不需要考虑进一步的扩展,因为您对源代码和使用此源代码的所有程序都具有完全控制权,则还可以使用静态“工厂”方法来解决问题。
如需进行更深入的讨论,请参阅本文

1
如果Square、Triangle等不扩展Polygon,添加特定类别没有意义。
你说派生类并未给Polygon增加任何内容,这可能表明"HAS A"而不是"IS A"关系。Square是一个Polygon,但它有顶点。
话虽如此,我也不会将它们放在类的静态方法中,除非你打算只为有限数量的多边形类型提供服务。由于多边形的数量是无限的,当你需要添加新形状时,你会编辑该类吗?
如果Polygon是一个基本对象,应该将其保留为简单的基本对象,并让工厂创建具体对象。
再次强调,这更像是一个有点模糊的考试问题,故意让事情变得模糊。

谢谢,你说的“并留给工厂去创建特定对象”是什么意思?是指一个额外的类来创建对象吗? - abenci
是的,工厂是一个额外的类,其唯一目的是创建某种对象。它用于封装对象如何被创建的知识。 - BoeseB

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接