Abstraction vs Encapsulation in Java [duplicate]

試著忘記壹切 提交于 2019-11-27 08:58:53

问题


Possible Duplicate:
Abstraction VS Information Hiding VS Encapsulation

I know this question might have been asked thousands times on this forum, even net is also filled with lots of definitions about these concepts but all sounds same and all uses same technical words. For example following definitions

Encapsulation is a process of binding or wrapping the data and the codes that operates on the data into a single entity. This keeps the data safe from outside interface and misuse. One way to think about encapsulation is as a protective wrapper that prevents code and data from being arbitrarily accessed by other code defined outside the wrapper.

What I understood from above definition is that creating variables, mark them private and generate getter-setter for those variables and use object to access those getter and setter. In that way data is hidden inside object and is only accessible through object. Hope I am right.


Abstraction is the process in Java which is used to hide certain details and only show the essential features of the object. In other words, it deals with the outside view of an object (interface).

Now this is the part which confuses me always. Whenever I think about abstraction the thing which comes to my mind is Abstract class(may be because both have Abstract keyword). Above definition says abstraction means hiding data and only showing required details but that is what we are already doing in encapsulation right? then what is the difference. Also I did not get what is out side view of object in it deals with the outside view of an object.

Can someone please put more light on this with some real life example or with some programmatic examples if possible.


回答1:


OO Abstraction occurs during class level design, with the objective of hiding the implementation complexity of how the the features offered by an API / design / system were implemented, in a sense simplifying the 'interface' to access the underlying implementation.

The process of abstraction can be repeated at increasingly 'higher' levels (layers) of classes, which enables large systems to be built without increasing the complexity of code and understanding at each layer.

For example, a Java developer can make use of the high level features of FileInputStream without concern for how it works (i.e. file handles, file system security checks, memory allocation and buffering will be managed internally, and are hidden from consumers). This allows the implementation of FileInputStream to be changed, and as long as the API (interface) to FileInputStream remains consistent, code built against previous versions will still work.

Similarly, when designing your own classes, you will want to hide internal implementation details from others as far as possible.

In the Booch definition1, OO Encapsulation is achieved through Information Hiding, and specifically around hiding internal data (fields / members representing the state) owned by a class instance, by enforcing access to the internal data in a controlled manner, and preventing direct, external change to these fields, as well as hiding any internal implementation methods of the class (e.g. by making them private).

For example, the fields of a class can be made private by default, and only if external access to these was required, would a get() and/or set() (or Property) be exposed from the class. (In modern day OO languages, fields can be marked as readonly / final / immutable which further restricts change, even within the class).

Example where NO information hiding has been applied (Bad Practice):

class Foo {
   // BAD - NOT Encapsulated - code external to the class can change this field directly
   // Class Foo has no control over the range of values which could be set.
   public int notEncapsulated;
}

Example where field encapsulation has been applied:

class Bar {
   // Improvement - access restricted only to this class
   private int encapsulatedPercentageField;

   // The state of Bar (and its fields) can now be changed in a controlled manner
   public void setEncapsulatedField(int percentageValue) {
      if (percentageValue >= 0 && percentageValue <= 100) {
          encapsulatedPercentageField = percentageValue;
      }
      // else throw ... out of range
   }
}

Example of immutable / constructor-only initialization of a field:

class Baz {
   private final int immutableField;

   public void Baz(int onlyValue) {
      // ... As above, can also check that onlyValue is valid
      immutableField = onlyValue;
   }
   // Further change of `immutableField` outside of the constructor is NOT permitted, even within the same class 
}

Re : Abstraction vs Abstract Class

Abstract classes are classes which promote reuse of commonality between classes, but which themselves cannot directly be instantiated with new() - abstract classes must be subclassed, and only concrete (non abstract) subclasses may be instantiated. Possibly one source of confusion between Abstraction and an abstract class was that in the early days of OO, inheritance was more heavily used to achieve code reuse (e.g. with associated abstract base classes). Nowadays, composition is generally favoured over inheritance, and there are more tools available to achieve abstraction, such as through Interfaces, events / delegates / functions, traits / mixins etc.

Re : Encapsulation vs Information Hiding

The meaning of encapsulation appears to have evolved over time, and in recent times, encapsulation can commonly also used in a more general sense when determining which methods, fields, properties, events etc to bundle into a class.

Quoting Wikipedia:

In the more concrete setting of an object-oriented programming language, the notion is used to mean either an information hiding mechanism, a bundling mechanism, or the combination of the two.

For example, in the statement

I've encapsulated the data access code into its own class

.. the interpretation of encapsulation is roughly equivalent to the Separation of Concerns or the Single Responsibility Principal (the "S" in SOLID), and could arguably be used as a synonym for refactoring.


[1] Once you've seen Booch's encapsulation cat picture you'll never be able to forget encapsulation - p46 of Object Oriented Analysis and Design with Applications, 2nd Ed




回答2:


In simple words: You do abstraction when deciding what to implement. You do encapsulation when hiding something that you have implemented.




回答3:


Abstraction is about identifying commonalities and reducing features that you have to work with at different levels of your code.

e.g. I may have a Vehicle class. A Car would derive from a Vehicle, as would a Motorbike. I can ask each Vehicle for the number of wheels, passengers etc. and that info has been abstracted and identified as common from Cars and Motorbikes.

In my code I can often just deal with Vehicles via common methods go(), stop() etc. When I add a new Vehicle type later (e.g. Scooter) the majority of my code would remain oblivious to this fact, and the implementation of Scooter alone worries about Scooter particularities.



来源:https://stackoverflow.com/questions/11965929/abstraction-vs-encapsulation-in-java

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!