抽象和封装是两个很好的味道,它们在一起味道很好。
封装 可以最大程度地减少向代码用户展示的内容。该“用户”可以是您代码的其余部分,也可以是使用您发布的代码的任何人。
封装有一定的好处:
- 代码的用户不依赖于程序中可能更改的部分。当您更改程序时,他们不必更改代码
- 您可以更好地控制代码和状态在程序生命周期中的变化方式。您必须处理更少的场景,并且可以解决更少的意外问题
我不懂Java,但这是C#封装的一个小例子:
public class Giraffe{ public Giraffe(int heightInFeet) { this.heightInFeet = heightInFeet; this.numberOfSpots = heightInFeet * 72; } public override string ToString() { return "Height: " + heightInFeet + " feet" + " Number of Spots: " + numberOfSpots; } private int heightInFeet; private int numberOfSpots;}numberOfSpots它没有公开,而是封装在类中,并通过
ToString方法公开。
抽象 使用扩展点使选择推迟到运行精确代码的其他部分。可以在您程序的其他位置,在另一个程序中或在运行时动态选择该选项。
抽象也有很多好处:
- 当您更改实现抽象的代码时,抽象的用户不必更改其代码。只要抽象不变,用户就不必更改其代码。
- 当编写使用抽象的代码时,您可以编写一次可对实现该抽象的任何新代码重复使用的代码。您可以编写更少的代码来完成更多工作。
C#中高度使用的抽象是
IEnumerable。列表,数组,字典和任何其他类型的集合类都实现
IEnumerable。的
foreach环结构和LINQ库的整体是基于抽象:
public IEnumerable<int> GetSomeCollection(){ // This could return any type of int collection. Here it returns an array return new int[] { 5, 12, 7, 14, 2, 3, 7, 99 };}IEnumerable<int> someCollectionOfInts = GetSomeCollection();IEnumerable<string> itemsLessThanFive = from i in someCollectionOfInts where i < 5 select i.ToString();foreach(string item in itemsLessThanFive){ Console.WriteLine(item);}您也可以轻松编写自己的抽象:
public interface IAnimal{ bool IsHealthy { get; } void Eat(IAnimal otherAnimal);}public class Lion : IAnimal{ public Lion() { this.isHealthy = true; } public bool IsHealthy { get { return isHealthy; } } void Eat(IAnimal otherAnimal) { if(otherAnimal.IsHealthy && !(otherAnimal is SlimeMold)) { isHealthy = true; } else { isHealthy = false; } } private bool isHealthy;}IAnimal someAnimal = PullAnAnimalOutOfAWoodenCrate();Console.WriteLine("The animal is healthy?: " + someAnimal.IsHealthy);就像我
IAnimal和和一样,您可以将两者一起使用
IsHealthy。
IAnimal是一个抽象,只有一个
get访问器,封装
set上没有访问器
IsHealthy。



