实现类封装的几个想法
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;//更改后,这是隐藏的操作,自动计算出,应该准备多少饲料
}
}
}