deepak
deepak

Reputation: 107

Why Encapsulation is called data hiding, if its not hiding the data?

What is the difference between following two class in terms of data hiding(encapsulation).

In below example , I can access the value of member by making it public.

Eg: 1

public class App {
   public int b = 10;

public static void main(String[] args) {
    System.out.println(new App().b);
 }
}

In below example, I can access the value of member by using getter method.

Eg : 2

class DataHiding 
   {

    private int b;

    public DataHiding() {
    }

    public int getB() {
        return b;
    }

    public void setB(int b) {
        this.b = b;
    }

    }

In both the above examples, I can access the value of member. Why Eg : 2, is called data hiding (encapsulation) ? If its not hiding the data.

Why Eg : 1 is not called encapsulated ?

Upvotes: 2

Views: 1922

Answers (5)

bric3
bric3

Reputation: 42223

What is it about

As you tagged this question with both and object oriented programming , I suppose you are implicitly thinking about Java Beans. Nevertheless this is a question quite common across languages, take the wikipedia page on this matter :

In programming languages, encapsulation is used to refer to one of two related but distinct notions, and sometimes to the combination1 thereof:

  • A language mechanism for restricting access to some of the object's components.
  • A language construct that facilitates the bundling of data with the methods (or other functions) operating on that data.

Some programming language researchers and academics use the first meaning alone or in combination with the second as a distinguishing feature of object-oriented programming, while other programming languages which provide lexical closures view encapsulation as a feature of the language orthogonal to object orientation.

The second definition is motivated by the fact that in many OOP languages hiding of components is not automatic or can be overridden; thus, information hiding is defined as a separate notion by those who prefer the second definition.

So encapsulation is not really about hiding data or information it about enclosing pieces of data in a language component (a class in Java). A Java Beans encapsulate data.

That being said, while encapsulation is one of the main feature of object oriented programming paradigm, at some point in the history of language design it was seen as not enough to help design better software.

History

One key practice to achieve better software design is decoupling, and encapsulation helps on that matter. Yet a cluster of data was not enough to help achieve this goal, other efforts in OOP pioneering were made in different language at that time, I believe SIMULA is the earliest language to introduce some kind of visibility keywords among other concepts like a class. Yet the idea of information hiding really appears later in 1972 with data that is only relevant to the component that uses it to achieve greater decoupling.

But back to the topic.

Answers to your questions

  1. In this case data is encapsulated and public

    This is commonly known as a global variable and it is usually regarded as a bad programming practice, because this may lead to coupling and other kind of bugs

  2. Data is encapsulated and public (through method accessors)

    This class is usually referred to as a Java Bean, these are an abomination if used in any other than what they were designed for.

    These object were designed to fulfill a single role and that is quite specific is according to the specification

    2.1 What is a Bean? Let's start with an initial definition and then refine it:

    “A Java Bean is a reusable software component that can be manipulated visually in a builder tool.”

    Why is it an abomination nowadays ? Because people, framework vendors usually misuse them. The specification is not enough clear about that, yet there's some statement in this regard :

    So for example it makes sense to provide the JDBC database access API as a class library rather than as a bean, because JDBC is essentially a programmatic API and not something that can be directly presented for visual manipulation.

    I'd rather quote Joshua Bloch (more in this question and answer) :

    "The JavaBeans pattern has serious disadvantages." - Joshua Bloch, Effective Java

Related points

As explained above one key practice to achieve better software is decoupling. Coupling has been one of the oldest battlefront of software engineers. Encapsulation, information hiding have a lot to do with the following practices to help decoupling for numerous reasons:

  • the Law of Demeter, breaking this law means the code has coupling. If one has to traverse a whole data graph by hand then, there's no information hiding, knowledge of the graph is outside of the component, which means the software is therefore less maintainable, less adaptable. In short : refactoring is a painful process. Anemic domain model suffer from that, and they are recognized as an anti-pattern.

    A somehow modern practice that allows one to not break the Law of Demeter is Tell, Don't Ask.

    That is, you should endeavor to tell objects what you want them to do; do not ask them questions about their state, make a decision, and then tell them what to do.

  • immutability, if data has to be public it should be immutable. In some degree if data is not needed, one module can introduce side effects in another ; if this was true for single threaded programs, it's even more painful with multi-threaded softwares. Today softwares and hardware are getting more and more multi-threaded, threads have to communicate, if an information has to be public it should be immutable. Immutability guarantee thread-safety, one less thing to worry about. Also immutability has to be guaranteed on the whole object graph.

    class IsItImmutable {
      // skipping method accessors for brevity
    
      // OK  <= String is immutable
      private final String str;
    
      // NOK <= java.util.Date is mutable, even if reference is final a date can be modified
      private final Date  date;
    
      // NOK <= Set operations are still possible, so this set is mutable
      private final Set<String> strs;
    
      // NOK <= Set is immutable, set operations are not permitted, however Dates in the set are mutable
      private final Set<Date> udates = Collections.unmodifiableSet(...);
    
      // OK  <= Set is immutable, set operations are not permitted, String is immutable
      private final Set<String> ustrs = Collections.unmodifiableSet(...);
    }
    

Upvotes: 2

Dalija Prasnikar
Dalija Prasnikar

Reputation: 28516

Encapsulation is not data hiding it is information hiding. You are hiding internal structure and data implementation, as well as data access logic.

For instance you can store your integer internally as String, if you like. In first case changing that internal implementation would mean that you have to also change all code that depends on b being an int. In second case accessor methods will protect internal structure and give you int, and you don't have to change the rest of the code if internals have changed.

Accessor methods also give you opportunity to restrict access to the data making it read-only or write-only in addition to plain read-write access. Not to mention other logic that can verify integrity of data going into the object as well as changing object state accordingly.

Upvotes: 1

David van rijn
David van rijn

Reputation: 2220

In java, all methods are virtual. This means, that if you extend some class, you can override the result of a method. Imagine for example the next class (continuing on your example):

class DataHidingDouble extends DataHiding{
  public int getB(){
    return b*2;
  }
}

this means that you maintain control over what b is to the outer world in your subclass. imagine also some subclass where the value of b comes from something that is not a variable, eg. a database. How are you then going to make b return the value if it is a variable. It hides the data, not the value. Because the class is responsible for maintaining the data, and returning the correct value to the outside world.

Upvotes: 0

Maroun
Maroun

Reputation: 95958

Using mutators and accessors hides the logic, not the name of the methods. It prevents users from directly modifying the class members.

In your second example, the user has no idea about the class member b, whereas in the first example, the user is directly exposed to that variable, having the ability to change it.

Imagine a situation where you want to do some validation before setting the value of b, or using a helper variable and methods that you don't want to expose. You'll encapsulate the logic in your setter and by doing that, you ensure that users cannot modify the variable without your supervision.

Upvotes: 1

Ringo
Ringo

Reputation: 838

What happens if you want to retrieve the state of B without being able to change its value? you would create the getter but not the setter, you can't accomplish that by accessing B as a public int.

Also, in both methods get and set, if we had a more complex object, maybe we want to set or get some property or state of the object.

Example.

private MyObject a;

public setMyObjectName(String name){
     MyObject.name = name;
}

public getMyObjectName(){
     return MyObject.name;
}

This way we keep the object encapsulated, by restricting access to its state.

Upvotes: 0

Related Questions