C# 继承 - 类的层次结构>
本文关键字:层次结构 继承 | 更新日期: 2023-09-27 18:11:21
嘿伙计们,
我在理解 C# 中的继承过程时遇到问题。我正在做作业,我想分享我想出的代码。我也包括任务。
任务:
Work 1:
Develop a hierarchic structure of classes: shape, circle and cylinder:
Write the base class Shape which has two fields x and y coordinates The function
Display() returns a text string, which contains the point position.
The derived classes Circle and Cylinder inherit x , y coordinates and the method
Display() from base class Shape. You define the new necessary fields and methods
and you override the method Display() to return a text string with the coordinates,
the area and/or the volume.
The computing formulas are:
Circle area : p * r 2
Cylinder area: (2*p * r 2 ) + (2*p * r * h)
Cylinder volume: p * r 2 * h
这是我的代码:
类形状:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace A_Work_1
{
class Shape
{
public int xCoordinate = 0;
public int yCoordinate = 2;
public virtual void Display()
{
Console.WriteLine("The position of the point is: [{0};{1}].", xCoordinate, yCoordinate);
}
}
}
班级圈:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace A_Work_1
{
class Circle : Shape
{
public override void Display()
{
double PI = Math.PI;
double radius = 2;
double circleArea = (PI * radius * radius);
Console.WriteLine("The area of the circle is: {0:F2}", circleArea);
}
}
}
气缸类:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace A_Work_1
{
class Cylinder : Shape
{
public override void Display()
{
double PI = Math.PI;
double radius = 2;
double height = 5.5;
double cylinderArea = (2* PI * radius * radius) + (2 * PI * radius * height);
Console.WriteLine("The area of the cylinder is: {0:F2}", cylinderArea);
double cylinderVolume = (PI * radius * radius * height);
Console.WriteLine("The volume of the cylinder is: {0:F3}'n", cylinderVolume);
}
}
}
和主类:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace A_Work_1
{
class Program
{
static void Main(string[] args)
{
Console.WriteLine("A: Work 1'n");
Shape position = new Shape();
position.Display();
Circle circleArea = new Circle();
circleArea.Display();
Cylinder cylinderArea = new Cylinder();
cylinderArea.Display();
}
}
}
我想知道我哪里做错了。继承的概念对我来说有点难以理解。如何改进此练习以完成任务?
谢谢你的回答! 五.
编辑:
我已经编辑了代码,所以现在应该有适当的内在。最后一个问题。我应该把代码 Console.WriteLine 放在哪里来获取输出?
类形状:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace A_Work_1
{
class Shape
{
public int xCoordinate = 0;
public int yCoordinate = 2;
public string Display()
{
string xCoordinateString = xCoordinate.ToString();
string yCoordinateString = yCoordinate.ToString();
return xCoordinateString + yCoordinateString;
}
}
}
班级圈:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace A_Work_1
{
class Circle : Shape
{
public new string Display()
{
double PI = Math.PI;
double radius = 2;
double circleArea = (PI * radius * radius);
string circleAreaString = circleArea.ToString();
return circleAreaString;
}
}
}
类气缸:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace A_Work_1
{
class Cylinder : Circle
{
public string Display(double radius, double PI)
{
double height = 5.5;
double cylinderArea = (2* PI * radius * radius) + (2 * PI * radius * height);
string cylinderAreaString = cylinderArea.ToString();
double cylinderVolume = (PI * radius * radius * height);
string cylinderVolumeString = cylinderVolume.ToString();
return cylinderVolumeString + cylinderAreaString;
}
}
}
主类保持不变。谢谢,V。
最后编辑:
我已经更改了主类代码,所以现在有这样的 Console.WriteLine 代码:
Shape position = new Shape();
Console.WriteLine(position.Display());
我遇到的最后一个问题是,当我运行应用程序时,我得到的圆面积和圆柱面积的数字相同。看起来类 Cylinder 中的 Display 方法正在使用类 Circle 的返回值。这怎么可能?
最好将半径和高度移动到类级别,如下所示:
class Circle : Shape
{
public double radius = 2;
...
class Cylinder : Circle
{
public double height = 5.5;
...
而且你的Display()
现在不好,编辑前更好。它应该是无参数的,并且应该override
你的基方法。 Display()
Shape
:
public virtual string Display()
{
return "[" + this.xCoordinate + ", " + this.yCoordinate + "]";
}
Display()
Circle
:
public override string Display()
{
return base.Display() + Environment.NewLine +
"Area = " + (Math.PI * this.radius * this.radius).ToString();
}
Display()
Cylinder
:
public override string Display()
{
return base.Display() + Environment.NewLine +
"Volume = " + (Math.PI * this.radius * this.radius * this.height).ToString();
}
要写入结果,请使用:
Circle myCircle = new Circle();
Console.WriteLine(myCircle.Display());
Cylinder myCylinder = new Cylinder();
Console.WriteLine(myCylinder.Display());
你会更容易理解从现实生活中的例子继承。
假设你有一个人,一个人有一个ID和一个名字。现在,假设有一个警察,一个警察是从一个人那里继承的,为什么?因为每个警察首先都是一个人(他有名字和身份证(,只有这样你才能知道他是一个警察,如果他有其他额外的细节,比如警察身份证和武器。
在OOP中也是如此,继承类(子类(与继承类(父类(具有相同的属性,但上面有额外的东西,就像你的家庭作业一样,Circle 类有更多独特的东西,添加到Shape类中。我们不是在圆圈中重新编写所有形状内容,而是继承 Shape 类并在 Circle 类中添加额外的信息。
这使得我们和其他程序员更容易理解软件对象是什么,以及它们如何相互连接并用于类似于"现实世界"中的对象(例如,如果你有一个用于管理劳动力的信息系统,你可以有一个"工人"的父亲类和一个"主管"的子类, 因为每个主管首先都是工人(。
希望对您有所帮助。
对于您的特定家庭作业:
在您的特定家庭作业中,我会做的是更改继承,以便圆形继承自形状,圆柱体继承自圆形。因为每个圆柱体也是一个圆,具有额外的属性。
形状是继承的经典教科书示例。不幸的是,这也是一个很难正确处理的情况。
继承的基本规则是,您可以使用继承对 is-a 关系进行建模。
你可以说矩形是一种形状,你也可以说正方形是一种形状。在数学上,你也可以说每个正方形都是一个矩形。但是,如果您从矩形导出正方形,则必须与 Lisskov 聊天。正方形是建模的,而不是矩形。
以这个例子为例(可能出现的问题的进一步解释由链接到的文章给出(
public class Rectangle : Shape{
public virtual int Width{get;set}
public virtual int Height{get;set}
}
public class Square : Rectangle{
public override int Width{get{return Height;} set{Height = value;}}
}
代码中的一些位置
rect.Height = 10;
rect.Width = 5;
第二行可能会更改高度,因为将正方形替换为矩形时出现问题。
圆形和圆柱形也是如此。您可以在一张面积为 0.2 平方英寸的纸上画多少个半径为 4 英寸的圆?多少个气缸?我没有计算前者,但后者的答案是没有。它是一个三维形状,不能在二维空间中绘制。你怎么能根据圆和圆柱体高度的知识来构造一个圆柱体。这种关系是用组合来建模的。
在这种特殊情况下,您可以做
abstract class Shape{
public abstract double Area{get;}
}
class Cylinder : Shape{
private Circle baseCircle;
private double height;
public override double Area{
get{//use height and baseCircle for the calculation left.
//Actual code left out because it's homework}
}
体积使用高度和基圆的面积也是如此,以计算体积。
家庭作业问题要求您从显示中返回文本字符串,当前您返回的是 void。 您需要更改方法签名以返回字符串,然后调整调用代码以使用 (Console.WriteLine( 显示该字符串。
每个覆盖形状的类都应该定义它自己的私有属性,例如圆应该有一个常量的 pi(因为它永远不会改变(和一个半径属性。 这将允许您对圆执行其他操作,而无需重新定义这些变量。