Код не работает, когда я использую абстрактное ключевое слово в среднем классе - PullRequest
0 голосов
/ 01 октября 2010

У меня есть код ниже, который работает нормально:

  public abstract class Beverage
{
    public string description = "Unknown beverage";
    public virtual  string getDescription()
    {
        return description;
    }
    public abstract double cost();
}

public abstract class condimentDecorator : Beverage
{
   // public abstract string getDescription();
}

public class DarkRoast : Beverage
{
    public DarkRoast()
    {
        description = "DarkRoast";
    }
    public override  double cost()
    {
        return 2.10;
    }
}
public class Espresso : Beverage
{
    public Espresso()
    {
        description = "Espresso";
    }
    public override double cost()
    {
        return 1.99;
    }
}

public class HouseBlend : Beverage
{
    public HouseBlend()
    {
        description = "House Blend Coffee";
    }
    public override double cost()
    {
        return .89;
    }
}


public class Mocha : condimentDecorator
{
    Beverage beverage;
    public Mocha(Beverage beverage)
    {
        this.beverage = beverage;
    }

    public override string getDescription()
    {
        return beverage.getDescription() + ", Mocha";
    }
    public override double cost()
    {
        return .20 + beverage.cost();
    }
}

public class Soy : condimentDecorator
{
    Beverage beverage;
    public Soy(Beverage beverage)
    {
        this.beverage = beverage;
    }

    public override string getDescription()
    {
        return beverage.getDescription() + ", Soy";
    }
    public override double cost()
    {
        return .10 + beverage.cost();
    }
}

public class Whip : condimentDecorator
{
    Beverage beverage;
    public Whip(Beverage beverage)
    {
        this.beverage = beverage;
    }

    public override string getDescription()
    {
        return beverage.getDescription() + ", Whip";
    }
    public override double cost()
    {
        return .10 + beverage.cost();
    }
}

Я использую это следующим образом:

 protected void Page_Load(object sender, EventArgs e)
    {
        Beverage beverage2 = new DarkRoast();
        beverage2 = new Mocha(beverage2);
        beverage2 = new Mocha(beverage2);
        beverage2 = new Whip(beverage2);
        Response.Write ("<br> " + beverage2.getDescription() + " : $" + beverage2.cost().ToString());
    }

Проблема: я хочу, чтобы весь дочерний класс «condimentDecorator» принудительно переопределил функцию getDescription (), для этого я написал код ниже в классе «condimentDecorator»:

 public abstract string getDescription();

но это вносит изменения в мое текущее функционирование и не дает желаемого результата, оно просто показывает "Неизвестный напиток" как значение getDescription (), которое является значением самого родительского класса.

Нормальный результат:

DarkRoast, Mocha, Mocha, Whip : $2.6 

Результат после использования «public abstract string getDescription ()»:

Unknown beverage : $2.6 

Пожалуйста, предложите мне, что я должен написать / изменить, чтобы я мог заставить дочерние классы "condimentDecorator" переопределить "getDescription ();" а также получает resutl, так как работает без него.

Ответы [ 3 ]

3 голосов
/ 01 октября 2010

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

Как насчет этого:

Я предлагаю вам создать интерфейс, IBeverage, который вы реализуете для всего, что можно пить. Затем вы создаете базовый класс для «фундаментальных» напитков - DarkRoast, Espresso, HouseBlend - так же, как вы это делали сейчас.

Для Condiments вы реализуете новый абстрактный базовый класс, реализующий IBeverage, но не обеспечивающий реализацию GetDescription по умолчанию. Этот класс также может использовать IBeverage в своем конструкторе, чтобы заставить другие приправы делать то же самое.

Мне кажется, что-то вроде этого должно работать (не проверено, не скомпилировано - но вы поняли)

public interface IBeverage
{
  string GetDescription ();
}

public abstract class BeverageBase : IBeverage
{
  public virtual string GetDescription () { return "Unknown Beverage"; }
}

public class DarkRoast : BeverageBase { ... }
public class HouseBlend : BeverageBase { ...}

public abstract class CondimentBase : IBeverage
{
  public CondimentBase(IBeverage beverage)
  {
    Beverage = beverage;
  }
  protected IBeverage Beverage { get; set; }
  public abstract string GetDescription ();
}

public class Mocha : CondimentBase 
{
  public Mocha(IBeverage beverage)
    : base (beverage)
  { }
  public string GetDescription()
  {
    return Beverage.GetDescription() + ", Mocha";
  }
}
1 голос
/ 01 октября 2010

Быстрый гугл получился так: http://codebetter.com/blogs/darrell.norton/archive/2005/05/18/63332.aspx

Я не пробовал сам код.

0 голосов
/ 01 октября 2010

вы можете создать новый метод, например, так:

public abstract class condimentDecorator : Beverage
{
     public override string getDescription()
     {
          return getDescriptionInternal();
     }
     protected abstract string getDescriptionInternal();
}

Таким образом, все классы должны будут косвенно реализовывать getDescription.

...