Hej家伙,
我在理解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);
}
}
}
Class Cylinder:
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;
}
}
}
Class cylinder:
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。
最后编辑:
我已经更改了Main类代码,所以现在有这样的Console.WriteLine代码:
Shape position = new Shape();
Console.WriteLine(position.Display());
我遇到的最后一个问题是,当我运行应用程序时,我获得了Circle Area和Cylinder Area的相同数字。看起来类Cylinder中的Display方法正在使用Circle类的返回值。这怎么可能?
答案 0 :(得分:2)
我认为你更容易理解从现实生活中继承的例子。
假设你有一个人,一个人有一个ID和一个名字。现在,让我们说有一个警察,警察是从一个人继承的,为什么?因为每个警察首先都是一个人(他有一个名字和一个身份证),只有这样你就可以告诉他,如果他有其他额外的细节,比如警察身份和武器,他就是警察。
在OOP中是一样的,继承类(子类)与继承类(父类)具有相同的属性,但是它上面有额外的东西,就像你的作业一样,Circle Class有更多的独特性东西,添加到Shape类。我们不是在圆圈中再次编写所有形状的东西,而是继承Shape类并在Circle Class中添加额外的信息。
这使我们和其他程序员更容易理解软件对象是什么,以及它们如何在它们之间连接并且习惯于在“现实世界”中类似对象(如果你有一个用于管理的信息系统)劳动力,你可以有一个“工人”的父亲班和一个监督员的孩子班,“因为每个监督员都是工人。”
希望它有所帮助。
并为您的特定作业:
我在你的特定作业中会做的是改变继承,以便圆从一个形状继承,一个圆柱继承自一个圆。因为每个Cylinder也是一个圆圈,具有额外的属性。
答案 1 :(得分:2)
最好将半径和高度移动到类级别,如下所示:
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());
答案 2 :(得分:1)
形状是继承的经典教科书示例。不幸的是,这也是一个很难做到的案例。
继承中的基本规则是您可以使用继承建模is-a关系。
你可以说矩形是一个形状,你也可以说一个正方形就是一个形状。在数学上你也可以说每个方格都是一个矩形。但是,如果从矩形派生平方,则必须与Lisskov聊天。 A square is modellingwise not a rectangle
以此为例(对文章链接可能产生的问题的进一步解释)
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}
}
同样适用于体积使用高度和baseCircle的面积来计算体积。
答案 3 :(得分:0)
作业问题要求您从显示中返回一个文本字符串,目前您正在返回void。您需要更改方法签名以返回字符串,然后调整您的调用代码以使用(Console.WriteLine)显示该字符串。
每个覆盖形状的类都应该定义它自己的私有属性,例如circle应该有一个常量pi(因为它永远不会改变)和一个半径属性。这将允许您在圆上执行其他操作,而无需重新定义这些变量。