-1

Here is a very simple code example:

public class Name {

    public string Name = "John"

}

If you made an instance of the Name class in another class(Name n = Name();), you can change the Name string of the instance by doing n.Name = "Chris";. However, this will just change the name for the instance of the Name class not the class itself. If you made a new instance of the Name class(Name na = Name();), and called the Name variable, it will still be "John" not "Chris".

I know that one of the reasons encapsulation is used is that so the user can't modify variables in a class. In the above example I showed, the user is not modifying the variable of the class itself.

Matt Ke
  • 3,599
  • 12
  • 30
  • 49
Calvin
  • 33
  • 4
  • 2
    *One of the reasons encapsulation is used is that so the user can't modify variables in a class.* How many more reasons do you need? Also, this code is not legal in Java. Nor does `Name.Name` make much sense. – Elliott Frisch Jan 09 '19 at 01:05
  • You seem to have answered your own question? What do you not understand? – Stalemate Of Tuning Jan 09 '19 at 01:07
  • I don't think you guys read my question completely :(. – Calvin Jan 09 '19 at 01:08
  • "*this will just change the name for the instance of the Name class not the class itself*" I don't know what you are trying to say here. If you make a new instance of a variable, it will have different properties from the first. That's the whole point of objects – Stalemate Of Tuning Jan 09 '19 at 01:14
  • Were you thinking all future `Name` objects initialized would start with "Chris" instead of "John"? – Stalemate Of Tuning Jan 09 '19 at 01:15
  • What I'm trying to say there is, no matter how many times the class variables got changed by the user, it's not going to affect the class variables in a class, since the changes are just being made to the instance of the class. So what is the point of setting the variables to private, when users can't modify the class variables anyway? – Calvin Jan 09 '19 at 01:20
  • 1
    Modifying "class variables" as you describe is not allowed because it makes no sense. The only time an object's properties matter are when the object is initialized as an instance (barring `static`). Encapsulation is about protecting **object instances** from unwanted change, not from rewriting the class itself. – Stalemate Of Tuning Jan 09 '19 at 01:23
  • 1
    I don't get it still. Then there is no point of using encapsulation. No one can modify variables in a class except the developer. why use encapsulation and use methods to get and set these variables and make things more complicated? – Calvin Jan 09 '19 at 01:32
  • @Calvin, hence we have [setter and getter](https://stackoverflow.com/questions/1568091/why-use-getters-and-setters-accessors) so the class can control who can modify its properties and if there are some pre or post assignment steps to be done. perhaps you need to get back and reread some concept such as `pointer` and `OOP` - or just the [encapsulation](https://stackoverflow.com/questions/31529809/encapsulation-vs-plain) part. really, before the flames set ablaze.. :( – Bagus Tesa Jan 09 '19 at 01:36
  • @Calvin Code is often shared among a team of developers in professional development environments. In this case you want to ensure that people don't break code that you wrote because they were using its properties incorrectly. If you are the only person that uses it, then yes it would not matter. But consider that you might as well be another person when you come back to a project two months from now and decide to make some changes. – Stalemate Of Tuning Jan 09 '19 at 01:50
  • first of all new instance of Class will be be created by Name na = new Name(); , You missed the new. – Vishwa Ratna Jan 09 '19 at 03:44
  • Do you really understand what is a `Class` and what is an `Object`? Please read at least a cookbook for the reason that you even don't know how to create an object. – Keijack Jan 09 '19 at 03:54
  • Encapsulation / Data hiding is too abstract; let's talk about **wallets**. I think everyone will agree that my wallet is distinct from your wallet. Our wallets each contain money, but my wallet contains my money and your wallet contains your money (and these are important properties for our wallets to have). Further, it isn't possible for you to reach into your wallet and take money from my wallet. Nor is the reverse possible (such a pity). – Elliott Frisch Jan 10 '19 at 03:32

3 Answers3

1

Let's say you load a data from a server or local database and you parsed it to your own object. For example, user's profile.

class User {

    public static final String TAG = User.class.getSimpleName();
    private String name; 
    private String userToken; 
}

The User class doesn't have any default or static values because the data will be fed by the server.

The data you get from the server or DB will be something like,

name: John
userToken: 0x23fa8.... 

If the fields in your User class is public, the user (or any other parties) will access to the data and manipulate it. Think about the case the user changed his/her AuthToken, device id, or backup key phrases, etc... and if this manipulated data gets committed, it will cause a lot of trouble and clearly not what you want.

Just like @StalematOfTuning said, encapsulation is about protecting object instance's fields, not protecting pre-defined, class variables. If you only want to create a class with pre-defined class properties (static values), there's really no point of constructing a class because the class you created cannot be reusable for any other situation.

For example, if you already know the Name class will have one and only value, "John", it is wasteful to even constructing a class. The whole point of creating a class or an object is to reuse it for any possible input or data.

WasabiTea
  • 389
  • 2
  • 10
  • Thank you so much for answering. If your variable is changed to the value you don't want, you can just create a new instance of that class, so you 'll have the original value? – Calvin Jan 09 '19 at 02:15
  • @Calvin The reason why we use objects is because we don't know what the original value will be. Let's say you load a user data with user id 29345 from the server. All you know is just a user id and you don't know the username, auth token, device id, etc... so there is no such thing as original value here since we don't know if the user is John or Kevin or Jason. When anyone changes the value of your object variable due to lack of encapsulation, and if that person commits that change to the server, you lose the actual value forever since the data source(server) is already rewritten. – WasabiTea Jan 09 '19 at 03:33
0

OK so I think you are confused about a few things here.

For starters, let's clean up this example a bit so it's easier to follow. I'm going to make a Person class:

public class Person {
    public String name;
}

Doesn't get much simpler than that. So, right now I have defined the class Person but it's important to note that no Person objects actually exist yet. The class Person can be thought of as a blueprint for making Person objects. So, let's make a person:

public static void main(String[] args) {
    Person john = new Person();
    john.name = "John";
}

Here I have initialized a Person by calling its default constructor (note the word new), and set its name property to "John".

Now, if someone else was using this code they could come along and say hey let's change his name because why not?

john.name = "Bob";

But wait... a person's name changing might not make sense in the context of our program. Perhaps we don't want people to be able to change their names whenever they want as it might cause us problems later down the line. Even worse, someone could try and do something weird like turning his name into a number or any other crazy garbage that completely breaks the program. We can fix this by instead encapsulating the name property. We do this by making name a private field and define a constructor as well as a way to view that field.

public class Person {
    private String name;

    public Person(String name) {
        this.name = name;
    }

    public String getName() { 
        return name;
    }
}

Now, we must define what we want name to be when we create the object. Let's make John again:

Person john = new Person("John");

But most importantly, there is no way to change John's name anymore. Since we have not provided a public way to do so, it is impossible.

If we try to change john now, our program will not compile:

john.name = "Bob"; //NOT ALLOWED

And to view our name, we will instead have to use our getter method:

System.out.println(john.getName()); //prints "John"

This is the essence of encapsulation: protecting an object's properties from undesired changes in state. Instead of just handing over our data, we hide its actual state and only allow actions on it through controlled channels. If we did want to allow names to be changed, maybe we are ok with it but only if the new name meets certain criteria. Let's say: the new name has to be at least 3 characters long (sorry Al). We can provide a setter like so:

public void setName(String newName) {
    if(newName.length() < 3) {
        System.out.println("name is too short!");
    } else {
        name = newName;
    }
}

In this way we can have much greater control over how our data is used. I hope this helps clear up your confusion a bit.

Also note that if you create a new Person you will again need to specify another String to use to set its name in the constructor. Every object must be uniquely initialized.

  • In your example, you can still change the name by doing, Person john = new Person("Sam"). – Calvin Jan 09 '19 at 02:14
  • That is not changing the name property, that is changing the reference to the object. – Stalemate Of Tuning Jan 09 '19 at 02:15
  • I don't know why I'm struggling so much with this concept.... I'm so mad that I don't get it. lol. If you know your variable is changed to an unwanted value because it was a public variable, you can just create a new instance of the class to restore the original value. – Calvin Jan 09 '19 at 02:31
  • The john variable is nothing but a reference that points to an object. This reference is separate from the actual object. When you **assign** a variable with the `=` operator you are just telling what object it should refer to. When you do something like `john.getName()`, that's when you actually go follow the pointer to a specific object (dereferencing). When you set `john` to a new person you are in essence just picking up a sign and pointing it somewhere else. Encapsulation is NOT about controlling how variables are used, just hiding and protecting the internal details of classes. – Stalemate Of Tuning Jan 09 '19 at 02:41
  • what are some real life applications where encapsulation is used? I want to know this, so I have better understanding of this concept. – Calvin Jan 09 '19 at 03:08
  • I guess like a profile class with ID, Password, security questions variables, is a good example right? You would set these variables to private so the users can't modify these variables. – Calvin Jan 09 '19 at 03:23
  • Yes that could be a good example. Almost any real java application developed is going to have OOP principles to some extent, and that includes encapsulation. There's tons of resources out there, look around a bit and see for yourself – Stalemate Of Tuning Jan 09 '19 at 03:40
  • I know this is a very basic stuff to know, but it's been confusing me a lot. .Thank you for answering my absurd questions. :). – Calvin Jan 09 '19 at 04:16
  • Trust me we've all been there. – Stalemate Of Tuning Jan 09 '19 at 21:55
0

why use encapsulation for data hiding?

A major advantage of modular code development is that modules can be uncoupled from each other. Modules that are not coupled have no dependencies upon each other. This means that they may be developed independently and in parallel. Moreover, as long as the contract that governs the behavior of modules does not change, then modules that are uncoupled can be modified or rewritten at any time without breaking the system in which they operate (as long as the behavior of the module continues to conform to its contract with other modules, i.e. its API).

Consider something like:

public class A {
    public String name = "Hello";
        :
        :
}

public class B {
    private A myA = new A();
    myA.name = "Hello World!"
        :
        :
}

We have written B to be dependent upon the way in which A has been implemented: namely that A has an instance field named name. The modules A and B are now coupled to each other because B depends upon A having this instance field. If we ever decide to change the way that A is implemented, we may be in trouble because a major overhaul to A may require a major overhaul in B.

Data hiding is valuable because it avoids this problem. We want to write B in a way such that B depends only on the behavior of A (i.e., it's API) and not at all on how that behavior is implemented. That A has an instance field name is an implementation detail and we want to keep those details separated from the rest of the software system. It is usually true that any mutable fields that comprise the state of your objects should be hidden from other parts of the system. They are implementation details that should not be made a part of the API that modules export to the rest of the system.

TL;DR: Generally speaking, the more uncoupled modules are, the easier and cheaper they are to develop and to maintain.

scottb
  • 9,908
  • 3
  • 40
  • 56