C # наследование -> иерархия классов - PullRequest
2 голосов
/ 17 октября 2011

Эй, ребята,

У меня проблема с пониманием процесса наследования в 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);
    }
}
}

Class Circle:

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

    }
}
}

Я хотел бы знать, где я неправильно понял.Мне немного сложно понять идею наследования.Как я могу улучшить это упражнение, чтобы выполнить задание?

Спасибо за ваши ответы!V.

EDIT:

Я отредактировал код, так что теперь должно быть правильное наследование.И последний вопрос.Где я должен поставить код 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());

Последняя проблема у меня естьявляется то, что когда я запускаю приложение, я получаю одно и то же число для Circle Area и Cylinder Area.Похоже, что метод Display в классе Cylinder использует возвращаемое значение из класса Circle.Как это возможно?

Ответы [ 4 ]

2 голосов
/ 17 октября 2011

Я думаю, вам будет легче понять наследование от примера из реальной жизни.

Допустим, у вас есть человек, у человека есть идентификатор и имя. Теперь, скажем, есть полицейский, полицейский наследует от человека, почему? потому что каждый полицейский - это, прежде всего, личность (у него есть имя и удостоверение личности), и только тогда вы можете сказать, что он полицейский, если у него есть другие ДОПОЛНИТЕЛЬНЫЕ данные, например, идентификатор полицейского и оружие.

То же самое в ООП, унаследованный класс (дочерний класс) имеет те же свойства, что и унаследованный класс (класс отца), но имеет дополнительные элементы, как и ваша домашняя работа, у класса Circle есть более уникальный материал, добавленный в класс Shape. Вместо того, чтобы снова писать все элементы формы в круге, мы наследуем класс Shape и добавляем дополнительную информацию в класс Circle.

Это облегчает нам и другим программистам понимание того, что представляют собой программные объекты и как они связаны между собой и используются для напоминания объектов в «реальном мире» (если у вас есть, например, информационная система для управления рабочая сила, у вас может быть отцовский класс «Рабочий» и дочерний класс «Супервайзер», потому что каждый супервайзер - это, в первую очередь, работник).

Надеюсь, это поможет.

А для вашей конкретной домашней работы:

Что бы я сделал в вашей конкретной домашней задаче, так это изменил наследование так, чтобы Круг наследовал от фигуры, а Цилиндр наследовал от круга . Потому что каждый цилиндр - это тоже круг с дополнительными свойствами.

2 голосов
/ 17 октября 2011

Лучше перенести радиус и высоту на уровень класса, например:

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());
1 голос
/ 17 октября 2011

Фигуры являются классическим учебником примера наследования. К сожалению, это также очень сложно понять.

Базовое правило наследования заключается в том, что вы можете смоделировать отношения is-is с наследованием.

Вы можете сказать, что прямоугольник - это форма, вы также можете сказать, что квадрат - это форма. Математически вы также можете сказать, что каждый квадрат - это прямоугольник. Однако, если вы выводите квадрат из прямоугольника, вам нужно будет поговорить с Лисков . Квадрат по моделю не является прямоугольником .

Возьмем этот пример (дальнейшие объяснения проблем, которые могут возникнуть, приведены в ссылках на статьи)

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 кв. Дюйма? Сколько цилиндров? Я не рассчитал первый, но ответ на второй - нет. Это трехмерная форма и не может быть нарисован в 2-мерном пространстве. Как бы вы ни построили цилиндр на основе круга и знания высоты цилиндров. Такое соотношение моделируется композицией.

В этом конкретном случае вы могли бы сделать

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 для расчета объема.

0 голосов
/ 17 октября 2011

Вопрос о домашнем задании просит вас вернуть текстовую строку с дисплея, и в настоящее время вы возвращаете void.Вам нужно изменить сигнатуру метода, чтобы она возвращала строку, а затем настроить свой вызывающий код для отображения этой строки, используя (Console.WriteLine).

Каждый класс, который переопределяет форму, должен определять свои собственные частные свойства, например, круг должен иметьпостоянная пи (потому что она никогда не меняется) и свойство радиуса.Это позволит вам выполнять другие операции на круге без необходимости переопределять эти переменные.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...