【问题标题】:C# Class Inheritance Issue with Simple Calculator简单计算器的 C# 类继承问题
【发布时间】:2020-02-02 23:52:12
【问题描述】:

我是 C# 的初学者,正在尝试让我的第二个类 MyCalc2 继承自 MyCalc。但我遇到以下关于 MyCalc2 的错误消息:

没有给出与'MyCalc.MyCalc(int, int, string, string)'的所需形式参数'x'相对应的参数

这里的目标是添加另一个继承自基类的类。

我知道我需要在我的基类中添加类似 'MyCalc: base(x)' 的内容,但我不知道放置参数的位置(如果这甚至是正确的做法)。任何指导将不胜感激。这是我目前所拥有的:

    using System;
class MyCalc
{
    // class variable
    public int x;
    public int z;
    public string y;
    public string n;

    // constructor
    public MyCalc(int x, int z, string y, string n)
    {
        this.x = x;  // assign the parameter passed to the class variable
        this.z = z;
        this.y = y;
        this.n = n;

    }
    // calculate the operations
    public int GetAdd()
    {
        return (this.x + this.z);

    }

    public int GetSubtract()
    { 
        return (this.x - this.z);
    }

    public int GetMultiply()
    {
        return (this.x * this.z);
    }

    public int GetDivide()
    {
        return (this.x / this.z);
    }

    public string GetYes()
    {
        return (this.y);
    }

    public string GetNo()
    {
        return (this.n);
    }

}

class MyCalc2:MyCalc //where the error is occurring 
{
    static void Main(string[] args)



    {
        bool repeat = false;
        do
        {

            repeat = false;


            int x = 0; int z = 0; string y; string n;
            Console.WriteLine("Enter the First Number");
            x = Convert.ToInt32(Console.ReadLine());

            Console.WriteLine("Enter the Second Number");
            z = Convert.ToInt32(Console.ReadLine());



            //Using a switch statement to perform calculation:
            Console.WriteLine("Enter operator\r");
            switch (Console.ReadLine())


            {

                case "+":
                    Console.WriteLine($"The Answer is: {x} + {z} = " + (x + z));
                    break;

                case "-":
                    Console.WriteLine($"The Answer is: {x} - {z} = " + (x - z));
                    break;
                case "*":
                    Console.WriteLine($"The Answer is: {x} + {z} = " + (x + z));
                    break;

                case "/":
                    Console.WriteLine($"The Answer is: {x} - {z} = " + (x - z));
                    break;


            }



                //Repeat or Exit program using the do-while loop:

            string input = Console.ReadLine();
            Console.WriteLine("Do you want another operation(Y / N) ?");
            input = Console.ReadLine();
            repeat = (input.ToUpper() == "Y");

        }
            while (repeat);
            Console.WriteLine("Thanks for using our system.");
            Console.ReadKey();
        }

    }

【问题讨论】:

  • 为什么MyCalc2继承自MyCalc?它不会扩展或覆盖MyCalc 的任何方法。我怀疑你想在你的MyCalc2 中使用new MyCalc(something),而不是从它继承。
  • 您可能需要重新考虑您的设计,继承可能不适合这里。
  • 您可能不应该将 Main 方法包含为 MyClass2 的成员。你是故意这样做的吗?继承应该非常严格地保留在可以说“Childclass is an ParentClass”的情况下。在所有其他情况下,使用继承可能不是一个好主意。我建议只踢出 MyVals2:MyCalc 行,确保所有学徒匹配。您可能会尝试创建一个控制台应用程序。 Main 是入口点,它可能运行良好。

标签: c# class inheritance


【解决方案1】:

MyCalc2 没有初始化 MyCalc(基类)的方法,因为在您的 BaseClass 中您没有无参数构造函数。

解决方案:

  1. 在基类中添加无参数构造函数
  2. 在派生类中添加一个构造函数,该构造函数具有调用基类构造函数的方式

因为您的以下代码应该可以工作:

class MyCalc2 : MyCalc
{
    public MyCalc2 () : base(0, 0, "", "")
    {
    }
}

【讨论】:

    【解决方案2】:

    MyCalc2 没有显式构造函数。这意味着它只有一个 implicit 构造函数,它不接受任何参数并且不设置任何值。如果明确表示,它将如下所示:

    public MyCalc2()
    {
    
    }
    

    然而,MyCalc确实有一个显式的构造函数。这意味着它有 no 隐式构造函数。它的构造函数确实接受参数:

    public MyCalc(int x, int z, string y, string n)
    {
        this.x = x;  // assign the parameter passed to the class variable
        this.z = z;
        this.y = y;
        this.n = n;
    }
    

    因此,当您创建MyCalc2 的实例时,它无法为MyCalc 提供任何值。你基本上有三个选择:

    1. MyCalc 添加一个不带参数的构造函数(只要参数不同,您可以拥有任意数量的构造函数)。但是,在这种情况下,MyCalc 的类级别值都将是默认值。您必须在构造对象后明确设置它们。1
    2. MyCalc2 添加一个构造函数,它接受这些值并将它们传递给父构造函数,或者至少将默认值传递给父构造函数。
    3. 此处不要使用继承。

    老实说,在这种情况下,我会选择第三个选项。继承在这里意味着什么? MyCalc2 不是 MyCalc 的一个实例。它所做的只是保存应用程序的初始入口点(Main 方法),这就是它应该做的所有事情。

    Main 方法中的逻辑应该创建并使用MyCalc 的实例,但具有Main 方法的类不应该尝试成为@987654336 的实例@。这只会造成比解决任何有意义的问题更多的混乱。


    1 旁注:公共类字段历来是面向对象编程的一个坏习惯。关于这个主题有各种各样的讨论,当您继续体验时,您会经常看到这一点。一般来说,您希望您的对象公开行为,而不是。对象上的方法在约定中看起来有点像 Java。对于 C# 约定,请考虑使用属性(其编译为方法本身,语法只是语义不同)。您可以为值本身设置{ get; set; } 自动属性,并为计算值设置显式只读{ get { /*...*/ } } 属性。

    【讨论】:

    • 它被称为字段,而不是“类级变量”。
    【解决方案3】:

    这是一个可能的解决方案。 MyClass 有两个类,用于计算器(您可能想要重命名它)和 Propram。 Program 仅包含 Main 方法,它可以启动您的程序。它是这样工作的,但是还有一些错误。我把它留给你来修复它们。除了您错过了对概念类和继承的清晰理解之外,您的代码对于初学者来说还不错。它几乎可以工作了。

    using System;
    
    namespace TestCalculator
      {
     class MyCalc
    {
    // class variable
    public int x;
    public int z;
    public string y;
    public string n;
    
    // constructor
    public MyCalc(int x, int z, string y, string n)
      {
      this.x = x;  // assign the parameter passed to the class variable
      this.z = z;
      this.y = y;
      this.n = n;
    
      }
    // calculate the operations
    public int GetAdd()
      {
      return (this.x + this.z);
    
      }
    
    public int GetSubtract()
      {
      return (this.x - this.z);
      }
    
    public int GetMultiply()
      {
      return (this.x * this.z);
      }
    
    public int GetDivide()
      {
      return (this.x / this.z);
      }
    
    public string GetYes()
      {
      return (this.y);
      }
    
    public string GetNo()
      {
      return (this.n);
      }
    
    }
     class Program
    {
    static void Main(string[] args)
      {
      bool repeat = false;
      do
        {
    
        repeat = false;
    
    
        int x = 0; int z = 0; string y; string n;
        Console.WriteLine("Enter the First Number");
        x = Convert.ToInt32(Console.ReadLine());
    
        Console.WriteLine("Enter the Second Number");
        z = Convert.ToInt32(Console.ReadLine());
    
    
    
        //Using a switch statement to perform calculation:
        Console.WriteLine("Enter operator\r");
        switch (Console.ReadLine())
    
    
          {
    
          case "+":
            Console.WriteLine($"The Answer is: {x} + {z} = " + (x + z));
            break;
    
          case "-":
            Console.WriteLine($"The Answer is: {x} - {z} = " + (x - z));
            break;
          case "*":
            Console.WriteLine($"The Answer is: {x} + {z} = " + (x + z));
            break;
    
          case "/":
            Console.WriteLine($"The Answer is: {x} - {z} = " + (x - z));
            break;
    
    
          }
    
    
    
        //Repeat or Exit program using the do-while loop:
    
        string input = Console.ReadLine();
        Console.WriteLine("Do you want another operation(Y / N) ?");
        input = Console.ReadLine();
        repeat = (input.ToUpper() == "Y");
    
        }
      while (repeat);
      Console.WriteLine("Thanks for using our system.");
      Console.ReadKey();
      }
    }
    

    }

    【讨论】:

    • @Pedicellaria 如果我们帮助您解决了您的问题,请告诉我们?您可以将其中一个解决方案标记为已回答或有帮助。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-07-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-12-28
    • 1970-01-01
    相关资源
    最近更新 更多