抽象和封装之间有什么区别?


问题内容

Java中的封装和抽象之间到底有什么区别?任何简短的例子也将不胜感激。


问题答案:

抽象和封装是两个很好的味道,它们在一起味道很好。

封装 可以最大程度地减少向代码用户展示的内容。该“用户”可以是您代码的其余部分,也可以是使用您发布的代码的任何人。

封装有一定的好处:

  • 代码的用户不依赖于程序中可能更改的部分。当您更改程序时,他们不必更改代码
  • 您可以更好地控制代码和状态在程序生命周期中的变化方式。您必须处理更少的场景,并且可以解决更少的意外问题

我不懂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