Инициализация базового класса: объявление переменной дважды? - PullRequest
0 голосов
/ 12 сентября 2018

Я сейчас читаю через учебник по C #.Теперь я столкнулся с этим:

using System;

namespace RectangleApplication {
   class Rectangle {

      //member variables
      protected double length;
      protected double width;

      public Rectangle(double l, double w) {
         length = l;
         width = w;
      }
      public double GetArea() {
         return length * width;
      }
      public void Display() {
         Console.WriteLine("Length: {0}", length);
         Console.WriteLine("Width: {0}", width);
         Console.WriteLine("Area: {0}", GetArea());
      }
   }//end class Rectangle  
   class Tabletop : Rectangle {
      private double cost;
      public Tabletop(double l, double w) : base(l, w) { }

      public double GetCost() {
         double cost;
         cost = GetArea() * 70;
         return cost;
      }
      public void Display() {
         base.Display();
         Console.WriteLine("Cost: {0}", GetCost());
      }
   }
   class ExecuteRectangle {
      static void Main(string[] args) {
         Tabletop t = new Tabletop(4.5, 7.5);
         t.Display();
         Console.ReadLine();
      }
   }
}

В class Tabletop указано cost дважды.Когда-то как private double cost;, а через 4 строки - double cost;

Почему это так?

При удалении double cost; Код все еще работает.Когда double cost находится в коде, я могу навести курсор на private double cost; и прочитать сообщение: «Поле Tabletop.cost никогда не используется». Я в значительной степени могу убрать любую из стоимости, и код работает нормально.

  1. Они забыли удалить одно из объявлений или есть какая-то причина?
  2. Кроме того, почему я не получаю сообщение об ошибке типа "стоимость уже определена"?

Вот ссылка на учебник

Ответы [ 5 ]

0 голосов
/ 12 сентября 2018

Я думаю, что они забывают удалить его.

Поскольку вы не получаете сообщение об ошибке "стоимость уже определена", это потому, что double cost в GetCost() локально (доступно только внутри GetCost(), и будет уничтожен из памяти после завершения GetCost() метода), в то время как private double cost доступен всему классу Tabletop, к которому осуществляется доступ, и будет храниться в памяти до тех пор, пока экземпляр Tabletop будет работать.

0 голосов
/ 12 сентября 2018

private double cost; не используется и может быть удален.

Вы не получите ошибку, потому что, как сказал Джон в комментариях, она находится в разных областях;один определяется как поле класса, а другой - локальная переменная.Когда используется cost, доступ к локальной переменнойДля доступа к полю можно использовать this.cost.

class A
{
  private int a = 1;

  void A()
  {
    int a = 2;

    Console.WriteLine(a); // 2
    Console.WriteLine(this.a); // 1
  }
}

Обратите внимание, что у вас не может быть нескольких локальных переменных с одинаковыми именами, даже в разных областях:

void A()
{
  int a = 1;

  if(someCondition)
  {
    int b = 2; // Compiler error: A local variable named 'a' cannot be declared in this scope because it would give a different meaning to 'a', which is already used in a 'parent or current' scope to denote something else
  }
}
0 голосов
/ 12 сентября 2018

При определении переменной в области члена (в вашем случае в методе), имя которой совпадает с именем существующего члена, вы просто скрываете второе и ссылаетесь на первое.

Так в вашем примере:

class Tabletop : Rectangle 
{
    private double cost;
    public Tabletop(double l, double w) : base(l, w) { }

    public double GetCost() 
    {
        double cost;  // this hides the field
        cost = GetArea() * 70;
        return cost;  // this referts to the variable defined two lines above
    }
    public void Display() 
    {
        Console.WriteLine("Cost: {0}", cost); // while this refers to the field
    }
}

cost из в GetCost будет ссылаться на переменную local , а использование cost в Display, например, будет ссылаться нав поле .

Это абсолютно нормально.Однако это может привести к путанице и, следовательно, к неожиданному поведению.Вот почему некоторые разработчики склонны использовать this -квалификатор:

public double GetCost() 
{
    double cost;
    this.cost = GetArea() * 70;
    return this.cost;
}

с квалификатором, который вы ссылаетесь на текущий экземпляр, что делает this. cost` доступом к вашему полю .вместо переменной.

0 голосов
/ 12 сентября 2018

В классе Tabletop стоимость указана дважды.Когда-то частная двойная стоимость;и 4 строки позже как удвоенная стоимость;

Well private double cost; - это поле члена для класса tableTop, тогда как другое объявление является локальным для тела метода.Почему возникает путаница?

0 голосов
/ 12 сентября 2018

Фактически, в вашем классе Tabletop области действия cost перекрываются, поскольку в методе GetCost также есть локальная переменная с именем cost.

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

...