Логические ошибки и синтаксические ошибки с наследованием - PullRequest
2 голосов
/ 04 января 2012

Что не так с этим набором кода?У меня есть ошибки, и я не могу выяснить, что с этим не так.Ниже приведена логика того, что я пытаюсь сделать.Может ли кто-нибудь помочь мне решить эту проблему?

CustNum говорит, что скрывает унаследованный член и сообщает об ошибке для строки Convert.ToInt32 и метод new Customer() не работает.

using System;
public class DebugEight01
{
    public static void main()
    {
        Customer aRegularCustomer = new Customer();
        FrequentCustomer aFrequentCustomer = new Customer(); // I have an error here. 
        aRegularCustomer.CustNum = 2514;
        aRegularCustomer.CustBalance = 765.00;
        aFrequentCustomer.CustNum = 5719;
        aFrequentCustomer.CustBalance = 2500.00;
        aFrequentCustomer.DiscountRate = 0.15;   //15 % 
        Console.WriteLine("\naRegularCustomer #{0} owes {1}",
           aRegularCustomer.CustNum,
           aRegularCustomer.CustBalance = Convert.ToInt32; // I have an error here
        Console.WriteLine("\naFrequentCustomer #{0} would owe {1} without the discount",
           aFrequentCustomer.CustNum,
           aFrequentCustomer.CustBalance.ToString("C2"));
        double newBal = (1 - aFrequentCustomer.DiscountRate) *
           aFrequentCustomer.CustBalance;
        Console.WriteLine("...with {0} discount, customer owes {1}",
           aFrequentCustomer.DiscountRate.ToString("P"), newBal.ToString("C"));
    }
}
public class Customer
{
    private int custNum;
    private double custBalance;
    public int CustNum
    {
        get
        {
            return custNum;
        }
        set
        {
            custNum = value;
        }
    }
    public double CustBalance
    {
        get
        {
            return custBalance;
        }
        set
        {
            CustBalance = value;
        }
    }
}
class FrequentCustomer : Customer
{
    private double discountRate;
    public double DiscountRate
    {
        get
        {
            return discountRate;
        }
        set
        {
            discountRate = value;
        }
    }
    public int CustNum // I have an error here, it's hiding inherited member?
    {
        get
        {
            return base.CustNum;
        }
        set
        {
            CustNum = value;
        }
    }
}

Ответы [ 6 ]

4 голосов
/ 04 января 2012

Когда вы работаете с классами и наследованием, существуют некоторые правила, которые применяются при создании экземпляров переменных.

Если ваше дерево наследования выглядит примерно так

class Object + class Customer +class FrequentCustomer

Если вы объявите переменную типа Object в правой части объявления, он может принять любой тип, который находится ниже в дереве наследования.Это означает, что если ваша переменная имеет тип FrequentCustomer, ей должен быть присвоен только экземпляр FrequentCustomer.Если он имеет тип Customer, тогда он может принимать Customer и FrequentCustomer и так далее.Все классы наследуют тип object, поэтому я добавил его в дерево наследования.Ниже приведены все допустимые объявления.

object c = new Customer();
object c = new FrequesntCustomer();
Customer c = new Customer();
Customer c = new FequentCustomer();
FrequentCustomer c = new FrequentCustomer();

Вот почему возникает ваша первая ошибка компиляции.

Вторая ошибка связана с неправильным использованием метода Convert.ToInt32().Правильный синтаксис:

Console.WriteLine("\naRegularCustomer #{0} owes {1}",
       aRegularCustomer.CustNum,
       Convert.ToInt32(aRegularCustomer.CustBalance)); // im having a error here

Ваша третья ошибка - не ошибка, а только предупреждение.Класс FrequentCustomer уже имеет унаследованные от Customer свойства, даже если вы не указали их явно.Это означает, что вам не нужно указывать свойство CustNum в классе FrequentCustomer, оно уже унаследовано.Однако, если по какой-то причине вам нужно добавить свойство (например, у него другая реализация, чем у его родительского класса), вам нужно добавить ключевое слово new в это свойство следующим образом:

public new int CustNum
{
    get
    {
        return base.CustNum;
    }
    set
    {
        CustNum = value;
    }
}

Если вы этого не сделаете, это будет сделано автоматически (скрытие унаследованного члена), но вы получите предупреждение об этом.

1 голос
/ 04 января 2012

Что касается сокрытия унаследованных членов,
Клиент является базовым классом, и у него уже есть свойство CustNum, поэтому нет необходимости указывать это в FrequentCustomer, если вы не хотите переопределить этот

   FrequentCustomer aFrequentCustomer = new Customer(); // im having a error here. 

   Customer aFrequentCustomer = new FrequentCustomer();

Первый операторне будет работать, это на самом деле идет наоборот.Второе утверждение будет работать.Если вы действительно хотите сделать это таким образом, вы можете рассмотреть возможность использования интерфейса, такого как ICustomer

1 голос
/ 04 января 2012

Прежде всего, это не ошибка (у меня здесь ошибка, это скрытый унаследованный член?).Это предупреждение.Нет необходимости переопределять свойство CustNum в подклассе.Таким образом, вы скрываете член базового класса.

Ошибка в - FrequentCustomer aFrequentCustomer = new Customer();, и это должно быть,

FrequentCustomer aFrequentCustomer = new FrequentCustomer ();

Ошибка в свойстве - CustBalance в классе клиента

 public double CustBalance
    {
        get
        {
            return custBalance;
        }
        set
        {
            // CustBalance = value; <-- It will assign value to property not a field
            //                          will cause StackOverflow
            custBalance=value;                          
        }
    }

И нет необходимости конвертировать, пока вы печатаете / пишете их в виде строки.

 Console.WriteLine("\naRegularCustomer #{0} owes {1}",
           aRegularCustomer.CustNum,
           aRegularCustomer.CustBalance);

Для лучшей практики всегда используйте _ (подчеркивание) в качестве первого символа поля или используйте Auto-Implemented properties.

public class Customer
{
    private int _custNum;
    private double _custBalance;
    public int CustNum
    {
        get
        {
            return _custNum;
        }
        set
        {
            _custNum = value;
        }
    }
   .....
}

Автоматически реализованные свойства:

public class Customer
{
  public int CustNum {get;set;}
  public double CustBalance {get;set;}
}
1 голос
/ 04 января 2012

CustNum в родительском классе необходимо пометить virtual.

Ваша вторая ошибка - отсутствие закрывающей скобки и тот факт, что вы на самом деле не предоставляете Convert.ToInt32 спараметр (то есть что-то для преобразования).

0 голосов
/ 04 января 2012

Ваша ошибка из-за linbe:

     FrequentCustomer aFrequentCustomer = new Customer(); // im having a error here.  

Это вызывает ошибку, потому что вы пытаетесь сохранить ссылку на объект в переменной, которая объявлена ​​как тип, производный от конкретного типа объекта (справа). Это все равно, что создать объект типа «Млекопитающее» и попытаться назвать его свиньей. Можно создать свинью и назвать ее млекопитающим, но нельзя создать млекопитающее и назвать ее свиньей.

0 голосов
/ 04 января 2012

Что означает сообщение «унаследованный член», так это то, что свойство CustNum класса Customer больше не доступно из класса FrequentCutomer. Он не признает, что они должны быть одной и той же собственностью. Вы должны сказать это, пометив один в Customer как virtual как в public virtual int CustNum. Вы отмечаете один в FrequentCustomer как override как в public override int CustNum. В этом случае свойство может быть исключено из класса FrequentCustomer, поскольку оно просто избыточно.

Я думаю, вы имели в виду Convert.ToInt32(aRegularCustomer.CustBalance). Хотя лично я никогда не использую Convert. Я бы обычно использовал (int)aRegularCustomer.CustBalance, но это всего лишь мои предпочтения.

Вместо new Customer() вы хотите new FrequentCustomer(). Вы не можете поместить Customer в переменную FrequentCustomer, потому что она не одна.

Еще одна вещь, вы имели в виду custBalance = value; в вашей CustBalance собственности. В противном случае установка свойства создает бесконечный цикл.

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