2011-10-17 112 views
2

HEJ家伙,C#继承 - >的类层次结构

我理解在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 

这是我的代码有:

类Shape:

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(); 

    } 
} 
} 

我想知道我在哪里得到它错了。继承的想法对我来说有点难以理解。我如何改进这个练习来完成任务?

谢谢你的回答!五

编辑:

我已编辑的代码,所以现在应该有适当的inherting。最后一个问题。我应该在哪里放置代码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; 
    } 
} 
} 

Main类保持不变。 谢谢,五

最后编辑时间:

我修改了主类代码,所以现在有Console.WriteLine这样的代码:

Shape position = new Shape(); 
Console.WriteLine(position.Display()); 

最后一个问题我有,是,当我运行应用程序我得到了圆区和圆柱区的相同编号。它看起来像Cylinder类中的Display方法使用Circle类的返回值。这怎么可能?

+1

你说你はnt来知道你错在哪里。你认为什么是错的?你没有得到你期望的答案吗? –

+2

创建圆柱体类时,应该考虑构图,而不是重复计算圆的面积的代码。圆柱可以表示为圆形和高。然后使用圆的属性来计算圆柱的体积和面积 –

+0

@Rune,我也这么认为,但是指令告诉他'Cylinder'类只继承了来自'Shape'的坐标。可能它的措辞很糟糕。 –

回答

2

这是更好地半径和高度移动到一流水平,是这样的:

class Circle : Shape 
{ 
    public double radius = 2; 
    ... 

class Cylinder : Circle 
{ 
    public double height = 5.5; 
    ... 

而且你现在Display()并不好,这是编辑以前更好。它应该是无参数的,它应该是您的基本方法overrideDisplay()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()); 
+0

谢谢,这真是很好的解决方案!但是现在我的输出是这样的:从形状输出,从圆形输出,再次从形状输出,再次从圆形输出,从圆柱形输出。我怎样才能从每个只有一个? – Vojtech

+0

@Vojtech:对于所需的输出,只需从方法中删除'base.Display()+ Environment.NewLine'调用。 – Mentoliptus

+0

没关系,现在我明白了,这是因为调用Circle方法Display ..当我只打电话给Cylinder时,它的工作非常完美! – Vojtech

0

作业问题会要求您从显示中返回一个文本字符串,而目前您将返回void。您需要将方法签名更改为返回字符串,然后调整您的调用代码以使用(Console.WriteLine)显示该字符串。

覆盖形状的每个类都应该定义它自己的私有属性,例如circle应该有一个常量pi(因为它永远不会更改)和radius的属性。这将允许您在圆上执行其他操作,而不必重新定义这些变量。

+6

为什么Math.Pi已经给出了一个常数? –

2

我认为从现实生活的例子中可以更容易理解继承。

可以说你有一个人,一个人有一个ID和一个名字。现在,让我们说有一个警察,一个警察是从一个人继承的,为什么?因为每个警察首先是一个人(他有一个姓名和一个身份证),并且只有在那时你才能告诉他他是一个警察,如果他有其他EXTRA细节,如警察ID和武器。

在OOP中它是一样的,一个继承类(子类)与继承类(父类)具有相同的属性,但它有额外的东西,就像你的作业一样,Circle类有更多独特的东西,添加到形状类。我们没有在圆圈中重新编写所有形状的东西,而是继承Shape类并在Circle类中添加额外的信息。

这让我们更容易了解其他程序员,让他们了解软件对象是什么,以及它们如何在自己之间进行连接,并用于模拟“真实世界”中的对象(如果您有例如信息系统管理工作的力量,你可以有一个父类中的“工人”和子类监事”的,因为每一个监督员首先是工人)。

希望它能帮助。

和特定的功课:

我会d o在你的具体作业中正在改变继承,所以圆是从形状继承而圆柱体是从圆继承。因为每个Cylinder也是一个圆圈,具有额外的属性。

+0

非常感谢你的真实生活的例子。现在对我来说更清楚了!我改变了Cylinder类,所以它继承了Circle的属性,现在它就像一个魅力! – Vojtech

+0

不客气。 –

+0

一个圆柱不是一个圆。圆是二维物体,圆柱体是具有圆形底座的三维物体。这不是继承的候选人,但组成 –

1

形状是继承的经典教科书示例。不幸的是,这也是一个很难正确的案例。

继承的基本规则是你可以建立一个继承的关系。

你可以说一个矩形是一个形状,你也可以说一个正方形是一个形状。在数学上,你也可以说每个正方形都是一个矩形。但是,如果您从矩形派生出方形,则必须与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计算volumen的区域。

+0

谢谢澄清!你的意思是'覆盖区域' - >它应该是一个变量吗?还是另一个班? – Vojtech

+0

@Vojtech它覆盖了具有相同名称形状的抽象属性(我原来有点马虎,现在纠正了) –

+0

带有getter和setter的公共属性以及只读的'Area'属性是一个更好的解决方案,但这与Vojtech提出的要求相差甚远。我们为他的任务提供了更简单的解决方案。 – Mentoliptus