【问题标题】:call a non inherited method of a derived class调用派生类的非继承方法
【发布时间】:2023-04-09 14:24:01
【问题描述】:

我有这 5 个类。一个名为 Figura 的基类是一个抽象类,还有 4 个具体派生类。

我必须创建一个大小为 8 的 Figuras 数组(两个 Cuadrado、两个 Rectangulo、两个 Triangulo 和两个 Circulo),所以我这样做了:

Figuras[] figuras = new Figuras[8];
figuras[0] = new Cuadrado(1);
figuras[1] = new Cuadrado(2);
figuras[2] = new Rectangulo(2, 1);
figuras[3] = new Rectangulo(6, 2);
figuras[4] = new Triangulo(1, 2, 2);
figuras[5] = new Triangulo(3, 3, 4);
figuras[6] = new Circulo(1);
figuras[7] = new Circulo(4);

然后我遍历数组来计算每个图形的面积和周长。当我尝试调用仅属于图形 Circulo 的方法 calcularDiametro() 时,问题就来了。我该怎么做?

我尝试了以下方法,但它不起作用。

foreach (Figuras f in figuras)
    if (f is Circulo)
        f.calcularDiametro();

任何帮助将不胜感激。

【问题讨论】:

  • 只是一个建议 - 在命名变量、类、方法等时使用英文。 cmets 也是如此。尽管您在这里所做的事情是可以理解的,但它不会被国际团队很好地接受。
  • 感谢您的建议@Filkolev,我确实做到了。这只是一个练习类之间投射的练习

标签: c# .net oop inheritance


【解决方案1】:

您需要将其转换为 Circulo 才能调用特定于 Circulo 的方法:

foreach (Figuras f in figuras) 
{
    if (f is Circulo)
        (Circulo)f.calcularDiametro();
}

请注意,这有点浪费,因为它会进行两次类型检查(这是一项昂贵的操作)。一种避免浪费的方法是使用as

foreach (Figuras f in figuras) 
{
    Circulo circ = f as Circulo;
    if (circ != null)
    {
        circ.calcularDiametro();
    }
}

【讨论】:

    【解决方案2】:

    您可以使用as 运算符并防止额外的强制转换并提高性能

    foreach (Figuras f in figuras)
    {
        var c = f as Circulo;
        if (c != null)
            c.calcularDiametro();
    }
    

    您还可以使用OfType 从您的Enumerable 获取特定类型的对象

    foreach (var c in figuras.OfType<Circulo>())
    {
        c.calcularDiametro();
    }
    

    【讨论】:

      【解决方案3】:

      其他答案在技术上是正确的,但也是错误的。你的问题是你不应该首先从课外开始这些计算。类本身应根据需要执行计算,无论是在构造函数中还是在外部组件请求 perimetro 或 diametro 的值时。那就是封装。

      【讨论】:

      • 封装是计算内部工作的隐藏。这些课程做得很好。在我看来,calcularDiametro 方法不适用于其他形状,因此只有特定的子类具有此方法是完全可以的。
      • 我相信马丁说的很对,这个设计违反了一些原则。
      • 谢谢格伦纳。详细说明:隐藏计算代码但要求客户端启动计算从 OOP 角度来看是没有意义的。您对计算不感兴趣,您只对周长和直径感兴趣(形状的属性)。为产生这些值而需要做的任何事情都应该隐藏起来。这就像去面包店,不要面包,而是告诉男人把面团做成一个形状,放进烤箱,等几个小时,拿出来,放进袋子里递给它给你。现在谁在做面包?
      猜你喜欢
      • 1970-01-01
      • 2016-07-03
      • 2016-07-12
      • 2014-07-09
      • 2015-01-20
      • 2020-10-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多