Abstraction in Java?
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 encapsulatio开发者_JS百科n 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 Employee
s to deal with Person
s, you could implement other kinds of Person
s 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 Employee
s and Customer
s. 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 Person
s 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).
精彩评论