《Head First C#》 封装概念

实现类封装的几个想法
1.考虑字段可能会以何种方式被误用

如果设置不当,可能会导致字段被别人修改了,你却不知道,或者漏掉了本来应该执行的步骤却被忽略。

2.是不是类中的所有一切都是公共的
如果类中只有公共字段和方法,你可能需要多花一些时间来考虑封装的问题。

3.哪些字段需要在设置时做一些处理或计算
着些是最有可能需要封装的字段,如果有人以后写了一个方法来改变其中某个字段的值,可能会带来问题,导致你的程序
无法正常公共。

4.只是在需要的才将字段和方法声明为公共
还有要申明的是,封装可以使得你的类更好的维护,哪怕在你使用这段程序过后一段时间,你再想修改或者添加某个功能,也不会无从下手。


-------------将某些数据设置为私有并编写代码来使用这个数据,这就成为封装 (encapsulation)

    class DinnerParty
    {
        //人均消费
        public const int CostOfFoodPerPerson = 25;
        
        public decimal CostOfBeveragesPerPerson; //计算酒水
        public decimal CosOfDecorations = 0;//计算装饰

        /*
            提出一个封装的问题,再原有案例中,下拉菜单是修改numberOfPeople的一种途径,然后
         * 修改后,造成计算装修的未计算的错误,这个主要是因为修改numberofpeople的途径不止一种,
         * 所以我们必须限制修改numberofpeople的手段,这就是我理解的封装,我们先将public 修改为private
         */
        private int numberOfPeople;//人数 然后就是私有变量,开头要小写

        
        

        //同时,我们提供修改NumberOfPeolpe都必须经过这个方法
        public void SetPartyOptions(int people, bool fancy)
        {
            numberOfPeople = people;
            CalculateCostOfDecaorations(fancy);//这样。修改人数一定会经过这个方法,就不会造成遗漏没计算装饰的情况
        }

        public int getNumberOfPeople()
        { 
            return numberOfPeople;
        }
        // 将某些数据设置为私有并编写代码来使用这个数据,这就成为封装



        /// <summary>
        /// 如果选择了健康的选项
        /// 那么每个人的消费会增加5元
        /// </summary>
        /// <param name="isHealth"></param>
        public void SetHealthyOption(bool isHealth)
        {
            if (isHealth)
            {
                CostOfBeveragesPerPerson = 5.00M;
            }
            else
            {
                CostOfBeveragesPerPerson = 20.00M;
            }
        }

        public decimal CalculateCostOfDecaorations(bool isFanta)
        {
            if (isFanta)
            {
                CosOfDecorations = numberOfPeople * 15 + 50;
            }
            else
            {
                CosOfDecorations = numberOfPeople * 7.5m + 30;
            }
            return 0m; 
        }

        public decimal CalculateCost(bool isHealth)
        {

            decimal totalCost = CosOfDecorations +
                                ((CostOfBeveragesPerPerson + CostOfFoodPerPerson) * numberOfPeople);

            //有一个打折的过程,根据是否选了健康选项,会有个5%的折扣
            if (isHealth)
            {
                return totalCost * .95m;
            }
            else
            {
                return totalCost;
            }
        }
    }

    /// <summary>
    /// 对原DinnerParty的封装
    /// </summary>
    class DinnerPartyPackage
    { 
        /*
            修改这个方法
         * 嵌入封装的概念
         */
        public const int NumberOfPerPeople = 25;
        public int NumberOfPeople { get; set; }
        public bool FancyDecorations { get; set; }
        public bool  HealthyOption { get; set; }

        public DinnerPartyPackage(int numberOfPeople, bool fancyDecorations, bool healthyOption)
        {
            NumberOfPeople = numberOfPeople;
            FancyDecorations = fancyDecorations;
            HealthyOption = healthyOption;
        }

        //下面是帮助计算花费的方法的签名,填入计算
        /// <summary>
        /// 计算装潢的方法
        /// </summary>
        /// <returns></returns>
        private decimal CalculteCostOfDecorations()
        {
            if(FancyDecorations)
            {
                return 0m;
            }else
            {
                return 0m;
            }
           
        }
        /// <summary>
        /// 计算酒水的方法
        /// </summary>
        /// <returns></returns>
        private decimal CalculateCostOfBeveragesPerPerson()
        {
             if(HealthyOption)
            {
                return 0m;
            }else
            {
                return 0m;
            }
        }

        //增加一个只读的Cost属性来计算花费
        public decimal Cost {
            get {
                decimal total = CalculteCostOfDecorations();//别忘记加装修的钱
                total+=( CalculateCostOfBeveragesPerPerson()+NumberOfPerPeople)*NumberOfPeople;
                if(HealthyOption)
                {
                    return total*.95m;
                }
                    return total;
                
            } 
        }
    }

    /// <summary>
    /// 封装的小例子,封装类
    /// </summary>
    class Farmer
    {
        private int numberOfCows;//这个私有字段重命名为numberOfCows ,会成为NumberOfCows的 后备字段
        public int BegsOfFeed { get; set; }
        //public const int FeedMulitipliter = 30; //奶牛的单个饲料数还是可以修改的,所以可以设置成public
        private int feedMulitipliter;
        public int FeedMulitipliter { get {
            return feedMulitipliter;
        }  }
         
        //使用构造函数还初始化这个对象,连私有变量也可以初始
        public Farmer(int numberOfCows, int feedMulitipliter)
        {
            NumberOfCows = numberOfCows;
            this.feedMulitipliter = feedMulitipliter;
        }

        //使用属性
        public int NumberOfCows
        {
            get {

                return numberOfCows;
            }

            set {
                numberOfCows = value;

                BegsOfFeed = numberOfCows * FeedMulitipliter;//更改后,这是隐藏的操作,自动计算出,应该准备多少饲料
            }
        }
    }


猜你喜欢

转载自blog.csdn.net/CandyCCCation/article/details/79058312