การใช้รูปแบบมัณฑนากร

กำลังพยายามใช้รูปแบบมัณฑนากรใน C # จากโค้ดในหนังสือ "Head First Design Patterns" (เขียนด้วยภาษา Java)

ฉันเพิ่งเริ่มต้นด้วย C# และยังใหม่กับไวยากรณ์ ดังนั้นฉันจึงไม่แน่ใจว่าทำไมฉันไม่สามารถรับบรรทัดโค้ดที่มีความคิดเห็นด้านล่างให้ใช้งานได้

นี่คือคลาส abstract-base คลาสแรกและคลาสที่ได้รับมาในรูปแบบมัณฑนากร:

using System;

public abstract class Beverage
{
    private String m_description;

    // get a description of the beverage
    public virtual String Description { get { return m_description; } }

    // calculate cost of the beverage
    public abstract double Cost();
}

// HouseBlend coffee implements Beverage
public class HouseBlend : Beverage
{
    // Constructor
    public HouseBlend() { m_description = "House Blend"; }

    // calculate base cost of House Blend
    public override double Cost() { return 0.89; }
}

// DarkRoast coffee implements Beverage
public class DarkRoast : Beverage
{
    // Constructor
    public DarkRoast() { m_description = "Dark Roast"; }

    // calculate base cost of Dark Roast
    public override double Cost() { return 1.00; }
}

// Espresso coffee implements Beverage
public class Espresso : Beverage
{
    // Constructor
    public Espresso() { m_description = "Espresso"; }

    // calculate base cost of Espresso
    public override double Cost() { return 1.99; }
}

รหัสที่กระทำผิดอยู่ในวิธี Cost() ของคลาส Mocha:

using System;

// abstract base class CondimentDecorator is-a Beverage
public abstract class CondimentDecorator : Beverage {}

// Mocha implements the CondimentDecorater
public class Mocha : CondimentDecorator
{
    // Condiment decorator has-a Beverage (recursion!)
    private Beverage m_beverage;

    // Constructor binds the object passed to member var
    public Mocha(Beverage beverage)
    {
        this.m_beverage = beverage;
    }

    // getter implements abstract class Description
    public override String Description
    {
        get
        {
            return m_beverage.Description + ", Mocha";
        }
    }

    // get the Cost of the condiment plus the base-cost
    // of the original beverage
    public new double Cost()               // ERROR: 'Mocha.Cost()' hides inherited
    {                                      // member 'Beverage.Cost()'
        return 0.20 + m_beverage.Cost();
    }
}

person dtg    schedule 22.01.2012    source แหล่งที่มา
comment
โปรดทราบว่า แม้ว่าหนังสือจะใช้ Java แต่ เว็บไซต์ของหนังสือ ลิงก์ไปยัง โค้ดตัวอย่างใน C# และ C++   -  person Ahmad Mageed    schedule 22.01.2012


คำตอบ (3)


เปลี่ยน new เป็น override นอกจากนี้ m_description ควรเป็น protected

person jason    schedule 22.01.2012
comment
เดอร์ป. การประกาศ m_description ว่าได้รับการปกป้องแทนที่จะเป็นแบบส่วนตัวควรจะไม่ใช่เรื่องง่ายเลย... - person dtg; 22.01.2012
comment
ฉันขอแนะนำให้รักษาข้อมูลในพื้นที่ให้เป็นส่วนตัวและเปิดเผยให้ผู้สืบทอดทราบผ่านทรัพย์สินที่ได้รับการคุ้มครอง - person Erik Dietrich; 22.01.2012
comment
ไม่แน่ใจว่าจะทำอย่างไร... ฉันมีรายการคุณสมบัติสำหรับการตั้งค่าและรับ m_description ชื่อ Description แล้ว แต่ฉันไม่แน่ใจว่าจะนำไปใช้ในการเข้าถึงเมธอด Cost() ของอ็อบเจ็กต์เครื่องดื่มได้อย่างไร - person dtg; 22.01.2012
comment
@Dylan: สิ่งที่ @Erik Dietrich พูดมีดังต่อไปนี้: เก็บ m_description ไว้เป็นส่วนตัว คุณสามารถตั้งค่า m_description ได้โดยการเพิ่ม Constructor ไปที่ Beverage ซึ่งรับ string description และกำหนดให้กับ m_description ในเนื้อความของ Constructor จากนั้นเรียกคอนสตรัคเตอร์นี้จากแต่ละคลาสที่ได้รับโดยการผูกมัดคอนสตรัคเตอร์ ตัวอย่างเช่น สำหรับ Mocha ` public Mocha() : base(Mocha) { }` - person jason; 23.01.2012

คุณได้ประกาศวิธีการ Cost() ของ Mocha เป็นวิธีใหม่แทนที่จะแทนที่ ดูความแตกต่างที่นี่: http://blogs.msdn.com/b/csharpfaq/archive/2004/03/12/what-s-the-difference-between-code-override-code-and-รหัสใหม่-code.aspx

person CMPerez    schedule 22.01.2012
comment
ขอบคุณสำหรับคำอธิบายนั้น ตอนนี้ฉันเห็นความแตกต่าง - person dtg; 22.01.2012

โค้ดของคุณควรมีลักษณะเช่นนี้

public abstract class Beverage
{
    protected string m_description = "Unknown Beverage";

    public virtual string GetDescription()
    {
        return m_description;
    }

    public abstract double Cost();
}

public abstract class CondimentDecorator : Beverage
{
}

public class Espresso : Beverage
{
    public Espresso()
    {
        m_description = "Espresso";
    }

    public override double Cost()
    {
        return 1.99;
    }
}

public class HouseBlend : Beverage
{
    public HouseBlend()
    {
        m_description = "House Blend Coffe";
    }

    public override double Cost()
    {
        return 0.89;
    }
}

public class DarkRoast : Beverage
{
    public DarkRoast()
    {
        m_description = "Dark Roast";
    }

    public override double Cost()
    {
        return 0.99;
    }
}

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 0.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 0.15 + 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 0.10 + beverage.Cost();
    }
}
person Elephant    schedule 16.02.2013