Good day!
I am reading a Java book about encapsulation and it mentioned the getter and setter method.
I've read that to hide the attributes, I must mark my instance variables as "PRIVATE" and make a "PUBLIC" method of getter and setter to access the data. So I tried making a similar but not the conventional code about it as follows:
public class AddressBookEntry {
private String name;
private String address;
private String telNo;
private String email;
public void getAllInfo() {
name = JOptionPane.showInputDialog("Enter Name: ");
address = JOptionPane.showInputDialog("Enter Address: ");
telNo = JOptionPane.showInputDialog("Enter Tel. No: ");
email = JOptionPane.showInputDialog("Enter Email Address: ");
}
}
Does my code above exposes my variables because I assigned it directly? How can I do this better? Would it be better if I make the conventional getter and setter method instead and assigned the values on the other class? What does "hiding the data" means?
Thank you.
You use setters and getters to make the variables accessible from outside your class. In your example you will have
public class AddressBookEntry {
private String name;
public void setName(String name) {
this.name = name;
}
public String getName() {
return name;
}
}
You will access the name property from a UI class (it isn't good to mix UI and business logic in the same class):
public class MyPane extends JFrame {
public getAllData() {
String name = JOptionPane.showInputDialog("Enter Name: ");
AddressBookEntry entry = new AddressBookEntry();
entry.setName(name);
// You can't use entry.name = name
}
}
Yes and no. The point of encapsulation is that it prevents other classes from needing to know what your class is doing behind the scenes. If you store your name in a String (as you've done here), read/write it from a file, or do something different, the point of encapsulation is that to the user of your class it doesn't matter because all they see is String getName( ) and void setName (String name).
Since the modification of the data is entirely under the control of your class here, it doesn't break encapsulation. If you did store name to file, then you could potentially do so in getAllInfo without any other user of the class being any the wiser. Since the observable behaviour from the outside of the class still hides what the internals of the class is doing, it's still encapsulated.
That said, this is a very unconventional approach. Like I describe in the first paragraph, use of accessor methods (getters and setters) is a more idiomatic approach, and easier to understand for someone else using your code. You can do what you do, it doesn't break encapsulation, but it's not what I'd call elegant or typical.
The idea of private class members (attributes, fields) is to access them directly inside the declaring class (not instance!) only. All other classes will have to use other accessors, for example getter and setter methods. So the way how the AdressBookEntry stores the name, address, telNo and email values, is perfectly hidden inside the class.
You don't have to use getters or setters, although, sometimes there are good reasons to do so inside the class too. Using getters and setters sometimes makes sense if you do some logging or validating before a value is set.
This doesn't violate encapsulation, as it doesn't expose the internal data to another class. You may wish to look at Model-View-Controller (MVC) though to help separate out your interface from your data.
Traditional you create a single getter and setter for each variable as needed like so:
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
Don't create getters for variables that won't need to be accessed outside of the class, and don't create setters for variables that won't need to be set outside of the class.
If following MVC and using the traditional getters and setters like above, you would have the view code elsewhere and call something like
myAddressBookEntry.setName(JOptionPane.showInputDialog("Enter Name: "));
I agree with all the great answers provided. I would like to add another great benefit about using encapsulation and is the fact that by hiding the data from its clients (just as the examples described above) you can guarantee how to set and get these instance variables making your class easier to maintain and test (i.e if you have many clients manipulating your objects variables you don't need to go class by class writing the new functionality, instead you just modify the getter and setter).
By making usage only of the objects setters and getters, the details of its implementation can be hidden from the outside world. This is a nice advantage so other objects attempting to interact with your class won't be able to break its functionality. This also increases the likelihood that a system will be implemented effectively.
I find the answers above already answering your question. But, I see another issue with your code, which is, a security and data integrity issue. You are filling your class member directly out of the user's input w/o any validations on it. For example, you'd probably want to check that the email address has an xyz#abc.com pattern. A malicious user might also provide a very long string in the input causing unexpected errors.
Related
[I know the following does not respect OOP rules, this is an early-dev project. I will do all the setters and getters later]
I have a class called 'Item', which contains a private field 'name'.
abstract class Item{
protected PImage texture;
protected int durability;
protected int maxDurability;
private String name;
}
I also have a class called 'Armor', which inherit 'Item'. So it should inherit the private field 'name', right ?
class Armor extends Item{
protected int defense;
Armor(){
//First try to change the value
name = "Armor";
//Second try using 'this' to be sure it doesn't try to change super.name
this.name = "Armor";
}
}
In both cases, I have an error when I try to change the value : "The field Time_Fighter.Item.name is not visible".
After reading some stuff about how 'private' works in Processing, I discovered some people proposed to use 'protected' instead.
The thing is, if I use 'protected', every classes have access to it. But I just want 'Item' and the subclasses of 'Item' to have access to their private fields inherited from 'Item'.
I might have done a pretty obvious error since I'm kinda just a beginner, so if this is not the intended way of doing so, please tell me how I'm supposed to do it...
[Edit.
It seems from answers I've seen that this is not possible this way. So here's there any way to have a variable that would only be accessible for subclasses and not all the package ?]
You can't.
Private variables are just that: private. That means a subclass can't access them.
You might instead add a setter() function that the subclass uses.
Normally you would just make it protected, but Processing doesn't use packages, so it ends up being the same as public.
Honestly, I wouldn't worry too much about this. Processing is designed to make things simple, so it skips over this topic a bit. If you really want this functionality, you might consider writing Java code (which can call Processing code), but that's a lot more involved than just writing Processing directly.
In your case, you might create a constructor in your Item class that takes a name as a parameter. Then you can call that constructor from your Armor class and pass in whatever value you want:
abstract class Item{
private PImage texture;
private int durability;
private int maxDurability;
private String name;
public Item(String name){
this.name = name;
}
}
class Armor extends Item{
private int defense;
Armor(){
super("Armor");
}
}
You can make your name field protected and place your Item and Armor classes to a separate package. Fields declared as protected are available to the classes of the same package and descendant classes.
See Controlling Access to Members of a Class
you can access all class-global variables even private ones via Reflection How do I read a private field in Java? . I use this a lot and it works pretty fine. So if someone really wants to access the variables he can most of the time.
I try to understand a lot of times but I failed to understand this.
Encapsulation is the technique of making the fields in a class private
and providing access to the fields via public methods. If a field is
declared private, it cannot be accessed by anyone outside the class,
thereby hiding the fields within the class.
How can we change the values of fields through setter methods? How do we prevent accessing the fields directly? What is the real use of encapsulation?
Assume you have an age property.
The user can enter a value of -10, which although is a valid number, is an invalid age. A setter method could have logic which would allow you to catch such things.
Another scenario, would be to have the age field, but hide it. You could also have a Date of Birth field, and in it's setter you would have something like so:
...
private int age
private Date dob
...
public void setDateOfBirth(Date dob)
{
this.dob = dob;
age = ... //some logic to calculate the age from the Date of Birth.
}
I have also been confused like you too for a long time until I read the book Encapsulation and Inheritance in Object-Oriented Programming Language and a website that explained the importance of Encapsulation. I was actually directed from the website to the book.
People always say encapsulation is "hiding of information" therefore, maybe, making encapsulation focus on security as the main use. Yes you are hiding information in practice, but that should not be the definition as it could confuse people.
Encapsulation is simply "minimizing inter-dependencies among separately-written modules by defining strict external interfaces" (quoting from the book). That is to say that when I am building a module, I want a strict contract between my clients and me on how they can access my module. Reason being that, I can improve the inner workings without it AFFECTING my client's, life, application or whatever they are using my module for. Because their "module" does not exactly depend on the Inner workings of my module but depends on the "external interface", I made available to them.
So, if I don't provide my client with a setter and give them direct access to a variable, and I realize that I need to set some restriction on the variable before my client could use it, me changing it, could be me, changing the life of my client, or application of my client with HUGE EXPENSE. But if I provided the "strict contract" by creating a "strict external interface" i.e setter, then I can easily change my inner workings with very little or no expense to my clients.
In the setter situation (using encapsulation), if it happens that when you set a variable, and I return a message informing you that it has been assigned, now I could send a message via my "interface", informing my client of the new way my module have to be interacted with, i.e "You cannot assign negative numbers" that is if my clients try to assign negative number. But if I did not use encapsulation, and gave my client direct access to a variable and I do my changes, it could result in a crashed system. Because if the restriction I implemented, is that, you could not save negatives and my client have always been able to store negatives, my clients will have a crashed system in their hands (if that "crashed system" was a banking system, imagine what could happen).
So, encapsulation is more about reducing dependency between module, and an improvement can be made "quietly" with little or no expense to other modules interacting with it, than it is of security. Because the interacting modules depend on the "strict external interface or strict contract".
I hope this explains it properly. If not you could go the links below and read for yourself.
encapsulation matters
Encapsulation and Inheritance in Object-Oriented Programming Languages
The real use of encapsulation is also in the fact that you can do additional checks/processing on the way the values are set.
You're not exactly preventing access to the fields -- you're controlling how others can access certain fields. For example you can add validation to your setter method, or you can also update some other dependent field when the setter method of a field is called.
You can prevent write or read access to the field (e.g. by only providing a getter or setter respectively) -- but encapsulation with properties allows you to do more than just that.
If you have private fields they can't be accessed outside the class, that means basically those fields don't exist to the outside world and yes you can change their value through setter methods but using setter methods you have more flexibility/control to say who gets to change the fields and to what value can they be changed to...basically with encapsulation you get to put restrictions on how and who changes your fields.
For example you have: private double salary, you setter method could restrict that only hr staff can change the salary field it could be written as:
void setSalary(Person p,double newSalary)
{
//only HR objects have access to change salary field.
If(p instanceof HR && newSalary>=0)
//change salary.
else
S.o.p("access denied");
}
Imagine if salary was public and could be access directly any can change it however and whenever they want, this basically the significance of encapsulation
The main idea behind encapsulation is data hiding. There are several reasons why we use encapsulation in object oriented programming. Some of the identified reasons for why we encapsulation are as follows (The real use of encapsulation).
Better maintainability: When all the properties are private and encapsulated, it is easy for us to maintain the program simply by changing the methods.
Make Debugging Easy: This is in line with the above point. We know that the object can only be manipulated through methods. So, this makes it easy to debug and catch bugs.
Have a Controlled Environment: Let the users use the given objects, in a controlled manner, through objects.
Hide Complexities: Hiding the complexities irrelevant to the users. Sometimes, some properties and methods are only for internal use and the user doesn't have to know about these. This makes is simple for the user to use the object.
So, to answer the question, "What is the use of encapsulation when I'm able to change the property values with setter methods?", given above are some of the main reasons why we use encapsulation. To provide an understanding on why, getters and setters are useful, given below are some important points, obtained from this article.
You can limit the values that can be stored in a field (i.e. gender must be F or M).
You can take actions when the field is modified (trigger event, validate, etc).
You can provide thread safety by synchronizing the method.
You can switch to a new data representation (i.e. calculated fields, different data type)
Any how i am able to change the values of fields through setter methods.
Only if the setter method lets you do that.
How we are preventing the accessing fields?
The setter and getter get to control if and how you can access the fields.
A setter may check if the value is valid. It may ask a SecurityManager if you should be allowed to do this. It may convert between data types. And so on.
Lets suppose you make a custom Date class with the following setters / getters:
getDay()
getMonth()
getYear()
setDay()
setMonth()
setYear()
Internally you could store the date using:
private int day;
private int month;
private int year;
Or you could store the date using a java.lang.Date-object:
private Date date;
Encapsulation doesn't expose how your class is working internally. It gives you more freedom to change how your class works. It gives you the option to control the access to your class. You can check if what the user enters is valid (you don't want the user to enter a day with a value of 32).
It's aim is nothing but protecting anything which is prone to change. You have plenty of examples on the web, so I give you some of the advantages of it:
Encapsulated Code is more flexible and easy to change with new requirements
Allows you to control who can access what. (!!!)
Helps to write immutable class in Java
It allows you to change one part of code without affecting other part of code.
Accessing fields thru methods make difference because it makes it OOP. Eg you can extend you class and change the behaviour which you cannot do with direct access. If you have getters / setters you can make a proxy of your class and do some AOP or a make a 1.4 dynamic proxy. You can make a mock from your class and make unit testing...
Encapsultaion is used for hiding the member variables ,by making member as private and access that member variable by getter and setter methods.
Example
class Encapsulation{
private int value ;
Encapsulation() {
System.out.println("constructor calling ");
}
void setValue(int value){
this.value = value;
}
int getValue() {
return value;
}
}
class EncapsulationMain {
public static void main(String args[]) {
Encapsulation obj = new Encapsulation();
obj.setValue(4);
//System.out.print("value is "+obj.value);
//obj.value = 55;
//System.out.print("obj changing the value"+obj.value);
System.out.print("calling the value through the getterMethod"+obj.getValue());
}
}
you cannot access the private value outside the class.
Well, encapsulation is not all about hiding data. It is all about getting control over what is stored in the fields. Using encapsulation we can make a field as read-only or write-only depending upon the requirements.Also the users don't know how the data is stored in the fields. We can use some special encryption in the setter methods and store it in the fields.
For example human is a object. We only require the name field of the human to be read by the user but not to be modified. Then we define only get method on the name field.This is how the encapsulation is useful.
If you have class all of its properties are private-meaning that they cannot be accessed from outside the class- and the only way to interact with class properties is through its public methods.
You are changing tha values by giving the public access to those methods(setters).
using encapsulation the fields of a class can be made read-only or write-only.
Instead of letting everyone access the variables directly:
public Object object;
Is better to use SET and GET methods, or for example just the GET method (Sometimes you dont want nobody to set other value to that variable).
public Object getObject() {
return object;
}
public void setObject(Object object) {
this.object = object;
}
By using encapsulation you separate your class from the out-side world (other classes) and out-side world can access and modify your class instance variables through access modifiers, which provides several benefits:
-You can do some logging in your getter/setter methods.
-You can validate /normalize (for example trim spaces, remove special character,...) Your input in setter method.
And also you can hide your implementation from the outside world, for example you have a collection like array list in your class and you write your getter method like this
public List<t> get collection(){
return new ArrayList<t>(this.arrayList);
}
So in this case, in the future if you decide to change your implementation of collection from array list to something else like linked list, you are free to do so because out side world doesn't know anything about your implementation.
Encapsulation is not about secrecy, it is about reducing dependency over separate part of the application.
We control dependency (loose / weak / low coupling) by hiding information over separate part of the application.
Adding to Uche Dim's answer, look at the following example:
Two Connections:
public class Area {
// fields to calculate area
private int length;
private int breadth;
// constructor to initialize values
Area(int length, int breadth) {
this.length = length;
this.breadth = breadth;
}
public int getLength() {
return length;
}
public void setLength(int length) {
this.length = length;
}
public int getBreadth() {
return breadth;
}
public void setBreadth(int breadth) {
this.breadth = breadth;
}
public int getArea() {
int area = length * breadth;
return area;
}
}
class Main {
public static void main(String[] args) {
Area rectangle = new Area(5, 6);
// Two Connections
int length = rectangle.getLength();
int breadth = rectangle.getBreadth();
int area = length * breadth;
System.out.println("Area: " + area);
}
}
Please note that in the Main class, we are calling two methods (getLength() and getBreadth()) of Area class.
One Connection:
public class Area {
// fields to calculate area
private int length;
private int breadth;
// constructor to initialize values
Area(int length, int breadth) {
this.length = length;
this.breadth = breadth;
}
public int getArea() {
int area = length * breadth;
return area;
}
}
class Main {
public static void main(String[] args) {
Area rectangle = new Area(5, 6);
// One Connection
int area = rectangle.getArea();
System.out.println("Area: " + area);
}
}
Here, in the Main class, we are calling one methods (getArea()) of Area class.
So in the second example, the connection is weaker than the previous one (first one calling two methods or the Area class, second one calling one method of the Area class). Given, less connection (lower / weaker coupling) is better, the second example is better.
We should always keep fields and methods private unless necessary. In the Two Connections example, we made the mistake of creating the getters unnecessarily. As we have created it, the IntelliJ Idea (auto suggestion of modern IDE) suggested the developer who was working on the Main class that you can use the getLength() and getBreadth() methods and he did. He did not inquire further to check if there was a getArea() method. As a result he created stronger coupling than necessary.
We should not unnecessarily create getters. We should not unnecessarily make fields public or protected. If you must, first try protected, if that does not work then make it public. That way we will have a lesser possibility of having a tighter coupling.
If you still have the question "what is the difference between making a field public compared to making a field private but it's getters public?", in other words "Why should we use a function to get a value instead of getting it directly?" Well it gives you another layer of abstraction. For example, if you need some extra processing of the data before receiving it (ex. validation), you can do it there. Moreover, once you expose internals of a class, you can not change that internal representation or make it better until making changes in all client codes.
For example, suppose you did something like:
public class Area {
private int length;
private int breadth;
}
class Main {
public static void main(String[] args) {
Area rectangle = new Area(5, 6);
int area = rectangle.length * rectangle.breadth;
System.out.println("Area: " + area);
}
}
Now, if you want to change breadth to width in Area class, you can not do it without breaking the program, unless you search and replace rectangle.breadth with rectangle.width in all the clients where rectangle.breadth was used (in this case Main class).
There are other benefits as well. For example, Member variables cannot be overridden like methods. If a class has getters and setters, it's subclass can override these methods and return what makes more sense in the context of subclass.
Please check Why getter and setter are better than public fields in Java? for more details.
P.S. These are trivial examples, but in large scale, when program grows and frequent change requests are a reality, this makes sense.
I'm OK with using get and set, to mask and make reengineering easier, but if you tell to a novice programmer that using get and set does encapsulation, as I've seen many times, they will use set and get for internal members initialized by the constructor.
And this 99.9 % is wrong!!!!!
private uint8_t myvar = 0;
setMyVar(uint8_t value){
this.myvar = value * (20 / 41);
}
uint8_t getMyVar(){
return this. myvar ;
}
That’s for me is ok, but I think encapsulation is a method first, rather than get and set.
My inglish is not very well,but I think that this article says something like this.
I was wondering if it's possible to use a variable of a java class in another java class.Suppose variable Time is defined and calculated in Class A, how can I use it in Class B?
Other answers have suggested increasing a variable's visibility. Don't do this. It breaks encapsulation: the fact that your class uses a field to store a particular piece of information is an implementation detail; you should expose relevant information via the class's API (its methods) instead. You should make fields private in almost all cases.
Likewise, some other answers have suggested possibly making the variable static. Don't do this arbitrarily. You need to understand what static really means: it's saying that this piece of information is related to the type rather than to any one particular instance of the type. Occasionally that's appropriate, but it's generally a road towards less testable code - and in many cases it's clearly wrong. For example, a Person class may well have a name variable, but that certainly shouldn't be static - it's clearly a piece of information about a single person.
You should think carefully before exposing information anyway - consider whether there's a wider operation which the class in question could expose, instead of just giving away its data piecemeal - but when you do want to expose a field's value, use a property. For example:
public class Person {
private final String name;
public Person(String name) {
this.name = name;
}
public String getName() {
return name;
}
}
By exposing it via a method, you can later change the implementation details without breaking existing clients.
Then from another class, you'd just call the getName() method:
// However you end up getting a reference to an instance of Person
Person person = ...;
String name = person.getName();
If you do have a static field, you can expose the value in the same way, but with a static method, which you'd call using the class name.
Be careful about returning values which are mutable, e.g. java.util.Date. This is another reason for using a getter method instead of allowing direct access to the field - you can make the method return a defensive copy where you need to.
If it is declared as public, you may use ClassA.yourVariable. On the other hand, for private access modifier, include the getter to your ClassA. On the ClassB, call ClassA.getYourVariable().
Also read about access specifiers in Java it might help.
If the variable is static, you can refer to it as A.Time from any code that has access to the variable. There's only one Time value for all of class A. If it is an instance variable, and you have an instance a of class A, you can refer to the variable as a.Time. There's a separate value for each instance of class A.
This is subject to Java's access rules:
if the field is public, any code can access it (this makes public variables kind of dangerous unless they are also declared final)
if the field is protected, only code in the same package or in a subclass of A can access it
if the field has default access, only code in the same package as class A can access it
if the field is private, only code in class A (including inner classes of A) can access it.
Alternatively, you can provide an accessor method in class A:
public class A {
. . .
public class getTime() {
return this.Time; // the "this." is optional
}
}
If you declare your Variable as public or static you will be able to access it from another class.
WHICH IS A VERY VERY BAD IDEA :)
Iam a Java beginner and i would like to ask whats the pros and cons about this:
If i make a Class and i wont write my own setters and getters i can just get and set my class's properties like:
myClassInstance.name = "Jones"
myClassInstance.job = "Manager"
System.out.println(myClassInstance.name);
System.out.println(myClassInstance.job);
Why better if i make getters and setters and do like this:
myClassInstance.setName("Jones");
myClassInstance.setJob("Manager");
System.out.println(myClassInstance.getName());
System.out.println(myClassInstance.getJob());
This question is related to one of the basic principals of OO design: Encapsulation!
Accessors (also known as getters and setters) are methods that let you read and write the value of an instance variable of an object
public class AccessorExample {
private String attribute;
public String getAttribute() {
return attribute;
}
public void setAttribute(String attribute) {
this.attribute = attribute;
}
}
Why to use them?
Getter and Setters make APIs more stable. Lets consider a field public in a class which is accessed by other classes. Now later on, you want to add any extra logic while getting and setting the variable. This will impact the existing client that uses the API. So any changes to this public field will require change to each class that refers it. On the contrary, with accessor methods, one can easily add some logic like cache some data, lazily initialize it later. Moreover, one can fire a property changed event if the new value is different from the previous value. All this will be seamless to the class that gets value using accessor method.
Also Getters and setters methods allow different access levels - for eg. Get may be public, but the Set could be protected.
directly accessing the fields will lead to voilation of encapsulation.
making public variables to access them will be difficult to manage the state of that object.
where as with methods you can easily control state of the object.
Using getters and setters instead of public members is called encapsulation, and is a fundamental OOP concept. This way you are able to control the input and keep some sort of logic and validity to your models.
class Bottle {
public int volume = 0;
}
class EncapsulatedBottle {
private int volume = 0;
public void setVolume(int volume) throws Exception {
if (volume < 1) {
throw new Exception("A bottle cannot have a negative volume");
}
this.volume = volume;
}
public int getVolume() {
return this.volume;
}
}
Spot the difference :-)
Using getters and setters gives you more control over the validity of your objects, giving you the option of testing values that are set to ensure that they are reasonable, etc. (And of course, for read-only properties, you just leave off the setter.) On a modern JVM with a just-in-time compiler, they essentially don't cost anything; if they're really just reading and writing to a private data member, and if they're in a hotspot (bit of code that gets used a lot), the JIT will inline them.
Using getters/setters is normally better, because:
you can restrict (public) access to readonly (no setter)
you can add additional code without having to recompile/change the users of the property (i.e. classes that call the getter/setter)
it complies with the Java Bean specification which states a property must have getters/setters - and many libraries/frameworks, like Java EL etc. rely on that contract
Today i heard from my friend, that encapsulation is not only achieving information hiding but also abstraction. How does it achieve?
public class employee {
private String name;
private int id;
public void setName(String name){
this.name = name;
}
public String getName(){
return name;
}
}
The above example achieves encapsulation where i am allowing the class to access my public method rather than private members, but where does the abstraction come into picture here? Can anyone explain me on abstraction in a bit clear manner.
There's two different things, information hiding and abstraction.
Information hiding makes abstraction possible, but it is something different. For example, using your code
public class employee {
private String name;
private int id;
public void setName(String name) {
this.name = name;
}
public String getName(){
return name;
}
}
The id field is actually hidden. This allows one to handle ids in a manner that is decoupled from the rest of the program. Your name field is actually hidden too, as you don't access the name field directly, but the code in getName and setName does.
Once you hide the structure of the data from the rest of the code, forcing access through methods, it is possible to create a number of replaceable implementations of an item. For example, an employee is a conceptual kind of person, so you could rewrite the above like so:
public interface Person {
public abstract String getName();
}
public class Employee implements Person {
private String name;
private int id;
public void setName(String name){
this.name = name;
}
public String getName(){
return name;
}
}
Now your code can deal with the Employee as a Person. After rewriting the rest of the code that doesn't explicitly deal with Employees to deal with Persons, you could implement other kinds of Persons and leverage the non-Employee specific tasks that are now Person tasks.
public Customer implements Person {
private String name;
private integer moneySpent;
public String getName() {
return name;
}
}
So a person searching routine, as long as it only indexes Person objects can now include searches of both Employees and Customers. This is because the code dealing with Person objects is actually dealing with a higher level abstraction that both Employee and Customer objects share.
When dealing with Objects on an abstract level, the names of the methods are shared across the abstraction; but, the actual code executed depends on the unmentioned underlying type of the object. In other words, if you ask a Person (who happens to be an employee) getName() then it will respond with the Employee.getName() function, while a Customer will respond with a Customer.getName() function. Since the code calling getName() is operating on Persons it has no idea which type of person it will be handling, but the apparent change in behavior (the selection of the right block of code on a per-object basis) still happens. This phenomena is known as Polymorphisim, and if you are first hitting these concepts, you'll hear Polymorphisim as a word used a lot.
An example of polymorpic behavior:
public interface Animal {
public abstract String makeSound();
}
public class Cow implements Animal {
public String makeSound() {
return "Moo Moo!";
}
}
public class Dog implements Animal {
public String makeSound() {
return "Ruff Ruff!";
}
}
public class Sheep implements Animal {
public String makeSound() {
return "Baa Baa!";
}
}
// this class demonstrates the polymorphic behavior
public class Farm {
public static void main(String[] args) {
ArrayList<Animal> animals = new ArrayList<Animal>();
animals.add(new Cow());
animals.add(new Sheep());
animals.add(new Dog());
for (Animal animal : animals) {
// this is where the polymorphisim occurs
// each animal will make a different sound
// because the makeSound method is getting
// bound to different blocks of code based
// on the exact type of animal class hiding
// under the Animal abstraction.
System.out.println(animal.makeSound());
}
}
}
expected output:
Moo Moo!
Baa Baa!
Ruff Ruff!
even though we never explicitly changed classes, and we never explicitly changed methods. It was the binding of the abstract method to the explicit subclass that was changing, which is something that only happens in systems that support polymorphisim.
# John your friend is right by implementing the encapsulation you also achieve abstraction.
public class employee {
private String name;
private int id;
public void setName(String name){
name= name+"something that you want to edit";
this.name = name; }
public String getName(){
return name; }
}
in this way you have edited ur set method and hided the details from the user which is nothing but abstraction...
thus by writting getters and setters you hide user to do the unneccessary task...
public void setName(String name){
/*some internal logic suppose in database you want name
*should be added with its id but what user to do with it.*/
this.name = name; }
public String getName(){
/* now suppose you have recieved the name from
*data base it has id but you want user to know only
name then you will write the logic here to show the name.*/
return name; }
I know adding id to name is a stupid example but thats what i can think of right now... but consider for a very big project you many times write code in set(or call other method which modifies the parameters of it) then what...
suppose you get the name but you want to save it in a encrypted form in db, then what.
User dont care about the encryption but yes you have to... because its uneccesary to the user but important to you. So that should be in the code of yours but hidden from the user and thats what is all about abstraction*("HIDING THE UNNECCESARY DETAILS FROM USER")*
EDITED:-Go to the source! Grady Booch says (in Object Oriented Analysis and Design, page 49, second edition):
"Abstraction and encapsulation are complementary concepts: abstraction focuses on the observable behavior of an object... encapsulation focuses upon the implementation that gives rise to this behavior... encapsulation is most often achieved through information hiding, which is the process of hiding all of the secrets of object that do not contribute to its essential characteristics."
from above you can conclude the same
I think he's confusing polymorphism with encapsulation. Polymorphism can help you achieve abstration.
It's mostly encapsulation here, but there is some abstraction as well. By using a method called setName(), code that consumes your class doesn't need to know how you're implementing the operation of "setting a name". For all they know, you're calling out to a webservice and setting it in a database somewhere. Or maybe you're ignoring the parameter entirely and setting the name to "Steven" every time. Those facts are abstracted away from the caller.
I don't think you can prove encapsulation with that particular example. It's more like this:
interface NameService {
String getName();
}
Now, tell me: does a class implementing this interface get the name from a flat file, a database, a nosql store, or someplace else?
Abstraction is all about a concept/model which cannot be realized / instantiated as such.
Abstraction is all about restriction on an object's method/members behaviour to other classes.
Personally I wouldn't say encapsulation is really about abstraction (though I see how it could be taken that way), it's about only permitting a user to see or do what's necessary - they only see an interface to the class, not its inner workings. In your case it's achieved because you're only ever setting or getting the name of the particular class, you never access the name variable directly and never see how it's stored. So you could change the name or type of the name variable to something completely different and the interface to your class would still work and look the same. I guess that could be taken in a sense as an abstraction.
The definitions are loose, but I'd consider polymorphism to fall more into the realms of abstraction, where you decouple the implementation (say, ArrayList) from the interface it inherits (say, List.) That way you just deal with the list interface, and the underlying list could be anything, but that's an implementation detail and because you're an abstract level "above" it, you don't need to worry about it. Of course this is a simplification, sometimes you need to know implementation details for performance reasons or if some operations may not be implemented or allowed on your specific implementation. But from a loose viewpoint (and a pure OO viewpoint) it holds.
Whatever you understand it to be, the most important thing is you understand the logic behind it, why it's a good idea and why it's always better to do things that way (in this case, have fields as private and use getters / setters to access them.)
but where does the abstraction come into picture here?
you've said it yourself: "allowing the class to access my public method rather than private members"
or in other words: allowing other classes to access what they may access, and protecting what they may not.
the abstraction here comes from the public methods, for instance in getName() you don't need to always give the private member value, it could be appended with other value or even it could give totally different thing. it's like saying: "tell me your name, regardless how you'd give it to me". maybe a better example would be a method named getYourWorkDone(). the principle remains the same: "get your work done! how? I don't care how!"
the encapsulation part is from the private members. this class encapsulates those private members so they are grouped to form the class' state.
java official documentation for you to understand when to use interface or abstraction.
Also, I couldn't help notice that you were confused between encapsulation and abstraction so here is a simple difference between them for geekforgeeks website
Encapsulation is data hiding (information hiding) while,
Abstraction is detailed hiding
(implementation hiding).
Encapsulation groups together data and methods that act upon the data, data abstraction deal with exposing the interface to the user and hiding the details of implementation.
It seems encapsulation and abstraction has got everyone confused. If you ask me, those are poles-apart topics and there is absolutely no scope of confusion in this.
abstraction happens when you use "abstract" keyword, and encapsulation happens when you create a class. a good implementation of encapsulation involves making all your data members private.
I wrote a few blog posts that might help you:
Learn how to use an Abstract Class in Object Oriented Design
The Theory of Abstraction
Abstraction is done when you want to hide the data.Whereas encapsulation is done when you want to hide both data and code.That is wrapping both data and code which you implement.
You can implement abstraction by using abstract class or interface.
In abstract class we can either write concrete methods or abstract methods but in interface we can only use abstract methods.
You can implement encapsulation by using access modifiers like public, protected, private.
These access modifiers control the access of your data i.e whether it should be public(can be seen by anyone) or protected(can be accessed only by extended classes) or private(hiding it from everyone).