Is there any specific difference between abstraction and encapsulation? Also, is the concept of abstraction only meaningful in the context of OOP, or is 开发者_如何学Cit a generic term?
Abstraction is the more... abstract term here.
Encapsulation can be seen as one example of abstraction, where implementation details are omitted. But abstraction as a concept is certainly not limited to OOP; or even, for that matter, programming. Abstraction is really about forming higher-order concepts which connect seemingly unrelated concrete notions. It's the logical principle of leaving out details which are irrelevant to an idea, and capturing only what is essential to it.
I think the best example of abstraction that everyone is familiar with is numbers. What does the idea "3" mean? It could mean 3 cows, or 3 space ships, or 3 dreams. These are all unrelated things, yet there is something they have in common; the essential thing they have in common is that there are 3 of each of them. So "3" is an abstract concept which forgets the particulars of the things it is quantifying.
Similarly in programming, parametric polymorphism allows us to abstract away, for example, the type of the contents of a list. So a List<A>
doesn't care if it is a list of cows, space ships or dreams, as long as we pick one type of things and stick with it.
Abstraction
isn't limited to OOP. In functional programming, you may have it too.
For example, you have a method to search a person in a list, and a second implementation, and you wan't to measure the time, they take, to make a performance optimization.
In functional programming, you don't have to place a measurement around the function call 1, and another one around function call 2, but you may define a function for measurement, which expects another function (the one to measure) as argument.
(Pseudocode):
fun measure (int count, (List<Person> persons, Person x)=>int)
measure (1000, joesSearch (myList, paul))
measure (1000, amysSearch (myList, paul))
But abstraction is present in procedural context too - be it with or without OOP.
A function or procedure call is an abstract thing:
printHello (times int) {
for (i : (1 .. times)) print ("Hello")
}
is a form of abstraction - it abstracts away the number of times, an action should be performed, similarly
print5times (message string) {
for (i : (1 .. 5)) print (message)
}
abstracts over the content of the message.
Even a variable is an abstract thing:
for (i : (1 .. 9)) print ("Number " + i)
i is bound to different numbers, so i is an abstract thing. During runtime it gets concrete: Number 1, 2, 3 and so on.
Encapsulation
is more the opposite: It's a form of concretion.
In OOP, you have a class, and this can have attributes and methods. In a GUI, you may have a textbox, where the user can put text into. A label might have text as well, but the user isn't able to modify it. An icon or slider as different GUI-elements might not have text, associated.
Instead of a global method "getText", where you put your parameter to:
getText (label) // fine
getText (textfield) // dito
getText (slider) // fail
the encapsulation approach is, to bind a method inside a datastructure, so that the method is only called for the right thing (object):
label.getText ()
textfield.getText ()
slider.getText () // no such method in Slider
A private method will not be accessible from outside, but that's not the main aspect of encapsulation, but the binding of the data, which defines an object, with the behavior of an object. And this is a kind of specialization, hence, the opposite of abstraction.
So we have multiple ideas behind encapsulation: information hiding and separation of concern. And again, we find principles of encapsulation in functional programming. You may have methods hidden in other methods, like in this example:
def foo () = { fun rekursiveFoo (x: X) = if (cond) xx else rekursiveFoo (g (x)) rekursiveFoo (generateX ()) }
rekursiveFoo might need some setup, some initialization, and isn't visible from outside.
精彩评论