开发者

What is the difference between abstraction and encapsulation? [duplicate]

This question already has answers here: Abstraction VS Information Hiding VS Encapsulation (22 answers) 开发者_JS百科 Difference between abstraction and encapsulation? (40 answers) Closed last month.

What exactly is the difference between encapsulation and abstraction in Java? Any brief examples would also be appreciated.


Abstraction and encapsulation are two great flavors that taste great together.

Encapsulation is minimizing what you expose to the user of your code. That "user" may be the rest of your code, or whoever uses the code you publish.

There some definite benefits to encapsulation:

  • The user of your code doesn't depend on parts of your program that are likely to change. When you change your program, they don't have to change their code
  • You are more in control of exactly how your code and state changes over the lifetime of your program. You must handle fewer scenarios, and will have fewer unexpected problems to fix

I don't know Java, but here is a small example of encapsulation in 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;
}

Instead of exposing numberOfSpots, it is encapsulated within the class, and exposed via the ToString method.

Abstraction is using extension points to let the choice be deferred to a different part of which exact code is run. That choice could be made elsewhere in your program, in another program, or dynamically at runtime.

There are also strong benefits to abstraction:

  • When you change your code that implements an abstraction, the user of the abstraction doesn't have to change their code. As long as the abstraction doesn't change, the users won't have to change their code.
  • When you write code that uses an abstraction, you can write code once that will be reusable against any new code that implements that abstraction. You can write less code to do more.

A highly used abstraction in C# is IEnumerable. Lists, Arrays, Dictionaries, and any other type of collection class all implement IEnumerable. The foreach loop structure and the entirety of the LINQ library are based on that abstraction:

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);
}

You can easily write your own abstractions, too:

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);

You can use both together, as I did with IAnimal, and IsHealthy. IAnimal is an abtraction, and having only a get accessor, and no set accessor on IsHealthy is encapsulation.


These two concepts are quite different.

Abstraction is the practice of making a base class 'abstract' and then extending its functionality. An abstract class is something that doesn't exist in a concrete matter; its only purpose is to be extended. Think of if you were writing classes to represent different species. All of your different species might extend an abstract Animal class because they would all share common attributes as animals. However, you would never instantiate an Animal object, because every animal you see in the world is a squirrel, or a dog, or a fish ... or some kind of concrete implementation of that base, abstract animal class.

Encapsulation is the practice of making your class variables private, and then allowing access to them from get and set methods. The purpose of this is separate the way your data is accessed and the way it is implemented. For example, if you have some variable that has a requirement, that every time it is changed, it also increments a second variable by 1, then you would encapsulate that functionality; that way your code is more reliable because you don't have to remember to adhere that rule every time you'd access the original variable.

If you want specific code examples, I'd recommend just doing a google search, because there's a lot of examples like that available. Here's two:

http://www.tutorialspoint.com/java/java_abstraction.htm http://www.tutorialspoint.com/java/java_encapsulation.htm


Encapsulation is to protect your member variables or methods from the outside world.

Abstraction is the way to have specific implementation. that is which implementation to use is unknown to the user.


Encapsulation is part of abstraction. The notion of abstraction is one of creating an object to represent another object. Typically, the original object is more complex than the abstraction. An abstraction is thus a representation, usually as an aid to memory, for terminology/communication etc. Think of it like this: abstract art is a representation of something else. A steering wheel, gearshift and 2/3 pedals is an abstraction of how a car works.

Basically, the abstraction allows you to represent something complex, with a lot of details, as something a lot simpler. In my opinion, this is related to 'chunking' in cognitive science. We're not able to keep complex things in our head, so we simplify by abstracting, then using the abstraction. Design Patterns are another great example. Instead of talking about details, we can talk about Command, State or Strategy pattern etc.

Encapsulation is part of forming/creating an abstraction. The smaller an object's interface, the easier it is to abstract. You don't need to know how an engine and gearbox work to drive a car, you just need to understand their abstractions (gear shift and accelerator). The details of the engine and gearbox are encapsulated (into the interface) in order to create the abstraction.

Encapsulation is needed for abstraction because an abstaction can't deal with all the real details and complexity (otherwise its not an abstraction). So the gearshift is an incomplete representation (or model) of a gearbox, but its complete enough for everyday use. Encapsulation can be thought of as 'hiding details', which is necessary for creating a simpler representation.

Its also important to discuss the concept of an 'interface'. For the most part, the terms 'interface' and 'abstraction' are more less interchangeable in this instance. An interface is the part of a system with which the user deals or interacts. The interface to a car is the steering wheel, gear shift and pedals etc. The abstraction produces an interface. You don't deal with the engine/gearbox directly, you deal with their respective interfaces.

Another reason for encapsulation is because we're dealing with an incomplete model/abstraction, we don't understand the full complexity of the original, and can't be trusted to deal with all the variables (because we don't understand the full model). This is important for decoupling, because without abstraction, interacting components would know too much about each other. Think about it, because every car has a steering wheel, pedals and gearshift, you can drive any car, regardless of engine type etc. Also, the gearbox is abstracted from the engine. Otherwise each custom engine would need a custom gearbox.

Similarly, a Class is an abstraction. The class represents some complex model, through its interface - the public members of the class. This interface is created through encapsulation. The class presents a simplified interface of its more complex implementation to its collaborators. You can also think of it as a 'need to know' situation. The collaborators of the class don't need to know exactly how it works. Just as you don't need to know how an engine works to drive a car.

Encapsulation, interfaces and abstraction play a critical role in cohesion and coupling, and therefore maintenance of your code. If you don't create good abstractions, and violate the 'need to know' principle, then your code becomes entangled, fragile and a nightmare to change, because there is no 'buffering'. The OO concept of 'tell don't ask' is also related to this.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜