gpt4 book ai didi

oop - 使用子类中定义的静态方法进行排序

转载 作者:行者123 更新时间:2023-12-04 06:28:40 25 4
gpt4 key购买 nike

如果之前有人问过类似的问题,我提前道歉,正确描述我要找的东西是相当复杂的,我将用一个例子来解释。

我们将使用名为 Shape 的基类以及以下子类:TriangleSquarePentagon六边形。最后 4 个类分别代表具有 3、4、5 和 6 条边的形状。此信息“属于”类本身,而不属于这些类的实例。

我们还将假设每个类都有一个返回给定颜色的静态方法。给定类的每个实例都将共享相同的颜色。

我想做的是按边数的升序调用我的形状的静态函数getColor()。意思是,我想调用:

  1. 三角.getColor()
  2. Square.getColor()
  3. Pentagon.getColor()
  4. Hexagon.getColor()

不幸的是,我有以下问题(许多编程语言共有)

  • 我不能使用接口(interface),因为信息不属于实例,而是属于类

  • 我无法在我的 Shape 类中定义 getSideCount() 静态函数,因为我无法在我的子类中“覆盖”它得到正确的边数

child classes

我不要求完整的代码,只要求设计建议来解决这个问题。也许我完全错了,我不应该走这条路。不要犹豫,批评并建议一种新的方法来做到这一点。


如果你想要一个更“具体”的例子:

我有一个字符串myString

我有多个类 ABC 定义了 toString 方法。

  • a.toString() 返回 1 个字符的字符串
  • b.toString() 返回 2 个字符的字符串
  • c.toString() 返回 3 个字符的字符串

myStringa.toString()b.toString()c.toString()< 的串联 : ABBCCC.

明天,我可能希望 myStringc.toString()a.toString() 的串联b.toString() : CCCABB.因此,我在类 ABC 中定义了一个静态方法,返回实例在 myString 中的表示位置。我想要做的是以正确的顺序提取我的实例的表示。

执行此操作的“长”方法是:

index ← 0
if( A.position == 1 )
aStr ← extract( myString, index, 1 )
index ← index + 1
elif ( B.position == 1 )
bStr ← extract( myString, index, 2 )
index ← index + 2
elif ( C.position == 1 )
cStr ← extract( myString, index, 3 )
index ← index + 3
endif

if( A.position == 2 )
aStr ← extract( myString, index, 1 )
index ← index + 1
elif ( B.position == 2 )
bStr ← extract( myString, index, 2 )
index ← index + 2
elif ( C.position == 2 )
cStr ← extract( myString, index, 3 )
index ← index + 3
endif

if( A.position == 3 )
aStr ← extract( myString, index, 1 )
index ← index + 1
elif ( B.position == 3 )
bStr ← extract( myString, index, 2 )
index ← index + 2
elif ( C.position == 3 )
cStr ← extract( myString, index, 3 )
index ← index + 3
endif

预先感谢您的宝贵时间和帮助。

最佳答案

有几种方法可以解决这个问题。

  1. 如果您的语言支持(Scala、F#、Haskell),可能最简单的方法是模式匹配。通过支持(详尽的)模式匹配,您可以区分对象类型:

    // syntax will differ from language to language,
    // but you should get the idea

    def getColor(s: Shape): Color = s match {
    case Triangle => Color.Blue
    case Square => Color.Yellow
    ...
    }

    这有效地移动了 getColor类之外的方法,但是你不会用普通的“switch-case”得到的很酷的事情是,如果你没有涵盖所有的情况,编译器会警告你,所以你有效地获得了相同的编译时保证与抽象方法一样。

  2. 一般来说,您需要的是一种从类型映射的方法,所以您不妨只需使用 map 。在 C# 中,您将使用 Dictionary<Key, Value> :

    static readonly Dictionary<Type, Color> _shapeToColor;

    // use this to register a color for each type somewhere at the beginning
    public static Register<T>(Color color) where T : Shape
    {
    _shapeToColor[typeof(T)] = color;
    }

    // generic version for compile-time read
    public static Color GetColor<T>() where T : Shape => _shapeToColor[typeof(T)];

    // or a parameterized version for run-time read
    // (but might fail if incorrect type passed)
    public static Color GetColor(Type t) => _shapeToColor[t];

    // or generally
    public static Color GetColor(object x) => _shapeToColor[x.GetType()];

    这为您提供了更大的灵 active ,但您很容易忘记为新添加的类型注册颜色。此外,您可能会注册一个 ShapeInfo为每种颜色分类,并在其中放置多个 Color , 这样您就没有多本词典了。

  3. 另一个选项(同样是 C# 示例,抱歉,如果您使用的是 Java)是将实例方法与之前的想法(静态字典)和一些反射 。这个想法会是这样的:

    interface IShape
    {
    Color GetColor();
    }

    class Triangle : IShape
    {
    public Color GetColor() => Color.Blue;
    }

    class Square : IShape
    {
    public Color GetColor() => Color.Red;
    }

    static void InitializeValues()
    {
    // use reflection to iterate through all types
    var asm = Assembly.GetAssembly(typeof(IShape));
    foreach (var t in asm.GetTypes())
    {
    // find all Shapes
    if (t.IsInterface ||
    t.IsAbstract ||
    !typeof(IConfigTokenizer).IsAssignableFrom(t))
    continue;

    // instantiate a temporary shape
    var inst = (IShape)Activator.CreateInstance(t);

    // but we are only interested in creating
    // a mapping to the result of GetColor
    _shapeToColor[t] = inst.GetColor();
    }
    }

但是现在您已经用 toString 更新了问题东西,我不再确定你的实际目标是什么。 :)

关于oop - 使用子类中定义的静态方法进行排序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42910503/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com