C# GetName() 、 GetArea() 用于自定义接口“IShape”及其派生类

问题描述 投票:0回答:4

我有一个任务:

有一个层次结构:“Shape” - 接口,“Triangle”,“Circle”,“Rectangle” - “Shape”的派生类,“IsoscelesTriangle” - “Triangle”的派生类,“Square” - “”的派生类长方形”。 “Shape”有方法: GetArea() - 返回几何形状的面积, GetName() - 返回几何形状的名称。对于每个派生类,区域和名称都可以确定。控制台程序通过名称和区域的输出消息演示了多态性原理。

我的主要造型是这样的:

try {
  Problem1_2.IShape triangle2 = new Problem1_2.Triangle("triangle", 5, 10);
  double triangle2Area = triangle2.GetArea();
  string triangle2Name = triangle2.GetName();
  Console.WriteLine($"Name={triangle2Name}, Area={triangle2Area}");

  Problem1_2.IShape isoTriangle2 = new Problem1_2.IsoscelesTriangle("isosceles triangle", 2, 10);
  double isoTriangle2Area = isoTriangle2.GetArea();
  string isoTriangle2Name = isoTriangle2.GetName();
  Console.WriteLine($"Name={isoTriangle2Name}, Area={isoTriangle2Area}");

  Problem1_2.IShape circle2 = new Problem1_2.Circle("circle", 5);
  double circle2Area = circle2.GetArea();
  string circle2Name = circle2.GetName();
  Console.WriteLine($"Name={circle2Name}, Area={circle2Area}");

  Problem1_2.IShape rect2 = new Problem1_2.Rectangle("rectangle", 2, 10);
  double rect2Area = rect2.GetArea();
  string rect2Name = rect2.GetName();
  Console.WriteLine($"Name={rect2Name}, Area={rect2Area}");

  Problem1_2.IShape square2 = new Problem1_2.Square("square", 2);
  double square2Area = square2.GetArea();
  string square2Name = square2.GetName();
  Console.WriteLine($"Name={square2Name}, Area={square2Area}");
} catch (Exception) {
  Console.WriteLine("Critical error: Value cannot be negative");
}

我的自定义类命名空间如下所示:

interface IShape
{
    string GetName();
    double GetArea();
}

public class Triangle : IShape
{
    protected double side;
    protected double height;
    protected string name;

    public Triangle(string name, double side, double height)
    {
        if (side >= 0 && height >= 0)
        {
            this.side = side;
            this.height = height;
        }
        else
        {
            throw new Exception("Critical error: Value cannot be negative");
        }
    }

    protected Triangle(string name)
    {
        Name = name;
    }
    public string Name { get; }

    public virtual string GetName()
    {
        return "Shape: " + Name;
    }

    public double GetArea()
    {
        double area = (side * height) / 2;
        return area;
    }
}

public class Circle : IShape
{
    private double radius;

    public Circle(string name, double radius)
    {
        if (radius >= 0)
        {
            this.radius = radius;
        }
        else
        {
            throw new Exception("Critical error: Value cannot be negative");
        }
    }
    protected Circle(string name)
    {
        Name = name;
    }
    public string Name { get; }

    public virtual string GetName()
    {
        return "Shape: " + Name;
    }

    public double GetArea()
    {
        double area = radius * radius * Math.PI;
        return area;
    }
}

public class Rectangle : IShape
{
    protected double side1;
    protected double side2;

    public Rectangle(string name, double side1, double side2)
    {
        if (side1 >= 0 && side2 >= 0)
        {
            this.side1 = side1;
            this.side2 = side2;
        }
        else
        {
            throw new Exception("Critical error: Value cannot be negative");
        }
    }

    protected Rectangle(string name)
    {
        Name = name;
    }
    public string Name { get; }

    public virtual string GetName()
    {
        return "Shape: " + Name;
    }

    public double GetArea()
    {
        double area = side1 * side2;
        return area;
    }
}

public class IsoscelesTriangle : Triangle
{
    public IsoscelesTriangle(string name, double side, double height) : base(name, side, height) { }

    public double GetArea()
    {
        return base.GetArea();
    }
}

public class Square : Rectangle
{
    private double side1;

    public Square(string name, double side1) : base(name, side1, side1)
    {
        if (side1 >= 0)
        {
            this.side1 = side1;
        }
        else
        {
            throw new Exception("Critical error: Value cannot be negative");
        }
    }

    public double GetArea()
    {
        double area = side1 * side1;
        return area;
    }
}

但由于某种原因,我的类名称变为“null”而不是名称。并仅返回“形状:”而不是:

return "Shape: " + Name;

有人可以帮我解决吗?

c# inheritance
4个回答
1
投票

改变:

protected Triangle(string name)
{
    Name = name;
}
public string Name { get; }

public virtual string GetName()
{
    return "Shape: " + Name;
}

至:

const string Name = "Triangle";

public virtual string GetName()
{
    return "Shape: " + Name;
}

(对于 Circle 等来说也是如此)

您的旧代码允许传入名称,这是不必要的。将他们视为人 - 您不会“告诉”某人他们的名字,您会“询问”他们。因此,类最有可能知道自己的名字 - 所以最好有一个常量。 实例化不同类型的形状时,您使用

base()

0
投票
Name

属性,您需要设置该属性,或者您可以调用设置

Name
属性的构造函数,例如:

public Triangle(string name, double side, double height) { Name = name; // note this if (side >= 0 && height >= 0) { this.side = side; this.height = height; } else { throw new Exception("Critical error: Value cannot be negative"); } }

或者更好的是使用

this()
 调用设置 
Name

属性的构造函数,可以这样做(因为您有可用的构造函数,它设置特定

Name
实例的
IShape
) :

public Triangle(string name, double side, double height) : this(name) { ........ ........ ........ }

同样,您还需要调用

Circle
 的正确构造函数,这也会设置 
Name

属性:


public Circle(string name, double radius) : this(name) // call the constrcutor which takes Name { if (radius >= 0) { this.radius = radius; } else { throw new Exception("Critical error: Value cannot be negative"); } }

最后也为

Rectangle
 类做同样的事情:

public Rectangle(string name, double side1, double side2) : this(name) { ........ ........ ........ }


this(name)
 将导致调用 
Rectangle

Circle
等单参数构造函数的构造函数,为正在实例化的对象设置
Name
属性。

希望有帮助!
    

查看实现

Triangle

0
投票
IShape

类。这意味着该类必须实现

GetName
GetArea
方法。
Triangle
类具有
side1
height
name
属性。

“第一个”构造函数接受字符串、名称、边长和高度变量,检查边长和高度是否大于零,然后设置这些变量的属性。问题:
name
变量永远不会在此构造函数中设置。下面似乎是另一个构造函数…,这是不必要的。只需在原始构造函数中设置

name

即可,正如您应该做的那样。因此,您可以摆脱

protected Triangle(string name)
构造函数以及
Name
getter。您所需要的只是
IShape
接口的两个方法。下面的三角形类:

public class Triangle : IShape { protected double side; protected double height; protected string Name; public Triangle(string name, double side, double height) { if (side >= 0 && height >= 0) { this.side = side; this.height = height; Name = name; } else { throw new Exception("Critical error: Value cannot be negative"); } } public string GetName() { return Name; } public double GetArea() { double area = (side * height) / 2; return area; } }

转到

Circle
Rectangle

类,您可以看到相同的问题:原始构造函数中未设置名称。与上面类似的更改应该可以解决此问题。继续讨论另外两个类

IsoscelesTriangle
,它继承自
Trangle
类和
Square
,它继承自
Rectangle
类。在这些类中,您需要记住,因为您是从其他类继承的…它们保存了我们需要的大部分变量,所以我们只需要初始化基类,然后如果不同就实现
GetArea()
方法。由于
GetArea
方法与基础方法相同......因此无需实现它们,因为基础方法已经实现了它们。如果它们不同,那么您将重写该类的
GetArea
方法。

public class IsoscelesTriangle : Triangle { public IsoscelesTriangle(string name, double side, double height) : base(name, side, height) { } } public class Square : Rectangle { public Square(string name, double side1) : base(name, side1, side1) { } }

希望这是有道理的。


我是 C# 新手,我想创建一个类似的项目名称几何图形,它将其类作为平面形状来计算平面形状的面积、周长等。


0
投票

© www.soinside.com 2019 - 2024. All rights reserved.