2014年6月15日日曜日

開発環境

Head First C#―頭とからだで覚えるC#の基本 (Andrew Stellman (著)、Jennifer Green (著)、佐藤 嘉一 (監修)、木下 哲也 (翻訳)、オライリージャパン)の6章(インタフェースと抽象クラス: クラスに約束を守らせる)、長いエクササイズ(p.260)を解いてみる。

長いエクササイズ(p.260)

コード

Form1.cs

using System;
using System.Windows.Forms;

namespace WindowsFormsApplication1
{
    public partial class Form1 : Form
    {
        Location currentLocation;

        public Form1()
        {
            InitializeComponent();

            RoomWithDoor livingRoom = new RoomWithDoor(
                "居間", "アンティークカーペット", "真ちゅうのノブを持つオーク材のドア");
            Room diningRoom = new Room("ダイニングルーム", "クリスタルのシャンデリア");
            RoomWithDoor kitchen = new RoomWithDoor("台所", ":ステンレス製の電化製品", "網戸");
            Outside garden = new Outside("庭園", false);
            OutsideWithDoor frontYard = new OutsideWithDoor("前庭", false, "真ちゅうのノブを持つオーク材のドア");
            OutsideWithDoor backYard = new OutsideWithDoor("裏庭", true, "網戸");

            livingRoom.exits = new Location[] { frontYard, diningRoom };
            diningRoom.exits = new Location[] { livingRoom, kitchen };
            kitchen.exits = new Location[] { diningRoom, backYard };
            frontYard.exits = new Location[] {livingRoom, garden };
            backYard.exits = new Location[] { garden, kitchen };

            livingRoom.DoorLocation = frontYard;
            kitchen.DoorLocation = backYard;
            frontYard.DoorLocation = livingRoom;
            backYard.DoorLocation = kitchen;

            currentLocation = livingRoom;
            MoveToANewLocation(currentLocation);
        }

        private void Form1_Load(object sender, EventArgs e)
        {
           
        }

        void MoveToANewLocation(Location loc)
        {
            currentLocation = loc;

            exits.Items.Clear();
            for (int i = 0; i < currentLocation.exits.Length; ++i)
            {
                exits.Items.Add(currentLocation.exits[i].Name);
            }   
            exits.SelectedItem = 0;
            description.Text = currentLocation.Description;
            if (currentLocation is IHasExteriorDoor)
            {
                goThroughTheDoor.Visible = true;
            }else
            {
                goThroughTheDoor.Visible = false;
            }

        }

        private void goHere_Click(object sender, EventArgs e)
        {
            MoveToANewLocation(currentLocation.exits[exits.SelectedIndex]);
        }

        private void goThroughTheDoor_Click(object sender, EventArgs e)
        {
            IHasExteriorDoor door = currentLocation as IHasExteriorDoor;
            MoveToANewLocation(door.DoorLocation);
        }
    }

    public interface IHasExteriorDoor
    {
        string DoorDescription { get; }
        Location DoorLocation { get; set; }
    }
    public abstract class Location
    {
        private string name;
        public Location[] exits;

        public Location(string name)
        {
            this.name = name;
        }
        public string Name
        {
            get { return name; }
        }
        public virtual string Description
        {
            get
            {
                string description = "あなたは今" + name +
                    "に立っています。次の場所への出口があります。";
                for (int i = 0; i < exits.Length; ++i)
                {
                    description += " " + exits[i].Name;
                    if (i != exits.Length - 1)
                    {
                        description += ", ";
                    }
                }
                description += "。";
                return description;
            }
        }
    }
    public class Room : Location
    {
        private string decoration;
        public Room(string name, string decoration)
            : base(name)
        {
            this.decoration = decoration;
        }

        public string Decoration
        {
            get { return this.decoration; }
        }
        public override string Description
        {
            get
            {
                return base.Description + decoration + "が見えます。";
            }
        }
    }
    public class Outside : Location
    {
        private bool hot;
        public Outside(string name, bool hot)
            : base(name)
        {
            this.hot = hot;
        }

        public bool Hot
        {
            get { return this.hot; }
        }

        public override string Description
        {
            get
            {
                if (hot)
                {
                    return base.Description + "ここはとても暑い。";
                }
                return base.Description;
            }
        }
    }
    public class OutsideWithDoor : Outside, IHasExteriorDoor
    {
        private Location doorLocation;
        private string doorDescription;

        public OutsideWithDoor(string name, bool hot, string doorDescription)
            : base(name, hot)
        {
            this.doorDescription = doorDescription;
        }

        public string DoorDescription
        {
            get { return doorDescription; }
        }
        public Location DoorLocation
        {
            get { return this.doorLocation; }
            set { this.doorLocation = value; }
        }
    }
    public class RoomWithDoor : Room, IHasExteriorDoor
    {
        private Location doorLocation;
        private string doorDescription;

        public RoomWithDoor(string name, string decoration, string doorDescription)
            : base(name, decoration)
        {
            this.doorDescription = doorDescription;
        }

        public string DoorDescription
        {
            get { return doorDescription; }
        }
        public Location DoorLocation
        {
            get { return this.doorLocation; }
            set { this.doorLocation = value; }
        }
    }
}

0 コメント:

コメントを投稿