Related
I have seen this mentioned a few times and I am not clear on what it means. When and why would you do this?
I know what interfaces do, but the fact I am not clear on this makes me think I am missing out on using them correctly.
Is it just so if you were to do:
IInterface classRef = new ObjectWhatever()
You could use any class that implements IInterface? When would you need to do that? The only thing I can think of is if you have a method and you are unsure of what object will be passed except for it implementing IInterface. I cannot think how often you would need to do that.
Also, how could you write a method that takes in an object that implements an interface? Is that possible?
There are some wonderful answers on here to this questions that get into all sorts of great detail about interfaces and loosely coupling code, inversion of control and so on. There are some fairly heady discussions, so I'd like to take the opportunity to break things down a bit for understanding why an interface is useful.
When I first started getting exposed to interfaces, I too was confused about their relevance. I didn't understand why you needed them. If we're using a language like Java or C#, we already have inheritance and I viewed interfaces as a weaker form of inheritance and thought, "why bother?" In a sense I was right, you can think of interfaces as sort of a weak form of inheritance, but beyond that I finally understood their use as a language construct by thinking of them as a means of classifying common traits or behaviors that were exhibited by potentially many non-related classes of objects.
For example -- say you have a SIM game and have the following classes:
class HouseFly inherits Insect {
void FlyAroundYourHead(){}
void LandOnThings(){}
}
class Telemarketer inherits Person {
void CallDuringDinner(){}
void ContinueTalkingWhenYouSayNo(){}
}
Clearly, these two objects have nothing in common in terms of direct inheritance. But, you could say they are both annoying.
Let's say our game needs to have some sort of random thing that annoys the game player when they eat dinner. This could be a HouseFly or a Telemarketer or both -- but how do you allow for both with a single function? And how do you ask each different type of object to "do their annoying thing" in the same way?
The key to realize is that both a Telemarketer and HouseFly share a common loosely interpreted behavior even though they are nothing alike in terms of modeling them. So, let's make an interface that both can implement:
interface IPest {
void BeAnnoying();
}
class HouseFly inherits Insect implements IPest {
void FlyAroundYourHead(){}
void LandOnThings(){}
void BeAnnoying() {
FlyAroundYourHead();
LandOnThings();
}
}
class Telemarketer inherits Person implements IPest {
void CallDuringDinner(){}
void ContinueTalkingWhenYouSayNo(){}
void BeAnnoying() {
CallDuringDinner();
ContinueTalkingWhenYouSayNo();
}
}
We now have two classes that can each be annoying in their own way. And they do not need to derive from the same base class and share common inherent characteristics -- they simply need to satisfy the contract of IPest -- that contract is simple. You just have to BeAnnoying. In this regard, we can model the following:
class DiningRoom {
DiningRoom(Person[] diningPeople, IPest[] pests) { ... }
void ServeDinner() {
when diningPeople are eating,
foreach pest in pests
pest.BeAnnoying();
}
}
Here we have a dining room that accepts a number of diners and a number of pests -- note the use of the interface. This means that in our little world, a member of the pests array could actually be a Telemarketer object or a HouseFly object.
The ServeDinner method is called when dinner is served and our people in the dining room are supposed to eat. In our little game, that's when our pests do their work -- each pest is instructed to be annoying by way of the IPest interface. In this way, we can easily have both Telemarketers and HouseFlys be annoying in each of their own ways -- we care only that we have something in the DiningRoom object that is a pest, we don't really care what it is and they could have nothing in common with other.
This very contrived pseudo-code example (that dragged on a lot longer than I anticipated) is simply meant to illustrate the kind of thing that finally turned the light on for me in terms of when we might use an interface. I apologize in advance for the silliness of the example, but hope that it helps in your understanding. And, to be sure, the other posted answers you've received here really cover the gamut of the use of interfaces today in design patterns and development methodologies.
The specific example I used to give to students is that they should write
List myList = new ArrayList(); // programming to the List interface
instead of
ArrayList myList = new ArrayList(); // this is bad
These look exactly the same in a short program, but if you go on to use myList 100 times in your program you can start to see a difference. The first declaration ensures that you only call methods on myList that are defined by the List interface (so no ArrayList specific methods). If you've programmed to the interface this way, later on you can decide that you really need
List myList = new TreeList();
and you only have to change your code in that one spot. You already know that the rest of your code doesn't do anything that will be broken by changing the implementation because you programmed to the interface.
The benefits are even more obvious (I think) when you're talking about method parameters and return values. Take this for example:
public ArrayList doSomething(HashMap map);
That method declaration ties you to two concrete implementations (ArrayList and HashMap). As soon as that method is called from other code, any changes to those types probably mean you're going to have to change the calling code as well. It would be better to program to the interfaces.
public List doSomething(Map map);
Now it doesn't matter what kind of List you return, or what kind of Map is passed in as a parameter. Changes that you make inside the doSomething method won't force you to change the calling code.
Programming to an interface is saying, "I need this functionality and I don't care where it comes from."
Consider (in Java), the List interface versus the ArrayList and LinkedList concrete classes. If all I care about is that I have a data structure containing multiple data items that I should access via iteration, I'd pick a List (and that's 99% of the time). If I know that I need constant-time insert/delete from either end of the list, I might pick the LinkedList concrete implementation (or more likely, use the Queue interface). If I know I need random access by index, I'd pick the ArrayList concrete class.
Programming to an interface has absolutely nothing to do with abstract interfaces like we see in Java or .NET. It isn't even an OOP concept.
What it means is don't go messing around with the internals of an object or data structure. Use the Abstract Program Interface, or API, to interact with your data. In Java or C# that means using public properties and methods instead of raw field access. For C that means using functions instead of raw pointers.
EDIT: And with databases it means using views and stored procedures instead of direct table access.
Using interfaces is a key factor in making your code easily testable in addition to removing unnecessary couplings between your classes. By creating an interface that defines the operations on your class, you allow classes that want to use that functionality the ability to use it without depending on your implementing class directly. If later on you decide to change and use a different implementation, you need only change the part of the code where the implementation is instantiated. The rest of the code need not change because it depends on the interface, not the implementing class.
This is very useful in creating unit tests. In the class under test you have it depend on the interface and inject an instance of the interface into the class (or a factory that allows it to build instances of the interface as needed) via the constructor or a property settor. The class uses the provided (or created) interface in its methods. When you go to write your tests, you can mock or fake the interface and provide an interface that responds with data configured in your unit test. You can do this because your class under test deals only with the interface, not your concrete implementation. Any class implementing the interface, including your mock or fake class, will do.
EDIT: Below is a link to an article where Erich Gamma discusses his quote, "Program to an interface, not an implementation."
http://www.artima.com/lejava/articles/designprinciples.html
You should look into Inversion of Control:
Martin Fowler: Inversion of Control Containers and the Dependency Injection pattern
Wikipedia: Inversion of Control
In such a scenario, you wouldn't write this:
IInterface classRef = new ObjectWhatever();
You would write something like this:
IInterface classRef = container.Resolve<IInterface>();
This would go into a rule-based setup in the container object, and construct the actual object for you, which could be ObjectWhatever. The important thing is that you could replace this rule with something that used another type of object altogether, and your code would still work.
If we leave IoC off the table, you can write code that knows that it can talk to an object that does something specific, but not which type of object or how it does it.
This would come in handy when passing parameters.
As for your parenthesized question "Also, how could you write a method that takes in an object that implements an Interface? Is that possible?", in C# you would simply use the interface type for the parameter type, like this:
public void DoSomethingToAnObject(IInterface whatever) { ... }
This plugs right into the "talk to an object that does something specific." The method defined above knows what to expect from the object, that it implements everything in IInterface, but it doesn't care which type of object it is, only that it adheres to the contract, which is what an interface is.
For instance, you're probably familiar with calculators and have probably used quite a few in your days, but most of the time they're all different. You, on the other hand, knows how a standard calculator should work, so you're able to use them all, even if you can't use the specific features that each calculator has that none of the other has.
This is the beauty of interfaces. You can write a piece of code, that knows that it will get objects passed to it that it can expect certain behavior from. It doesn't care one hoot what kind of object it is, only that it supports the behavior needed.
Let me give you a concrete example.
We have a custom-built translation system for windows forms. This system loops through controls on a form and translate text in each. The system knows how to handle basic controls, like the-type-of-control-that-has-a-Text-property, and similar basic stuff, but for anything basic, it falls short.
Now, since controls inherit from pre-defined classes that we have no control over, we could do one of three things:
Build support for our translation system to detect specifically which type of control it is working with, and translate the correct bits (maintenance nightmare)
Build support into base classes (impossible, since all the controls inherit from different pre-defined classes)
Add interface support
So we did nr. 3. All our controls implement ILocalizable, which is an interface that gives us one method, the ability to translate "itself" into a container of translation text/rules. As such, the form doesn't need to know which kind of control it has found, only that it implements the specific interface, and knows that there is a method where it can call to localize the control.
Code to the Interface Not the Implementation has NOTHING to do with Java, nor its Interface construct.
This concept was brought to prominence in the Patterns / Gang of Four books but was most probably around well before that. The concept certainly existed well before Java ever existed.
The Java Interface construct was created to aid in this idea (among other things), and people have become too focused on the construct as the centre of the meaning rather than the original intent. However, it is the reason we have public and private methods and attributes in Java, C++, C#, etc.
It means just interact with an object or system's public interface. Don't worry or even anticipate how it does what it does internally. Don't worry about how it is implemented. In object-oriented code, it is why we have public vs. private methods/attributes. We are intended to use the public methods because the private methods are there only for use internally, within the class. They make up the implementation of the class and can be changed as required without changing the public interface. Assume that regarding functionality, a method on a class will perform the same operation with the same expected result every time you call it with the same parameters. It allows the author to change how the class works, its implementation, without breaking how people interact with it.
And you can program to the interface, not the implementation without ever using an Interface construct. You can program to the interface not the implementation in C++, which does not have an Interface construct. You can integrate two massive enterprise systems much more robustly as long as they interact through public interfaces (contracts) rather than calling methods on objects internal to the systems. The interfaces are expected to always react the same expected way given the same input parameters; if implemented to the interface and not the implementation. The concept works in many places.
Shake the thought that Java Interfaces have anything what-so-ever to do with the concept of 'Program to the Interface, Not the Implementation'. They can help apply the concept, but they are not the concept.
It sounds like you understand how interfaces work but are unsure of when to use them and what advantages they offer. Here are a few examples of when an interface would make sense:
// if I want to add search capabilities to my application and support multiple search
// engines such as Google, Yahoo, Live, etc.
interface ISearchProvider
{
string Search(string keywords);
}
then I could create GoogleSearchProvider, YahooSearchProvider, LiveSearchProvider, etc.
// if I want to support multiple downloads using different protocols
// HTTP, HTTPS, FTP, FTPS, etc.
interface IUrlDownload
{
void Download(string url)
}
// how about an image loader for different kinds of images JPG, GIF, PNG, etc.
interface IImageLoader
{
Bitmap LoadImage(string filename)
}
then create JpegImageLoader, GifImageLoader, PngImageLoader, etc.
Most add-ins and plugin systems work off interfaces.
Another popular use is for the Repository pattern. Say I want to load a list of zip codes from different sources
interface IZipCodeRepository
{
IList<ZipCode> GetZipCodes(string state);
}
then I could create an XMLZipCodeRepository, SQLZipCodeRepository, CSVZipCodeRepository, etc. For my web applications, I often create XML repositories early on so I can get something up and running before the SQL Database is ready. Once the database is ready I write an SQLRepository to replace the XML version. The rest of my code remains unchanged since it runs solely off of interfaces.
Methods can accept interfaces such as:
PrintZipCodes(IZipCodeRepository zipCodeRepository, string state)
{
foreach (ZipCode zipCode in zipCodeRepository.GetZipCodes(state))
{
Console.WriteLine(zipCode.ToString());
}
}
It makes your code a lot more extensible and easier to maintain when you have sets of similar classes. I am a junior programmer, so I am no expert, but I just finished a project that required something similar.
I work on client side software that talks to a server running a medical device. We are developing a new version of this device that has some new components that the customer must configure at times. There are two types of new components, and they are different, but they are also very similar. Basically, I had to create two config forms, two lists classes, two of everything.
I decided that it would be best to create an abstract base class for each control type that would hold almost all of the real logic, and then derived types to take care of the differences between the two components. However, the base classes would not have been able to perform operations on these components if I had to worry about types all of the time (well, they could have, but there would have been an "if" statement or switch in every method).
I defined a simple interface for these components and all of the base classes talk to this interface. Now when I change something, it pretty much 'just works' everywhere and I have no code duplication.
A lot of explanation out there, but to make it even more simpler. Take for instance a List. One can implement a list with as:
An internal array
A linked list
Other implementations
By building to an interface, say a List. You only code as to definition of List or what List means in reality.
You could use any type of implementation internally say an array implementation. But suppose you wish to change the implementation for some reason say a bug or performance. Then you just have to change the declaration List<String> ls = new ArrayList<String>() to List<String> ls = new LinkedList<String>().
Nowhere else in code, will you have to change anything else; Because everything else was built on the definition of List.
If you program in Java, JDBC is a good example. JDBC defines a set of interfaces but says nothing about the implementation. Your applications can be written against this set of interfaces. In theory, you pick some JDBC driver and your application would just work. If you discover there's a faster or "better" or cheaper JDBC driver or for whatever reason, you can again in theory re-configure your property file, and without having to make any change in your application, your application would still work.
I am a late comer to this question, but I want to mention here that the line "Program to an interface, not an implementation" had some good discussion in the GoF (Gang of Four) Design Patterns book.
It stated, on p. 18:
Program to an interface, not an implementation
Don't declare variables to be instances of particular concrete classes. Instead, commit only to an interface defined by an abstract class. You will find this to be a common theme of the design patterns in this book.
and above that, it began with:
There are two benefits to manipulating objects solely in terms of the interface defined by abstract classes:
Clients remain unaware of the specific types of objects they use, as long as the objects adhere to the interface that clients expect.
Clients remain unaware of the classes that implement these objects. Clients only know about the abstract class(es) defining the interface.
So in other words, don't write it your classes so that it has a quack() method for ducks, and then a bark() method for dogs, because they are too specific for a particular implementation of a class (or subclass). Instead, write the method using names that are general enough to be used in the base class, such as giveSound() or move(), so that they can be used for ducks, dogs, or even cars, and then the client of your classes can just say .giveSound() rather than thinking about whether to use quack() or bark() or even determine the type before issuing the correct message to be sent to the object.
Programming to Interfaces is awesome, it promotes loose coupling. As #lassevk mentioned, Inversion of Control is a great use of this.
In addition, look into SOLID principals. here is a video series
It goes through a hard coded (strongly coupled example) then looks at interfaces, finally progressing to a IoC/DI tool (NInject)
To add to the existing posts, sometimes coding to interfaces helps on large projects when developers work on separate components simultaneously. All you need is to define interfaces upfront and write code to them while other developers write code to the interface you are implementing.
It can be advantageous to program to interfaces, even when we are not depending on abstractions.
Programming to interfaces forces us to use a contextually appropriate subset of an object. That helps because it:
prevents us from doing contextually inappropriate things, and
lets us safely change the implementation in the future.
For example, consider a Person class that implements the Friend and the Employee interface.
class Person implements AbstractEmployee, AbstractFriend {
}
In the context of the person's birthday, we program to the Friend interface, to prevent treating the person like an Employee.
function party() {
const friend: Friend = new Person("Kathryn");
friend.HaveFun();
}
In the context of the person's work, we program to the Employee interface, to prevent blurring workplace boundaries.
function workplace() {
const employee: Employee = new Person("Kathryn");
employee.DoWork();
}
Great. We have behaved appropriately in different contexts, and our software is working well.
Far into the future, if our business changes to work with dogs, we can change the software fairly easily. First, we create a Dog class that implements both Friend and Employee. Then, we safely change new Person() to new Dog(). Even if both functions have thousands of lines of code, that simple edit will work because we know the following are true:
Function party uses only the Friend subset of Person.
Function workplace uses only the Employee subset of Person.
Class Dog implements both the Friend and Employee interfaces.
On the other hand, if either party or workplace were to have programmed against Person, there would be a risk of both having Person-specific code. Changing from Person to Dog would require us to comb through the code to extirpate any Person-specific code that Dog does not support.
The moral: programming to interfaces helps our code to behave appropriately and to be ready for change. It also prepares our code to depend on abstractions, which brings even more advantages.
If I'm writing a new class Swimmer to add the functionality swim() and need to use an object of class say Dog, and this Dog class implements interface Animal which declares swim().
At the top of the hierarchy (Animal), it's very abstract while at the bottom (Dog) it's very concrete. The way I think about "programming to interfaces" is that, as I write Swimmer class, I want to write my code against the interface that's as far up that hierarchy which in this case is an Animal object. An interface is free from implementation details and thus makes your code loosely-coupled.
The implementation details can be changed with time, however, it would not affect the remaining code since all you are interacting with is with the interface and not the implementation. You don't care what the implementation is like... all you know is that there will be a class that would implement the interface.
It is also good for Unit Testing, you can inject your own classes (that meet the requirements of the interface) into a class that depends on it
Short story: A postman is asked to go home after home and receive the covers contains (letters, documents, cheques, gift cards, application, love letter) with the address written on it to deliver.
Suppose there is no cover and ask the postman to go home after home and receive all the things and deliver to other people, the postman can get confused.
So better wrap it with cover (in our story it is the interface) then he will do his job fine.
Now the postman's job is to receive and deliver the covers only (he wouldn't bothered what is inside in the cover).
Create a type of interface not actual type, but implement it with actual type.
To create to interface means your components get Fit into the rest of code easily
I give you an example.
you have the AirPlane interface as below.
interface Airplane{
parkPlane();
servicePlane();
}
Suppose you have methods in your Controller class of Planes like
parkPlane(Airplane plane)
and
servicePlane(Airplane plane)
implemented in your program. It will not BREAK your code.
I mean, it need not to change as long as it accepts arguments as AirPlane.
Because it will accept any Airplane despite actual type, flyer, highflyr, fighter, etc.
Also, in a collection:
List<Airplane> plane; // Will take all your planes.
The following example will clear your understanding.
You have a fighter plane that implements it, so
public class Fighter implements Airplane {
public void parkPlane(){
// Specific implementations for fighter plane to park
}
public void servicePlane(){
// Specific implementatoins for fighter plane to service.
}
}
The same thing for HighFlyer and other clasess:
public class HighFlyer implements Airplane {
public void parkPlane(){
// Specific implementations for HighFlyer plane to park
}
public void servicePlane(){
// specific implementatoins for HighFlyer plane to service.
}
}
Now think your controller classes using AirPlane several times,
Suppose your Controller class is ControlPlane like below,
public Class ControlPlane{
AirPlane plane;
// so much method with AirPlane reference are used here...
}
Here magic comes as you may make your new AirPlane type instances as many as you want and you are not changing the code of ControlPlane class.
You can add an instance...
JumboJetPlane // implementing AirPlane interface.
AirBus // implementing AirPlane interface.
You may remove instances of previously created types too.
So, just to get this right, the advantage of a interface is that I can separate the calling of a method from any particular class. Instead creating a instance of the interface, where the implementation is given from whichever class I choose that implements that interface. Thus allowing me to have many classes, which have similar but slightly different functionality and in some cases (the cases related to the intention of the interface) not care which object it is.
For example, I could have a movement interface. A method which makes something 'move' and any object (Person, Car, Cat) that implements the movement interface could be passed in and told to move. Without the method every knowing the type of class it is.
Imagine you have a product called 'Zebra' that can be extended by plugins. It finds the plugins by searching for DLLs in some directory. It loads all those DLLs and uses reflection to find any classes that implement IZebraPlugin, and then calls the methods of that interface to communicate with the plugins.
This makes it completely independent of any specific plugin class - it doesn't care what the classes are. It only cares that they fulfill the interface specification.
Interfaces are a way of defining points of extensibility like this. Code that talks to an interface is more loosely coupled - in fact it is not coupled at all to any other specific code. It can inter-operate with plugins written years later by people who have never met the original developer.
You could instead use a base class with virtual functions - all plugins would be derived from the base class. But this is much more limiting because a class can only have one base class, whereas it can implement any number of interfaces.
C++ explanation.
Think of an interface as your classes public methods.
You then could create a template that 'depends' on these public methods in order to carry out it's own function (it makes function calls defined in the classes public interface). Lets say this template is a container, like a Vector class, and the interface it depends on is a search algorithm.
Any algorithm class that defines the functions/interface Vector makes calls to will satisfy the 'contract' (as someone explained in the original reply). The algorithms don't even need to be of the same base class; the only requirement is that the functions/methods that the Vector depends on (interface) is defined in your algorithm.
The point of all of this is that you could supply any different search algorithm/class just as long as it supplied the interface that Vector depends on (bubble search, sequential search, quick search).
You might also want to design other containers (lists, queues) that would harness the same search algorithm as Vector by having them fulfill the interface/contract that your search algorithms depends on.
This saves time (OOP principle 'code reuse') as you are able to write an algorithm once instead of again and again and again specific to every new object you create without over-complicating the issue with an overgrown inheritance tree.
As for 'missing out' on how things operate; big-time (at least in C++), as this is how most of the Standard TEMPLATE Library's framework operates.
Of course when using inheritance and abstract classes the methodology of programming to an interface changes; but the principle is the same, your public functions/methods are your classes interface.
This is a huge topic and one of the the cornerstone principles of Design Patterns.
In Java these concrete classes all implement the CharSequence interface:
CharBuffer, String, StringBuffer, StringBuilder
These concrete classes do not have a common parent class other than Object, so there is nothing that relates them, other than the fact they each have something to do with arrays of characters, representing such, or manipulating such. For instance, the characters of String cannot be changed once a String object is instantiated, whereas the characters of StringBuffer or StringBuilder can be edited.
Yet each one of these classes is capable of suitably implementing the CharSequence interface methods:
char charAt(int index)
int length()
CharSequence subSequence(int start, int end)
String toString()
In some cases, Java class library classes that used to accept String have been revised to now accept the CharSequence interface. So if you have an instance of StringBuilder, instead of extracting a String object (which means instantiating a new object instance), it can instead just pass the StringBuilder itself as it implements the CharSequence interface.
The Appendable interface that some classes implement has much the same kind of benefit for any situation where characters can be appended to an instance of the underlying concrete class object instance. All of these concrete classes implement the Appendable interface:
BufferedWriter, CharArrayWriter, CharBuffer, FileWriter, FilterWriter, LogStream, OutputStreamWriter, PipedWriter, PrintStream, PrintWriter, StringBuffer, StringBuilder, StringWriter, Writer
Previous answers focus on programming to an abstraction for the sake of extensibility and loose coupling. While these are very important points,
readability is equally important. Readability allows others (and your future self) to understand the code with minimal effort. This is why readability leverages abstractions.
An abstraction is, by definition, simpler than its implementation. An abstraction omits detail in order to convey the essence or purpose of a thing, but nothing more.
Because abstractions are simpler, I can fit a lot more of them in my head at one time, compared to implementations.
As a programmer (in any language) I walk around with a general idea of a List in my head at all times. In particular, a List allows random access, duplicate elements, and maintains order. When I see a declaration like this: List myList = new ArrayList() I think, cool, this is a List that's being used in the (basic) way that I understand; and I don't have to think any more about it.
On the other hand, I do not carry around the specific implementation details of ArrayList in my head. So when I see, ArrayList myList = new ArrayList(). I think, uh-oh, this ArrayList must be used in a way that isn't covered by the List interface. Now I have to track down all the usages of this ArrayList to understand why, because otherwise I won't be able to fully understand this code. It gets even more confusing when I discover that 100% of the usages of this ArrayList do conform to the List interface. Then I'm left wondering... was there some code relying on ArrayList implementation details that got deleted? Was the programmer who instantiated it just incompetent? Is this application locked into that specific implementation in some way at runtime? A way that I don't understand?
I'm now confused and uncertain about this application, and all we're talking about is a simple List. What if this was a complex business object ignoring its interface? Then my knowledge of the business domain is insufficient to understand the purpose of the code.
So even when I need a List strictly within a private method (nothing that would break other applications if it changed, and I could easily find/replace every usage in my IDE) it still benefits readability to program to an abstraction. Because abstractions are simpler than implementation details. You could say that programming to abstractions is one way of adhering to the KISS principle.
An interface is like a contract, where you want your implementation class to implement methods written in the contract (interface). Since Java does not provide multiple inheritance, "programming to interface" is a good way to achieve multiple inheritance.
If you have a class A that is already extending some other class B, but you want that class A to also follow certain guidelines or implement a certain contract, then you can do so by the "programming to interface" strategy.
Q: - ... "Could you use any class that implements an interface?"
A: - Yes.
Q: - ... "When would you need to do that?"
A: - Each time you need a class(es) that implements interface(s).
Note: We couldn't instantiate an interface not implemented by a class - True.
Why?
Because the interface has only method prototypes, not definitions (just functions names, not their logic)
AnIntf anInst = new Aclass();
// we could do this only if Aclass implements AnIntf.
// anInst will have Aclass reference.
Note: Now we could understand what happened if Bclass and Cclass implemented same Dintf.
Dintf bInst = new Bclass();
// now we could call all Dintf functions implemented (defined) in Bclass.
Dintf cInst = new Cclass();
// now we could call all Dintf functions implemented (defined) in Cclass.
What we have: Same interface prototypes (functions names in interface), and call different implementations.
Bibliography:
Prototypes - wikipedia
program to an interface is a term from the GOF book. i would not directly say it has to do with java interface but rather real interfaces. to achieve clean layer separation, you need to create some separation between systems for example: Let's say you had a concrete database you want to use, you would never "program to the database" , instead you would "program to the storage interface". Likewise you would never "program to a Web Service" but rather you would program to a "client interface". this is so you can easily swap things out.
i find these rules help me:
1. we use a java interface when we have multiple types of an object. if i just have single object, i dont see the point. if there are at least two concrete implementations of some idea, then i would use a java interface.
2. if as i stated above, you want to bring decoupling from an external system (storage system) to your own system (local DB) then also use a interface.
notice how there are two ways to consider when to use them.
Coding to an interface is a philosophy, rather than specific language constructs or design patterns - it instructs you what is the correct order of steps to follow in order to create better software systems (e.g. more resilient, more testable, more scalable, more extendible, and other nice traits).
What it actually means is:
===
Before jumping to implementations and coding (the HOW) - think of the WHAT:
What black boxes should make up your system,
What is each box' responsibility,
What are the ways each "client" (that is, one of those other boxes, 3rd party "boxes", or even humans) should communicate with it (the API of each box).
After you figure the above, go ahead and implement those boxes (the HOW).
Thinking first of what a box' is and what its API, leads the developer to distil the box' responsibility, and to mark for himself and future developers the difference between what is its exposed details ("API") and it's hidden details ("implementation details"), which is a very important differentiation to have.
One immediate and easily noticeable gain is the team can then change and improve implementations without affecting the general architecture. It also makes the system MUCH more testable (it goes well with the TDD approach).
===
Beyond the traits I've mentioned above, you also save A LOT OF TIME going this direction.
Micro Services and DDD, when done right, are great examples of "Coding to an interface", however the concept wins in every pattern from monoliths to "serverless", from BE to FE, from OOP to functional, etc....
I strongly recommend this approach for Software Engineering (and I basically believe it makes total sense in other fields as well).
Program to an interface allows to change implementation of contract defined by interface seamlessly. It allows loose coupling between contract and specific implementations.
IInterface classRef = new ObjectWhatever()
You could use any class that implements IInterface? When would you need to do that?
Have a look at this SE question for good example.
Why should the interface for a Java class be preferred?
does using an Interface hit performance?
if so how much?
Yes. It will have slight performance overhead in sub-seconds. But if your application has requirement to change the implementation of interface dynamically, don't worry about performance impact.
how can you avoid it without having to maintain two bits of code?
Don't try to avoid multiple implementations of interface if your application need them. In absence of tight coupling of interface with one specific implementation, you may have to deploy the patch to change one implementation to other implementation.
One good use case: Implementation of Strategy pattern:
Real World Example of the Strategy Pattern
"Program to interface" means don't provide hard code right the way, meaning your code should be extended without breaking the previous functionality. Just extensions, not editing the previous code.
Also I see a lot of good and explanatory answers here, so I want to give my point of view here, including some extra information what I noticed when using this method.
Unit testing
For the last two years, I have written a hobby project and I did not write unit tests for it. After writing about 50K lines I found out it would be really necessary to write unit tests.
I did not use interfaces (or very sparingly) ... and when I made my first unit test, I found out it was complicated. Why?
Because I had to make a lot of class instances, used for input as class variables and/or parameters. So the tests look more like integration tests (having to make a complete 'framework' of classes since all was tied together).
Fear of interfaces
So I decided to use interfaces. My fear was that I had to implement all functionality everywhere (in all used classes) multiple times. In some way this is true, however, by using inheritance it can be reduced a lot.
Combination of interfaces and inheritance
I found out the combination is very good to be used. I give a very simple example.
public interface IPricable
{
int Price { get; }
}
public interface ICar : IPricable
public abstract class Article
{
public int Price { get { return ... } }
}
public class Car : Article, ICar
{
// Price does not need to be defined here
}
This way copying code is not necessary, while still having the benefit of using a car as interface (ICar).
In interviews I have been asked to explain the difference between abstraction and encapsulation. My answer has been along the lines of
Abstraction allows us to represent complex real world in simplest manner. It is the process of identifying the relevant qualities and behaviors an object should possess; in other words, to represent the necessary feature without representing the background details.
Encapsulation is a process of hiding all the internal details of an object from the outside real world. The word "encapsulation", is like "enclosing" into a "capsule". It restricts clients from seeing its internal view where the behavior of the abstraction is implemented.
I think with above answer the interviewer was convinced, but then I was asked, if the purpose of both is hiding, then why there is a need to use encapsulation. At that time I didn't have a good answer for this.
What should I have added to make my answer more complete?
Abstraction has to do with separating interface from implementation. (We don't care what it is, we care that it works a certain way.)
Encapsulation has to do with disallowing access to or knowledge of internal structures of an implementation. (We don't care or need to see how it works, only that it does.)
Some people do use encapsulation as a synonym for abstraction, which is (IMO) incorrect. It's possible that your interviewer thought this. If that is the case then you were each talking about two different things when you referred to "encapsulation."
It's worth noting that these concepts are represented differently in different programming languages. A few examples:
In Java and C#, interfaces (and, to some degree, abstract classes) provide abstraction, while access modifiers provide encapsulation.
It's mostly the same deal in C++, except that we don't have interfaces, we only have abstract classes.
In JavaScript, duck typing provides abstraction, and closure provides encapsulation. (Naming convention can also provide encapsulation, but this only works if all parties agree to follow it.)
Its Simple!
Take example of television - it is Encapsulation, because:
Television is loaded with different functionalies that i don't know because they are completely hidden.
Hidden things like music, video etc everything bundled in a capsule that what we call a TV
Now, Abstraction is When we know a little about something and which can help us to manipulate something for which we don't know how it works internally.
For eg:
A remote-control for TV is abstraction, because
With remote we know that pressing the number keys will change the channels. We are not aware as to what actually happens internally. We can manipulate the hidden thing but we don't know how it is being done internally.
Programmatically, when we can acess the hidden data somehow and know something.. is Abstraction .. And when we know nothing about the internals its Encapsulation.
Without remote we can't change anything on TV we have to see what it shows coz all controls are hidden.
Abstraction
Exposing the Entity instead of the details of the entity.
"Details are there, but we do not consider them. They are not required."
Example 1:
Various calculations:
Addition, Multiplication, Subtraction, Division, Square, Sin, Cos, Tan.
We do not show the details of how do we calculate the Sin, Cos or Tan. We just Show Calculator and it's various Methods which will be, and which needs to be used by the user.
Example 2:
Employee has:
First Name, Last Name, Middle Name. He can Login(), Logout(), DoWork().
Many processes might be happening for Logging employee In, such as connecting to database, sending Employee ID and Password, receiving reply from Database. Although above details are present, we will hide the details and expose only "Employee".
Encapsulation
Enclosing. Treating multiple characteristics/ functions as one unit instead of individuals.
So that outside world will refer to that unit instead of it's details directly.
"Details are there, we consider them, but do not show them, instead we show what you need to see."
Example 1:
Instead of calling it as Addition, Subtraction, Multiplication, Division, Now we will call it as a Calculator.
Example 2:
All characteristics and operations are now referred by the employee, such as "John". John Has name. John Can DoWork(). John can Login().
Hiding
Hiding the implemention from outside world.
So that outside world will not see what should not be seen.
"Details are there, we consider them, but we do not show them. You do not need to see them."
Example 1:
Your requirement: Addition, Substraction, Multiplication, Division. You will be able to see it and get the result.
You do not need to know where operands are getting stored. Its not your requirement.
Also, every instruction that I am executing, is also not your requirement.
Example 2:
John Would like to know his percentage of attendance. So GetAttendancePercentage() Will be called.
However, this method needs data saved in database. Hence it will call FetchDataFromDB(). FetchDataFromDB() is NOT required to be visible to outside world.
Hence we will hide it. However, John.GetAttendancePercentage() will be visible to outside world.
Abstraction, encapsulation and hiding complement each others.
Because we create level of abstraction over details, the details are encapsulated. And because they are enclosed, they are hidden.
Difference between Abstraction and Encapsulation :-
Abstraction
Abstraction solves the problem in the design level.
Abstraction is used for hiding the unwanted data and giving relevant data.
Abstraction lets you focus on what the object does instead of how it does it.
Abstraction- Outer layout, used in terms of design.
For Example:-
Outer Look of a Mobile Phone, like it has a display screen and keypad buttons to dial a number.
Encapsulation
Encapsulation solves the problem in the implementation level.
Encapsulation means hiding the code and data into a single unit to protect the data from outside world.
Encapsulation means hiding the internal details or mechanics of how an object does something.
Encapsulation- Inner layout, used in terms of implementation.
For Example:- Inner Implementation detail of a Mobile Phone, how keypad button and Display Screen are connect with each other using circuits.
Encapsulation
Encapsulation from what you have learnt googling around, is a concept of combining the related data and operations in a single capsule or what we could say a class in OOP, such that no other program can modify the data it holds or method implementation it has, at a particular instance of time. Only the getter and setter methods can provide access to the instance variables.
Our code might be used by others and future up-gradations or bug fixes are liable. Encapsulation is something that makes sure that whatever code changes we do in our code doesn't break the code of others who are using it.
Encapsulation adds up to the maintainability, flexibility and extensibility of the code.
Encapsulation helps hide the implementation behind an interface.
Abstraction
Abstraction is the process of actually hiding the implementation behind an interface. So we are just aware of the actual behavior but not how exactly the think works out internally. The most common example could the scenario where put a key inside the lock and easily unlock it. So the interface here is the keyhole, while we are not aware of how the levers inside the lock co-ordinate among themselves to get the lock unlocked.
To be more clear, abstraction can be explained as the capability to use the same interface for different objects. Different implementations of the same interface can exist, while the details of every implementation are hidden by encapsulation.
Finally, the statement to answer all the confusions until now -
The part that is hidden relates to encapsulation while the part that is exposed relates to abstraction.
Read more on this here
Abstraction : Abstraction is process in which you collect or gather relevant data and remove non-relevant data. (And if you have achieved abstraction, then encapsulation also achieved.)
Encapsulation: Encapsulation is a process in which you wrap of functions and members in a single unit. Means You are hiding the implementation detail. Means user can access by making object of class, he/she can't see detail.
Example:
public class Test
{
int t;
string s;
public void show()
{
s = "Testing";
Console.WriteLine(s);
Console.WriteLine(See()); // No error
}
int See()
{
t = 10;
return t;
}
public static void Main()
{
Test obj = new Test();
obj.Show(); // there is no error
obj.See(); // Error:- Inaccessible due to its protection level
}
}
In the above example, User can access only Show() method by using obj, that is Abstraction.
And See() method is calling internally in Show() method that is encapsulation, because user doesn't know what things are going on in Show() method.
I know there are lot's of answers before me with variety of examples.
Well here is my opinion abstraction is getting interested from reality .
In abstraction we hide something to reduce the complexity of it
and In encapsulation we hide something to protect the data.
So we define encapsulation as wrapping of data and methods in single entity referred as class.
In java we achieve encapsulation using getters and setters not just by wrapping data and methods in it. we also define a way to access that data.
and while accessing data we protect it also. Techinical e.g would be to define a private data variable call weight.Now we know that weight can't be zero or less than zero in real world scenario. Imagine if there are no getters and setters someone could have easily set it to a negative value being public member of class.
Now final difference using one real world example,
Consider a circuit board consisting of switches and buttons.
We wrap all the wires into a a circuit box, so that we can protect someone by not getting in contact directly(encapsulation).
We don't care how those wires are connected to each other we just want an interface to turn on and off switch. That interface is provided by buttons(abstraction)
Encapsulation : Suppose I have some confidential documents, now I hide these documents inside a locker so no one can gain access to them, this is encapsulation.
Abstraction : A huge incident took place which was summarised in the newspaper. Now the newspaper only listed the more important details of the actual incident, this is abstraction. Further the headline of the incident highlights on even more specific details in a single line, hence providing higher level of abstraction on the incident. Also highlights of a football/cricket match can be considered as abstraction of the entire match.
Hence encapsulation is hiding of data to protect its integrity and abstraction is highlighting more important details.
In programming terms we can see that a variable may be enclosed is the scope of a class as private hence preventing it from being accessed directly from outside, this is encapsulation. Whereas a a function may be written in a class to swap two numbers. Now the numbers may be swapped in either by either using a temporary variable or through bit manipulation or using arithmetic operation, but the goal of the user is to receive the numbers swapped irrespective of the method used for swapping, this is abstraction.
Abstraction: In case of an hardware abstraction layer, you have simple interfaces to trigger the hardware (e.g. turn enginge left/right) without knowing the hardware details behind. So hiding the complexity of the system. It's a simplified view of the real world.
Encapsulation: Hiding of object internals. The object is an abstraction of the real world. But the details of this object (like data structures...) can be hidden via encapsulation.
Abstraction refers to the act of representing essential features without including the background details or explanations.
Encapsulation is a technique used for hiding the properties and behaviors of an object and allowing outside access only as appropriate. It prevents other objects from directly altering or accessing the properties or methods of the encapsulated object.
Difference between abstraction and encapsulation
1.Abstraction focuses on the outside view of an object (i.e. the interface) Encapsulation (information hiding) prevents clients from seeing it’s inside view, where the behavior of the abstraction is implemented.
2.Abstraction solves the problem in the design side while Encapsulation is the Implementation.
3.Encapsulation is the deliverable of Abstraction. Encapsulation barely talks about grouping up your abstraction to suit the developer needs.
ABSTRACTION:"A view of a problem that extracts the essential information
relevant to a particular purpose and ignores the remainder of
the information."[IEEE, 1983]
ENCAPSULATION: "Encapsulation or equivalently information hiding refers to the
practice of including within an object everything it needs, and
furthermore doing this in such a way that no other object need ever
be aware of this internal structure."
Abstraction is one of the many benefits of Data Encapsulation. We can also say Data Encapsulation is one way to implement Abstraction.
My opinion of abstraction is not in the sense of hiding implementation or background details!
Abstraction gives us the benefit to deal with a representation of the real world which is easier to handle, has the ability to be reused, could be combined with other components of our more or less complex program package. So we have to find out how we pick a complete peace of the real world, which is complete enough to represent the sense of our algorithm and data. The implementation of the interface may hide the details but this is not part of the work we have to do for abstracting something.
For me most important thing for abstraction is:
reduction of complexity
reduction of size/quantity
splitting of non related domains to clear and independent components
All this has for me nothing to do with hiding background details!
If you think of sorting some data, abstraction can result in:
a sorting algorithm, which is independent of the data representation
a compare function, which is independent of data and sort algorithm
a generic data representation, which is independent of the used algorithms
All these has nothing to do with hiding information.
In my view encapsulation is a thought of programmer to hide the complexity of the program code by using access specifier.
Where as Abstraction is separation of method and object according to there function and behavior. For example Car has sheets, wheels, break, headlight.
Developer A, who is inherently utilising the concept of abstraction will use a module/library function/widget, concerned only with what it does (and what it will be used for) but not how it does it. The interface of that module/library function/widget (the 'levers' the Developer A is allowed to pull/push) is the personification of that abstraction.
Developer B, who is seeking to create such a module/function/widget will utilise the concept of encapsulation to ensure Developer A (and any other developer who uses the widget) can take advantage of the resulting abstraction. Developer B is most certainly concerned with how the widget does what it does.
TLDR;
Abstraction - I care about what something does, but not how it does it.
Encapsulation - I care about how something does what it does such that others only need to care about what it does.
(As a loose generalisation, to abstract something, you must encapsulate something else. And by encapsulating something, you have created an abstraction.)
Encapsulation is basically denying the access to the internal implementation or knowledge about internals to the external world, while Abstraction is giving a generalized view of any implementation that helps the external world to interact with it
The essential thing about abstraction is that client code operates in terms of a different logical/abstract model. That different model may be more or less complex than the implementation happens to be in any given client usage.
For example, "Iterator" abstracts (aka generalises) sequenced traversal of 0 or more values - in C++ it manifests as begin(), */-> (dereferencing), end(), pre/post ++ and possibly --, then there's +, +=, [], std::advance etc.. That's a lot of baggage if the client could say increment a size_t along an array anyway. The essential thing is that the abstraction allows client code that needs to perform such a traversal to be decoupled from the exact nature of the "container" or data source providing the elements. Iteration is a higher-level notion that sometimes restricts the way the traversal is performed (e.g. a forward iterator can only advance an element at a time), but the data can then be provided by a larger set of sources (e.g. from a keyboard where there's not even a "container" in the sense of concurrently stored values). The client code can generally switch to another data source abstracted through its own iterators with minimal or even no changes, and even polymorphically to other data types - either implicitly or explicitly using something like std::iterator_traits<Iterator>::value_type available.
This is quite a different thing from encapsulation, which is the practice of making some data or functions less accessible, such that you know they're only used indirectly as a result of operations on the public interface. Encapsulation is an essential tool for maintaining invariants on an object, which means things you want to keep true after every public operation - if client code could just reach in and modify your object then you can't enforce any invariants. For example, a class might wrap a string, ensuring that after any operation any lowercase letters were changed to upper case, but if the client code can reach in and put a lowercase letter into the string without the involvement of the class's member functions, then the invariant can't be enforced.
To further highlight the difference, consider say a private std::vector<Timing_Sample> data member that's incidentally populated by operations on the containing object, with a report dumped out on destruction. With the data and destructor side effect not interacting with the object's client code in any way, and the operations on the object not intentionally controlling the time-keeping behaviour, there's no abstraction of that time reporting functionality but there is encapsulation. An example of abstraction would be to move the timing code into a separate class that might encapsulate the vector (make it private) and just provide a interface like add(const Timing_Sample&) and report(std::ostream&) - the necessary logical/abstract operations involved with using such instrumentation, with the highly desirable side effect that the abstracted code will often be reusable for other client code with similar functional needs.
In my opinion, both terms are related in some sense and sort of mixed into each other. "Encapsulation" provides a way to grouping related fields, methods in a class (or module) to wrap the related things together. As of that time, it provides data hiding in two ways;
Through access modifiers.
Purely for hiding state of the class/object.
Abstracting some functionalities.
a. Through interfaces/abstract classes, complex logic inside the encapsulated class or module can be abstracted/generalized to be used by outside.
b. Through function signatures. Yes, even function signatures example of abstracting. Because callers only knows the signature and parameters (if any) and know nothing about how the function is carried out. It only cares of returned value.
Likewise, "Abstraction" might be think of a way of encapsulation in terms of grouping/wrapping the behaviour into an interface (or abstract class or might be even a normal class ).
As far as iOS is concerned, it can be said that Objective C files (i.e. .h and .m) use abstraction as well as encapsulation.
Abstraction
Header file (.h) only exposes the functions and public members to outside world. No one knows how they are used unless they have the implementation file with them. It is the .m file that holds all the usage and implementation logic with it self. "Implementation remains unexposed".
Encapsulation
The property (#property) encapsulates the memory management attribute (atomic, strong, retain, weak) of an iVar.
A program has mainly two parts : DATA and PROCESS. abstraction hides data in process so that no one can change. Encapsulation hides data everywhere so that it cannot be displayed.
I hope this clarifies your doubt.
Encapsulation is used for 2 main reasons:
1.) Data hiding & protecting (the user of your class can't modify the data except through your provided methods).
2.) Combining the data and methods used to manipulate the data together into one entity (capsule).
I think that the second reason is the answer your interviewer wanted to hear.
On the other hand, abstraction is needed to expose only the needed information to the user, and hiding unneeded details (for example, hiding the implementation of methods, so that the user is not affected if the implementation is changed).
Abstraction: Hiding the data.
Encapsulation: Binding the data.
Why Encapsulation? Why Abstraction?
lets start with the question below:
1)What happens if we allow code to directly access field ? (directly allowing means making field public)
lets understand this with an example,
following is our BankAccount class and following is its limitation
*Limitation/Policy* : Balance in BankAccount can not be more than 50000Rs. (This line
is very important to understand)
class BankAccount
{
**public** double balanceAmount;
}
Following is **AccountHolder**(user of BankAccount) class which is consumer of
**BankAccount** class.
class AccountHolder
{
BankAccount mybankAccount = new BankAccount();
DoAmountCreditInBankAccount()
{
mybankAccount.balanceAmount = 70000;
/*
this is invalid practice because this statement violates policy....Here
BankAccount class is not able to protect its field from direct access
Reason for direct access by acount holder is that balanceAmount directly
accessible due to its public access modifier. How to solve this issue and
successfully implement BankAccount Policy/Limitation.
*/
}
}
if some other part of code directly access balanceAmount field and set balance amount to 70000Rs which is not acceptable. Here in this case we can not prevent some other part of code from accessing balanceAmount field.
So what we can do?
=> Answer is we can make balanceAmount field private so that no other code can directly access it and allowing access to that field only via public method which operates on balanceAmount field. Main role of method is that we can write some prevention logic inside method so that field can not be initialized with more than 50000Rs. Here we are making binding between data field called balanceAmount and method which operates on that field. This process is called Encapsulation.(it is all about protecting fields using access modifier such as private)
Encapsulation is one way to achieve abstraction....but How?
=> User of this method will not know about implementation (How amount gets credited? logic and all that stuff) of method which he/she will invoke. Not knowing about implementation details by user is called Abstraction(Hiding details from user).
Following will be the implementation of class:
class BankAccount
{
**private** double balanceAmount;
**public** void UpdateBankBalance(double amount)
{
if(balanceAmount + amount > 50000)
{
Console.WriteLine("Bank balance can not be more than 50000, Transaction can
not be proceed");
}
else
{
balanceAmount = balanceAmount + amount;
Console.WriteLine("Amount has been credited to your bank account
successfully.....");
}
}
}
class AccountHolder
{
BankAccount mybankAccount = new BankAccount();
DoAmountCreditInBankAccount()
{
mybankAccount.UpdateBankBalance(some_amount);
/*
mybankAccount.balanceAmount will not be accessible due to its protection level
directly from AccountHolder so account holder will consume BankAccount public
method UpdateBankBalance(double amount) to update his/her balance.
*/
}
}
Simply put, abstraction is all about making necessary information for interaction with the object visible, while encapsulation enables a developer to implement the desired level of abstraction.
Encapsulation: Hiding the information at the implementation level. This deals with properties or methods which will be hidden from other objects.
Abstraction: Hiding the information at the idea level/design level. Here we decide that something will be abstract(hidden) from the user while thinking of an idea. Abstraction can be achieved using encapsulation at the implementation level.
I have a data class which encapsulates relevant data items in it. Those data items are set and get by users one by one when needed.
My confusion about the design has to do with which object should be responsible for handling the update of multiple properties of that data object. Sometimes an update operation will be performed which affects many properties at once.
So, which class should have the update() method?. Is it the data class itself or another manager class ? The update() method requires data exchange with many different objects, so I don't want to make it a member of the data class because I believe it should know nothing about the other objects required for update. I want the data class to be only a data-structure. Am I thinking wrong? What would be the right approach?
My code:
class RefData
{
Matrix mX;
Vector mV;
int mA;
bool mB;
getX();
setB();
update(); // which affects almost any member attributes in the class, but requires many relations with many different classes, which makes this class dependant on them.
}
or,
class RefDataUpdater
{
update(RefData*); // something like this ?
}
There is this really great section in the book Clean Code, by Robert C. Martin, that speaks directly to this issue.
And the answer is it depends. It depends on what you are trying to accomplish in your design--and
if you might have more than one data-object that exhibit similar behaviors.
First, your data class could be considered a Data Transfer Object (DTO). As such, its ideal form is simply a class without any public methods--only public properties -- basically a data structure. It will not encapsulate any behavior, it simply groups together related data. Since other objects manipulate these data objects, if you were to add a property to the data object, you'd need to change all the other objects that have functions that now need to access that new property. However, on the flip side, if you added a new function to a manager class, you need to make zero changes to the data object class.
So, I think often you want to think about how many data objects might have an update function that relates directly to the properties of that class. If you have 5 classes that contain 3-4 properties but all have an update function, then I'd lean toward having the update function be part of the "data-class" (which is more of an OO-design). But, if you have one data-class in which it is likely to have properties added to it in the future, then I'd lean toward the DTO design (object as a data structure)--which is more procedural (requiring other functions to manipulate it) but still can be part of an otherwise Object Oriented architecture.
All this being said, as Robert Martin points out in the book:
There are ways around this that are well known to experienced
object-oriented designers: VISITOR, or dual-dispatch, for example.
But these techniques carry costs of their own and generally return the
structure to that of a procedural program.
Now, in the code you show, you have properties with types of Vector, and Matrix, which are probably more complex types than a simple DTO would contain, so you may want to think about what those represent and whether they could be moved to separate classes--with different functions to manipulate--as you typically would not expose a Matrix or a Vector directly as a property, but encapsulate them.
As already written, it depends, but I'd probably go with an external support class that handles the update.
For once, I'd like to know why you'd use such a method? I believe it's safe to assume that the class doesn't only call setter methods for a list of parameters it receives, but I'll consider this case as well
1) the trivial updater method
In this case I mean something like this:
public update(a, b, c)
{
setA(a);
setB(b);
setC(c);
}
In this case I'd probably not use such a method at all, I'd either define a macro for it or I'd call the setter themselves. But if it must be a method, then I'd place it inside the data class.
2) the complex updater method
The method in this case doesn't only contain calls to setters, but it also contains logic. If the logic is some sort of simple property update logic I'd try to put that logic inside the setters (that's what they are for in the first place), but if the logic involves multiple properties I'd put this logic inside an external supporting class (or a business logic class if any appropriate already there) since it's not a great idea having logic reside inside data classes.
Developing clear code that can be easily understood is very important and it's my belief that by putting logic of any kind (except for say setter logic) inside data classes won't help you achieving that.
Edit
I just though I'd add something else. Where to put such methods also depend upon your class and what purpose it fulfills. If we're talking for instance about Business/Domain Object classes, and we're not using an Anemic Domain Model these classes are allowed (and should contain) behavior/logic.
On the other hand, if this data class is say an Entity (persistence objects) which is not used in the Domain Model as well (complex Domain Model) I would strongly advice against placing logic inside them. The same goes for data classes which "feel" like pure data objects (more like structs), don't pollute them, keep the logic outside.
I guess like everywhere in software, there's no silver bullet and the right answer is: it depends (upon the classes, what this update method is doing, what's the architecture behind the application and other application specific considerations).
What is the precise difference between encapsulation and abstraction?
Most answers here focus on OOP but encapsulation begins much earlier:
Every function is an encapsulation; in pseudocode:
point x = { 1, 4 }
point y = { 23, 42 }
numeric d = distance(x, y)
Here, distance encapsulates the calculation of the (Euclidean) distance between two points in a plane: it hides implementation details. This is encapsulation, pure and simple.
Abstraction is the process of generalisation: taking a concrete implementation and making it applicable to different, albeit somewhat related, types of data. The classical example of abstraction is C’s qsort function to sort data:
The thing about qsort is that it doesn't care about the data it sorts — in fact, it doesn’t know what data it sorts. Rather, its input type is a typeless pointer (void*) which is just C’s way of saying “I don't care about the type of data” (this is also called type erasure). The important point is that the implementation of qsort always stays the same, regardless of data type. The only thing that has to change is the compare function, which differs from data type to data type. qsort therefore expects the user to provide said compare function as a function argument.
Encapsulation and abstraction go hand in hand so much so that you could make the point that they are truly inseparable. For practical purposes, this is probably true; that said, here’s an encapsulation that’s not much of an abstraction:
class point {
numeric x
numeric y
}
We encapsulate the point’s coordinate, but we don’t materially abstract them away, beyond grouping them logically.
And here’s an example of abstraction that’s not encapsulation:
T pi<T> = 3.1415926535
This is a generic variable pi with a given value (π), and the declaration doesn’t care about the exact type of the variable. Admittedly, I’d be hard-pressed to find something like this in real code: abstraction virtually always uses encapsulation. However, the above does actually exist in C++(14), via variable templates (= generic templates for variables); with a slightly more complex syntax, e.g.:
template <typename T> constexpr T pi = T{3.1415926535};
Many answers and their examples are misleading.
Encapsulation is the packing of "data" and "functions operating on that data" into a single component and restricting the access to some of the object's components.
Encapsulation means that the internal representation of an object is generally hidden from view outside of the object's definition.
Abstraction is a mechanism which represent the essential features without including implementation details.
Encapsulation:-- Information hiding.
Abstraction:-- Implementation hiding.
Example (in C++):
class foo{
private:
int a, b;
public:
foo(int x=0, int y=0): a(x), b(y) {}
int add(){
return a+b;
}
}
Internal representation of any object of foo class is hidden outside of this class. --> Encapsulation.
Any accessible member (data/function) of an object of foo is restricted and can only be accessed by that object only.
foo foo_obj(3, 4);
int sum = foo_obj.add();
Implementation of method add is hidden. --> Abstraction.
Encapsulation is hiding the implementation details which may or may not be for generic or specialized behavior(s).
Abstraction is providing a generalization (say, over a set of behaviors).
Here's a good read: Abstraction, Encapsulation, and Information Hiding by Edward V. Berard of the Object Agency.
encapsulation puts some things in a box and gives you a peephole; this keeps you from mucking with the gears.
abstraction flat-out ignores the details that don't matter, like whether the things have gears, ratchets, flywheels, or nuclear cores; they just "go"
examples of encapsulation:
underpants
toolbox
wallet
handbag
capsule
frozen carbonite
a box, with or without a button on it
a burrito (technically, the tortilla around the burrito)
examples of abstraction:
"groups of things" is an abstraction (which we call aggregation)
"things that contains other things" is an abstraction (which we call composition)
"container" is another kind of "things that contain other things" abstraction; note that all of the encapsulation examples are kinds of containers, but not all containers exhibit/provide encapsulation. A basket, for example, is a container that does not encapsulate its contents.
Encapsulation means-hiding data like using getter and setter etc.
Abstraction means- hiding implementation using abstract class and interfaces etc.
Abstraction is generalized term. i.e. Encapsulation is subset of Abstraction.
Abstraction
Encapsulation
It solves an issue at the design level.
Encapsulation solves an issue at implementation level.
hides the unnecessary detail but shows the essential information.
It hides the code and data into a single entity or unit so that the data can be protected from the outside world.
Focuses on the external lookout.
Focuses on internal working.
Lets focus on what an object does instead of how it does it.
Lets focus on how an object does something.
Example: Outer look of mobile, like it has a display screen and buttons.
Example: Inner details of mobile, how button and display screen connect with each other using circuits.
Example: The solution architect is the person who creates the high-level abstract technical design of the entire solution, and this design is then handed over to the the development team for implementation.
Here, solution architect acts as a abstract and development team acts as a Encapsulation.
Example: Encapsulation(networking) of user data
image courtesy
Abstraction (or modularity) – Types enable programmers to think at a higher level than the bit or byte, not bothering with low-level implementation. For example, programmers can begin to think of a string as a set of character values instead of as a mere array of bytes. Higher still, types enable programmers to think about and express interfaces between two of any-sized subsystems. This enables more levels of localization so that the definitions required for interoperability of the subsystems remain consistent when those two subsystems communicate.
Source
Java example
A lot of good answers are provided above but I am going to present my(Java) viewpoint here.
Data Encapsulation simply means wrapping and controlling access of logically grouped data in a class. It is generally associated with another keyword - Data Hiding. This is achieved in Java using access modifiers.
A simple example would be defining a private variable and giving access to it using getter and setter methods or making a method private as it's only use is withing the class. There is no need for user to know about these methods and variables.
Note : It should not be misunderstood that encapsulation is all about data hiding only. When we say encapsulation, emphasis should be on grouping or packaging or bundling related data and behavior together.
Data Abstraction on the other hand is concept of generalizing so that the underneath complex logic is not exposed to the user. In Java this is achieved by using interfaces and abstract classes.
Example -
Lets say we have an interface Animal and it has a function makeSound(). There are two concrete classes Dog and Cat that implement this interface. These concrete classes have separate implementations of makeSound() function. Now lets say we have a animal(We get this from some external module). All user knows is that the object that it is receiving is some Animal and it is the users responsibility to print the animal sound. One brute force way is to check the object received to identify it's type, then typecast it to that Animal type and then call makeSound() on it. But a neater way is to abstracts thing out. Use Animal as a polymorphic reference and call makeSound() on it. At runtime depending on what the real Object type is proper function will be invoked.
More details here.
Complex logic is in the circuit board which is encapsulated in a touchpad and a nice interface(buttons) is provided to abstract it out to the user.
PS: Above links are to my personal blog.
These are somewhat fuzzy concepts that are not unique to Computer Science and programming. I would like to offer up some additional thoughts that may help others understand these important concepts.
Short Answer
Encapsulation - Hiding and/or restricting access to certain parts of a system, while exposing the necessary interfaces.
Abstraction - Considering something with certain characteristics removed, apart from concrete realities, specific objects, or actual instances, thereby reducing complexity.
The main similarity is that these techniques aim to improve comprehension and utility.
The main difference is that abstraction is a means of representing things more simply (often to make the representation more widely applicable), whereas encapsulation is a method of changing the way other things interact with something.
Long Answer
Encapsulation
Here's an example of encapsulation that hopefully makes things more clear:
Here we have an Arduino Uno, and an Arduino Uno within an enclosure. An enclosure is a great representation of what encapsulation is all about.
Encapsulation aims to protect certain components from outside influences and knowledge as well as expose components which other things should interface with. In programming terms, this involves information hiding though access modifiers, which change the extent to which certain variables and/or properties can be read and written.
But beyond that, encapsulation also aims to provide those external interfaces much more effectively. With our Arduino example, this could include the nice buttons and screen which makes the user's interaction with the device much simpler. They provide the user with simple ways to affect the device's behavior and gain useful information about its operation which would otherwise be much more difficult.
In programming, this involves the grouping of various components into a separable construct, such as a function, class, or object. It also includes providing the means of interacting with those constructs, as well as methods for gaining useful information about them.
Encapsulation helps programmers in many many additional ways, not least of which is improved code maintainability and testability.
Abstraction
Although many other answers here defined abstraction as generalization, I personally think that definition is misguided. I would say that generalization is actually a specific type of abstraction, not the other way around. In other words, all generalizations are abstractions, but all abstractions are not necessarily generalizations.
Here's how I like to think of abstraction:
Would you say the image there is a tree? Chances are you would. But is it really a tree? Well, of course not! It's a bunch of pixels made to look like something we might call a tree. We could say that it represents an abstraction of a real tree. Notice that several visual details of the tree are omitted. Also, it does not grow, consume water, or produce oxygen. How could it? it's just a bunch of colors on a screen, represented by bytes in your computer memory.
And here is the essence of abstraction. It's a way of simplifying things so they are easier to understand. Every idea going through your head is an abstraction of reality. Your mental image of a tree is no more an actual tree than this jpeg is.
In programming, we might use this to our advantage by creating a Tree class with methods for simulated growing, water consuming, and oxygen production. Our creation would be something that represents our experience of actual trees, and only includes those elements that we really care about for our particular simulation. We use abstraction as a way of representing our experience of something with bytes and mathematics.
Abstract Classes
Abstraction in programming also allows us to consider commonalities between several "concrete" object types (types that actually exist) and define those commonalities within a unique entity. For example, our Tree class may inherit from an abstract class Plant, which has several properties and methods which are applicable to all of our plant-like classes, but removes those that are specific to each type of plant. This can significantly reduce duplication of code, and improves maintainability.
The practical difference of an abstract class and plain class is that conceptually there's no "real" instances of the abstract class. It wouldn't make sense to construct a Plant object because that's not specific enough. Every "real" Plant is also a more specific type of Plant.
Also, if we want our program to be more realistic, we might want to consider the fact that our Tree class might be too abstract itself. In reality, every Tree is a more specific type of Tree, so we could create classes for those types such as Birch, Maple, etc. which inherit from our, perhaps now abstract, Tree class.
JVM
Another good example of abstraction is the Java Virtual Machine (JVM), which provides a virtual or abstract computer for Java code to run on. It essentially takes away all of the platform specific components of a system, and provides an abstract interface of "computer" without regard to any system in particular.
The Difference
Encapsulation differs from abstraction in that it doesn't have anything to do with how 'real' or 'accurate' something is. It doesn't remove components of something to make it simpler or more widely applicable. Rather it may hide certain components to achieve a similar purpose.
Abstraction lets you focus on what the object does instead of how it does it
Encapsulation means hiding the internal details or mechanics of how an object does something.
Like when you drive a car, you know what the gas pedal does but you may not know the process behind it because it is encapsulated.
Let me give an example in C#. Suppose you have an integer:
int Number = 5;
string aStrNumber = Number.ToString();
you can use a method like Number.ToString() which returns you characters representation of the number 5, and stores that in a string object. The method tells you what it does instead of how it does it.
Encapsulation: Is hiding unwanted/un-expected/propriety implementation details from the actual users of object.
e.g.
List<string> list = new List<string>();
list.Sort(); /* Here, which sorting algorithm is used and hows its
implemented is not useful to the user who wants to perform sort, that's
why its hidden from the user of list. */
Abstraction: Is a way of providing generalization and hence a common way to work with objects of vast diversity. e.g.
class Aeroplane : IFlyable, IFuelable, IMachine
{ // Aeroplane's Design says:
// Aeroplane is a flying object
// Aeroplane can be fueled
// Aeroplane is a Machine
}
// But the code related to Pilot, or Driver of Aeroplane is not bothered
// about Machine or Fuel. Hence,
// pilot code:
IFlyable flyingObj = new Aeroplane();
flyingObj.Fly();
// fighter Pilot related code
IFlyable flyingObj2 = new FighterAeroplane();
flyingObj2.Fly();
// UFO related code
IFlyable ufoObj = new UFO();
ufoObj.Fly();
// **All the 3 Above codes are genaralized using IFlyable,
// Interface Abstraction**
// Fly related code knows how to fly, irrespective of the type of
// flying object they are.
// Similarly, Fuel related code:
// Fueling an Aeroplane
IFuelable fuelableObj = new Aeroplane();
fuelableObj.FillFuel();
// Fueling a Car
IFuelable fuelableObj2 = new Car(); // class Car : IFuelable { }
fuelableObj2.FillFuel();
// ** Fueling code does not need know what kind of vehicle it is, so far
// as it can Fill Fuel**
Difference Between Abstraction and Encapsulation.
Abstraction: The idea of presenting something in a simplified / different way, which is either easier to understand and use or more pertinent to the situation.
Consider a class that sends an email... it uses abstraction to show itself to you as some kind of messenger boy, so you can call emailSender.send(mail, recipient). What it actually does - chooses POP3 / SMTP, calling servers, MIME translation, etc, is abstracted away. You only see your messenger boy.
Encapsulation: The idea of securing and hiding data and methods that are private to an object. It deals more with making something independent and foolproof.
Take me, for instance. I encapsulate my heart rate from the rest of the world. Because I don't want anyone else changing that variable, and I don't need anyone else to set it in order for me to function. Its vitally important to me, but you don't need to know what it is, and you probably don't care anyway.
Look around you'll find that almost everything you touch is an example of both abstraction and encapsulation. Your phone, for instance presents to you the abstraction of being able to take what you say and say it to someone else - covering up GSM, processor architecture, radio frequencies, and a million other things you don't understand or care to. It also encapsulates certain data from you, like serial numbers, ID numbers, frequencies, etc.
It all makes the world a nicer place to live in :D
Abstraction: Only necessary information is shown. Let's focus on the example of switching on a computer. The user does not have to know what goes on while the system is still loading (that information is hidden from the user).
Let's take another example, that of the ATM. The customer does not need to know how the machine reads the PIN and processes the transaction, all he needs to do is enter the PIN, take the cash and leave.
Encapsulation: Deals with hiding the sensitive data of a clas hence privatising part of it. It is a way of keeping some information private to its clients by allowing no access to it from outside.
Another example:
Suppose I created an immutable Rectangle class like this:
class Rectangle {
public:
Rectangle(int width, int height) : width_(width), height_(height) {}
int width() const { return width_; }
int height() const { return height_; }
private:
int width_;
int height_;
}
Now it's obvious that I've encapsulated width and height (access is somehow restricted), but I've not abstracted anything (okay, maybe I've ignored where the rectangle is located in the coordinates space, but this is a flaw of the example).
Good abstraction usually implies good encapsulation.
An example of good abstraction is a generic database connection class. Its public interface is database-agnostic, and is very simple, yet allows me to do what I want with the connection. And you see? There's also encapsulation there, because the class must have all the low-level handles and calls inside.
A mechanism that prevents the data of a particular objects safe from intentional or accidental misuse by external functions is called "data Encapsulation"
The act of representing essential features without including the background details or explanations is known as abstraction
Abstraction and Encapsulation by using a single generalized example
------------------------------------------------------------------------------------------------------------------------------------
We all use calculator for calculation of complex problems !
Abstraction : Abstraction means to show What part of functionality.
Encapsulation : Encapsulation means to hide the How part of the functionality.
Lets take a very simple example
/// <summary>
/// We have an Employee class having two properties EmployeeName and EmployeeCode
/// </summary>
public class Employee
{
public string EmplpyeeName { get; set; }
public string EmployeeCode { get; set; }
// Add new employee to DB is the main functionality, so are making it public so that we can expose it to external environment
// This is ABSTRACTION
public void AddEmployee(Employee obj)
{
// "Creation of DB connection" and "To check if employee exists" are internal details which we have hide from external environment
// You can see that these methods are private, external environment just need "What" part only
CreateDBConnection();
CheckIfEmployeeExists();
}
// ENCAPLUSATION using private keyword
private bool CheckIfEmployeeExists()
{
// Here we can validate if the employee already exists
return true;
}
// ENCAPLUSATION using private keyword
private void CreateDBConnection()
{
// Create DB connection code
}
}
Program class of Console Application
class Program
{
static void Main(string[] args)
{
Employee obj = new Employee();
obj.EmplpyeeName = "001";
obj.EmployeeCode = "Raj";
// We have exposed only what part of the functionality
obj.AddEmployee(obj);
}
}
Let's take the example of a stack. It could be implemented using an array or a linked list. But the operations it supports are push and pop.
Now abstraction is exposing only the interfaces push and pop. The underlying representation is hidden (is it an array or a linked list?) and a well-defined interface is provided. Now how do you ensure that no accidental access is made to the abstracted data? That is where encapsulation comes in. For example, classes in C++ use the access specifiers which ensure that accidental access and modification is prevented. And also, by making the above-mentioned interfaces as public, it ensures that the only way to manipulate the stack is through the well-defined interface. In the process, it has coupled the data and the code that can manipulate it (let's not get the friend functions involved here). That is, the code and data are bonded together or tied or encapsulated.
Encapsulation is wrapping up complexity in one capsule that is class & hence Encapsulation…
While abstraction is the characteristics of an object which differentiates from other object...
Abstraction can be achieved by making class abstract having one or more methods abstract. Which is nothing but the characteristic which should be implemented by the class extending it.
e.g. when you inventing/designing a car you define a characteristics like car should have 4 doors, break, steering wheel etc… so anyone uses this design should include this characteristics. Implementation is not the head each of abstraction. It will just define characteristics which should be included.
Encapsulation is achieved keeping data and the behaviour in one capsule that is class & by making use of access modifiers like public, private, protected along with inheritance, aggregation or composition. So you only show only required things, that too, only to the extent you want to show. i.e. public, protected, friendly & private ka funda……
e.g. GM decides to use the abstracted design of car above. But they have various products having the same characteristics & doing almost same functionality. So they write a class which extends the above abstract class. It says how gear box should work, how break should work, how steering wheel should work. Then all the products just use this common functionality. They need not know how the gear box works or break works or steering wheal works. Indivisual product can surely have more features like a/c or auto lock etc…..
Both are powerful; but using abstraction require more skills than encapsulation and bigger applications/products can not survive with out abstraction.
I will try to demonstrate Encapsulation in a simple way.. Lets see..
The wrapping up of data and functions into a single unit (called
class) is known as encapsulation. Encapsulation containing and hiding
information about an object, such as internal data structures and
code.
Encapsulation is -
Hiding Complexity,
Binding Data and Function together,
Making Complicated Method's Private,
Making Instance Variable's Private,
Hiding Unnecessary Data and Functions from End User.
Encapsulation implements Abstraction.
And Abstraction is -
Showing Whats Necessary,
Data needs to abstract from End User,
Lets see an example-
The below Image shows a GUI of "Customer Details to be ADD-ed into a Database".
By looking at the Image we can say that we need a Customer Class.
Step - 1: What does my Customer Class needs?
i.e.
2 variables to store Customer Code and Customer Name.
1 Function to Add the Customer Code and Customer Name into Database.
namespace CustomerContent
{
public class Customer
{
public string CustomerCode = "";
public string CustomerName = "";
public void ADD()
{
//my DB code will go here
}
Now only ADD method wont work here alone.
Step -2: How will the validation work, ADD Function act?
We will need Database Connection code and Validation Code (Extra Methods).
public bool Validate()
{
//Granular Customer Code and Name
return true;
}
public bool CreateDBObject()
{
//DB Connection Code
return true;
}
class Program
{
static void main(String[] args)
{
CustomerComponent.Customer obj = new CustomerComponent.Customer;
obj.CustomerCode = "s001";
obj.CustomerName = "Mac";
obj.Validate();
obj.CreateDBObject();
obj.ADD();
}
}
Now there is no need of showing the Extra Methods(Validate(); CreateDBObject() [Complicated and Extra method] ) to the End User.End user only needs to see and know about Customer Code, Customer Name and ADD button which will ADD the record.. End User doesn't care about HOW it will ADD the Data to Database?.
Step -3: Private the extra and complicated methods which doesn't involves End User's Interaction.
So making those Complicated and Extra method as Private instead Public(i.e Hiding those methods) and deleting the obj.Validate(); obj.CreateDBObject(); from main in class Program we achieve Encapsulation.
In other words Simplifying Interface to End User is Encapsulation.
So now the code looks like as below -
namespace CustomerContent
{
public class Customer
{
public string CustomerCode = "";
public string CustomerName = "";
public void ADD()
{
//my DB code will go here
}
private bool Validate()
{
//Granular Customer Code and Name
return true;
}
private bool CreateDBObject()
{
//DB Connection Code
return true;
}
class Program
{
static void main(String[] args)
{
CustomerComponent.Customer obj = new CustomerComponent.Customer;
obj.CustomerCode = "s001";
obj.CustomerName = "Mac";
obj.ADD();
}
}
Summary :
Step -1: What does my Customer Class needs? is Abstraction.
Step -3: Step -3: Private the extra and complicated methods which doesn't involves End User's Interaction is Encapsulation.
P.S. - The code above is hard and fast.
Abstraction--- Hiding Implementation--at Design---Using Interface/Abstract calsses
Encapsulation--Hiding Data --At Development---Using access modifiers(public/private)
From this
Difference between Encapsulation and Abstraction in OOPS
Abstraction and Encapsulation are two important Object Oriented Programming (OOPS) concepts. Encapsulation and Abstraction both are interrelated terms.
Real Life Difference Between Encapsulation and Abstraction
Encapsulate means to hide. Encapsulation is also called data hiding.You can think Encapsulation like a capsule (medicine tablet) which hides medicine inside it. Encapsulation is wrapping, just hiding properties and methods. Encapsulation is used for hide the code and data in a single unit to protect the data from the outside the world. Class is the best example of encapsulation.
Abstraction refers to showing only the necessary details to the intended user. As the name suggests, abstraction is the "abstract form of anything". We use abstraction in programming languages to make abstract class. Abstract class represents abstract view of methods and properties of class.
Implementation Difference Between Encapsulation and Abstraction
Abstraction is implemented using interface and abstract class while Encapsulation is implemented using private and protected access modifier.
OOPS makes use of encapsulation to enforce the integrity of a type (i.e. to make sure data is used in an appropriate manner) by preventing programmers from accessing data in a non-intended manner. Through encapsulation, only a predetermined group of functions can access the data. The collective term for datatypes and operations (methods) bundled together with access restrictions (public/private, etc.) is a class.
The below paragraph helped me to understand how they differ from each other:
Data encapsulation is a mechanism of bundling the data, and the
functions that use them and data abstraction is a mechanism of
exposing only the interfaces and hiding the implementation details
from the user.
You can read more here.
Information hiding is not strictly required for abstraction or encapsulation. Information might be ignored, but does not have to be hidden.
Encapsulation is the ability to treat something as a single thing, even though it may be composed of many complex parts or ideas. For example, I can say that I'm sitting in a "chair" rather than referring to the many various parts of that chair each with a specific design and function, all fitting together precisely for the purpose of comfortably holding my butt a few feet away from the floor.
Abstraction is enabled by encapsulation. Because we encapsulate objects, we can think about them as things which relate to each other in some way rather than getting bogged down in the subtle details of internal object structure. Abstraction is the ability to consider the bigger picture, removed from concern over little details. The root of the word is abstract as in the summary that appears at the top of a scholarly paper, not abstract as in a class which can only be instantiated as a derived subclass.
I can honestly say that when I plop my butt down in my chair, I never think about how the structure of that chair will catch and hold my weight. It's a decent enough chair that I don't have to worry about those details. So I can turn my attention toward my computer. And again, I don't think about the component parts of my computer. I'm just looking at a part of a webpage that represents a text area that I can type in, and I'm communicating in words, barely even thinking about how my fingers always find the right letters so quickly on the keyboard, and how the connection is ultimately made between tapping these keys and posting to this forum. This is the great power of abstraction. Because the lower levels of the system can be trusted to work with consistency and precision, we have attention to spare for greater work.
The more I read, more I got confused. So, simply here is what I understood:
Encapsulation:
We generally see a watch from outside and it's components are encapsulated inside it's body. We have some kind of control for different operations. This way of hiding details and exposing control (e.g. setting time) is encapsulation.
Abstraction:
So far we were talking about a watch. But we didn't specify what kind of watch. It could be digital or analog, for hand or wall. There are many possibilities. What we do know is, it is a watch and it tells time and that is the only thing we are interested in, the time. This way of hiding details and exposing generic feature or use case is abstraction.
class Aeroplane : IFlyable, IFuelable, IMachine
{ // Aeroplane's Design says:
// Aeroplane is a flying object
// Aeroplane can be fueled
// Aeroplane is a Machine
}
// But the code related to Pilot, or Driver of Aeroplane is not bothered
// about Machine or Fuel. Hence,
// pilot code:
IFlyable flyingObj = new Aeroplane();
flyingObj.Fly();
// fighter Pilot related code
IFlyable flyingObj2 = new FighterAeroplane();
flyingObj2.Fly();
// UFO related code
IFlyable ufoObj = new UFO();
ufoObj.Fly();
// **All the 3 Above codes are genaralized using IFlyable,
// Interface Abstraction**
// Fly related code knows how to fly, irrespective of the type of
// flying object they are.
// Similarly, Fuel related code:
// Fueling an Aeroplane
IFuelable fuelableObj = new Aeroplane();
fuelableObj.FillFuel();
// Fueling a Car
IFuelable fuelableObj2 = new Car(); // class Car : IFuelable { }
fuelableObj2.FillFuel();
// ** Fueling code does not need know what kind of vehicle it is, so far
// as it can Fill Fuel**
abstraction is hiding non useful data from users
and encapsulation is bind together data into a capsule (a class).
I think encapsulation is way that we achieve abstraction.
The process of Abstraction and Encapsulation both generate interfaces.
An interface generated via encapsulation hides implementation details.
An interface generated via abstraction becomes applicable to more data types, compared to before abstraction.
Abstraction is a contract for the implementation we are going to do. Implementation may get changed over period of time. The various implementations themselves may or may not be hidden but are Masked behind the Abstraction.
Suppose we define all the APIs of a class in an interface then ask the users of our code to depened upon the defined APIs of the interface. We are free to improve or modify the implementation only we must follow the set contract. The users are not coupled with our implementation.
We EXPOSE all the NECESSARY Rules (methods) in abstraction, the implementation of the rules are left for the implementor entities, also the implemention is not part of the abstraction. Its just the signature and declaration what makes the abstraction.
Encapsulation is simply HIDING the internal details by reducing the acess of the states and behaviors. An encapsulated class may or may not have well defined Abstraction.
java.util.List is an abstraction for java.util.ArrayList. The internal states of java.util.ArrayList being marked with non public access modifiers is encapsulation.
Edit
Suppose a class Container.nava implements IContainer , IContainer may declare methods like addElement, removeElements, contains, etc. Here IContainer represents the abstraction for its implementing class. Abstraction is declaring the APIs of the class or a module or a system to the outer world. These APIs become the contract.
That system may be or may not be developed yet. The users of the system now can depend on the declared APIs and are sure any system implementing such a contract will always adhere to the APIs declared, they will always provide tge implementation for those APIs. Once we are writing some concrete entity then deciding to hide our internal states is encapsulation
I Think Encapsulation is a way to implement abstraction. Have a look at the following link.
Abstraction and Encapsulation
As it currently stands, this question is not a good fit for our Q&A format. We expect answers to be supported by facts, references, or expertise, but this question will likely solicit debate, arguments, polling, or extended discussion. If you feel that this question can be improved and possibly reopened, visit the help center for guidance.
Closed 11 years ago.
I understand that they force you to implement methods and such but what I cant understand is why you would want to use them. Can anybody give me a good example or explanation on why I would want to implement this.
One specific example: interfaces are a good way of specifying a contract that other people's code must meet.
If I'm writing a library of code, I may write code that is valid for objects that have a certain set of behaviours. The best solution is to specify those behaviours in an interface (no implementation, just a description) and then use references to objects implementing that interface in my library code.
Then any random person can come along, create a class that implements that interface, instantiate an object of that class and pass it to my library code and expect it to work. Note: it is of course possible to strictly implement an interface while ignoring the intention of the interface, so merely implementing an interface is no guarantee that things will work. Stupid always finds a way! :-)
Another specific example: two teams working on different components that must co-operate. If the two teams sit down on day 1 and agree on a set of interfaces, then they can go their separate ways and implement their components around those interfaces. Team A can build test harnesses that simulate the component from Team B for testing, and vice versa. Parallel development, and fewer bugs.
The key point is that interfaces provide a layer of abstraction so that you can write code that is ignorant of unnecessary details.
The canonical example used in most textbooks is that of sorting routines. You can sort any class of objects so long as you have a way of comparing any two of the objects. You can make any class sortable therefore by implementing the IComparable interface, which forces you to implement a method for comparing two instances. All of the sort routines are written to handle references to IComparable objects, so as soon as you implement IComparable you can use any of those sort routines on collections of objects of your class.
The easiest way of understanding interfaces is that they allow different objects to expose COMMON functionality. This allows the programmer to write much simplier, shorter code that programs to an interface, then as long as the objects implement that interface it will work.
Example 1:
There are many different database providers, MySQL, MSSQL, Oracle, etc. However all database objects can DO the same things so you will find many interfaces for database objects. If an object implements IDBConnection then it exposes the methods Open() and Close(). So if I want my program to be database provider agnostic, I program to the interface and not to the specific providers.
IDbConnection connection = GetDatabaseConnectionFromConfig()
connection.Open()
// do stuff
connection.Close()
See by programming to an interface (IDbconnection) I can now SWAP out any data provider in my config but my code stays the exact same. This flexibility can be extremely useful and easy to maintain. The downside to this is that I can only perform 'generic' database operations and may not fully utilize the strength that each particular provider offers so as with everything in programming you have a trade off and you must determine which scenario will benefit you the most.
Example 2:
If you notice almost all collections implement this interface called IEnumerable. IEnumerable returns an IEnumerator which has MoveNext(), Current, and Reset(). This allows C# to easily move through your collection. The reason it can do this is since it exposes the IEnumerable interface it KNOWS that the object exposes the methods it needs to go through it. This does two things. 1) foreach loops will now know how to enumerate the collection and 2) you can now apply powerful LINQ exprssions to your collection. Again the reason why interfaces are so useful here is because all collections have something in COMMON, they can be moved through. Each collection may be moved through a different way (linked list vs array) but that is the beauty of interfaces is that the implementation is hidden and irrelevant to the consumer of the interface. MoveNext() gives you the next item in the collection, it doesn't matter HOW it does it. Pretty nice, huh?
Example 3:
When you are designing your own interfaces you just have to ask yourself one question. What do these things have in common? Once you find all the things that the objects share, you abstract those properties/methods into an interface so that each object can inherit from it. Then you can program against several objects using one interface.
And of course I have to give my favorite C++ polymorphic example, the animals example. All animals share certain characteristics. Lets say they can Move, Speak, and they all have a Name. Since I just identified what all my animals have in common and I can abstract those qualities into the IAnimal interface. Then I create a Bear object, an Owl object, and a Snake object all implementing this interface. The reason why you can store different objects together that implement the same interface is because interfaces represent an IS-A replationship. A bear IS-A animal, an owl IS-A animal, so it makes since that I can collect them all as Animals.
var animals = new IAnimal[] = {new Bear(), new Owl(), new Snake()} // here I can collect different objects in a single collection because they inherit from the same interface
foreach (IAnimal animal in animals)
{
Console.WriteLine(animal.Name)
animal.Speak() // a bear growls, a owl hoots, and a snake hisses
animal.Move() // bear runs, owl flys, snake slithers
}
You can see that even though these animals perform each action in a different way, I can program against them all in one unified model and this is just one of the many benefits of Interfaces.
So again the most important thing with interfaces is what do objects have in common so that you can program against DIFFERENT objects in the SAME way. Saves time, creates more flexible applications, hides complexity/implementation, models real-world objects / situations, among many other benefits.
Hope this helps.
One typical example is a plugin architecture. Developer A writes the main app, and wants to make certain that all plugins written by developer B, C and D conform to what his app expects of them.
Interfaces define contracts, and that's the key word.
You use an interface when you need to define a contract in your program but you don't really care about the rest of the properties of the class that fulfills that contract as long as it does.
So, let's see an example. Suppose you have a method which provides the functionality to sort a list. First thing .. what's a list? Do you really care what elements does it holds in order to sort the list? Your answer should be no... In .NET (for example) you have an interface called IList which defines the operations that a list MUST support so you don't care the actual details underneath the surface.
Back to the example, you don't really know the class of the objects in the list... neither you care. If you can just compare the object you might as well sort them. So you declare a contract:
interface IComparable
{
// Return -1 if this is less than CompareWith
// Return 0 if object are equal
// Return 1 if CompareWith is less than this
int Compare(object CompareWith);
}
that contract specify that a method which accepts an object and returns an int must be implemented in order to be comparable. Now you have defined an contract and for now on you don't care about the object itself but about the contract so you can just do:
IComparable comp1 = list.GetItem(i) as IComparable;
if (comp1.Compare(list.GetItem(i+1)) < 0)
swapItem(list,i, i+1)
PS: I know the examples are a bit naive but they are examples ...
When you need different classes to share same methods you use Interfaces.
Interfaces are absolutely necessary in an object-oriented system that expects to make good use of polymorphism.
A classic example might be IVehicle, which has a Move() method. You could have classes Car, Bike and Tank, which implement IVehicle. They can all Move(), and you could write code that didn't care what kind of vehicle it was dealing with, just so it can Move().
void MoveAVehicle(IVehicle vehicle)
{
vehicle.Move();
}
The pedals on a car implement an interface. I'm from the US where we drive on the right side of the road. Our steering wheels are on the left side of the car. The pedals for a manual transmission from left to right are clutch -> brake -> accelerator. When I went to Ireland, the driving is reversed. Cars' steering wheels are on the right and they drive on the left side of the road... but the pedals, ah the pedals... they implemented the same interface... all three pedals were in the same order... so even if the class was different and the network that class operated on was different, i was still comfortable with the pedal interface. My brain was able to call my muscles on this car just like every other car.
Think of the numerous non-programming interfaces we can't live without. Then answer your own question.
Imagine the following basic interface which defines a basic CRUD mechanism:
interface Storable {
function create($data);
function read($id);
function update($data, $id);
function delete($id);
}
From this interface, you can tell that any object that implements it, must have functionality to create, read, update and delete data. This could by a database connection, a CSV file reader, and XML file reader, or any other kind of mechanism that might want to use CRUD operations.
Thus, you could now have something like the following:
class Logger {
Storable storage;
function Logger(Storable storage) {
this.storage = storage;
}
function writeLogEntry() {
this.storage.create("I am a log entry");
}
}
This logger doesn't care if you pass in a database connection, or something that manipulates files on disk. All it needs to know is that it can call create() on it, and it'll work as expected.
The next question to arise from this then is, if databases and CSV files, etc, can all store data, shouldn't they be inherited from a generic Storable object and thus do away with the need for interfaces? The answer to this is no... not every database connection might implement CRUD operations, and the same applies to every file reader.
Interfaces define what the object is capable of doing and how you need to use it... not what it is!
Interfaces are a form of polymorphism. An example:
Suppose you want to write some logging code. The logging is going to go somewhere (maybe to a file, or a serial port on the device the main code runs on, or to a socket, or thrown away like /dev/null). You don't know where: the user of your logging code needs to be free to determine that. In fact, your logging code doesn't care. It just wants something it can write bytes to.
So, you invent an interface called "something you can write bytes to". The logging code is given an instance of this interface (perhaps at runtime, perhaps it's configured at compile time. It's still polymorphism, just different kinds). You write one or more classes implementing the interface, and you can easily change where logging goes just by changing which one the logging code will use. Someone else can change where logging goes by writing their own implementations of the interface, without changing your code. That's basically what polymorphism amounts to - knowing just enough about an object to use it in a particular way, while allowing it to vary in all the respects you don't need to know about. An interface describes things you need to know.
C's file descriptors are basically an interface "something I can read and/or write bytes from and/or to", and almost every typed language has such interfaces lurking in its standard libraries: streams or whatever. Untyped languages usually have informal types (perhaps called contracts) that represent streams. So in practice you almost never have to actually invent this particular interface yourself: you use what the language gives you.
Logging and streams are just one example - interfaces happen whenever you can describe in abstract terms what an object is supposed to do, but don't want to tie it down to a particular implementation/class/whatever.
There are a number of reasons to do so. When you use an interface, you're ready in the future when you need to refactor/rewrite the code. You can also provide an sort of standardized API for simple operations.
For example, if you want to write a sort algorithm like the quicksort, all you need to sort any list of objects is that you can successfuuly compare two of the objects. If you create an interface, say ISortable, than anyone who creates objects can implement the ISortable interface and they can use your sort code.
If you're writing code that uses a database storage, and you write to an storage interface, you can replace that code down the line.
Interfaces encourage looser coupling of your code so that you can have greater flexibility.
In an article in my blog I briefly describe three purposes interfaces have.
Interfaces may have different
purposes:
Provide different implementations for the same goal. The typical example
is a list, which may have different
implementations for different
performance use cases (LinkedList,
ArrayList, etc.).
Allow criteria modification. For example, a sort function may accept a
Comparable interface in order to
provide any kind of sort criteria,
based on the same algorithm.
Hide implementation details. This also makes it easier for a user to
read the comments, since in the body
of the interface there are only
methods, fields and comments, no long
chunks of code to skip.
Here's the article's full text: http://weblogs.manas.com.ar/ary/2007/11/
The best Java code I have ever seen defined almost all object references as instances of interfaces instead of instances of classes. It is a strong sign of quality code designed for flexibility and change.
As you noted, interfaces are good for when you want to force someone to make it in a certain format.
Interfaces are good when data not being in a certain format can mean making dangerous assumptions in your code.
For example, at the moment I'm writing an application that will transform data from one format in to another. I want to force them to place those fields in so I know they will exist and will have a greater chance of being properly implemented. I don't care if another version comes out and it doesn't compile for them because it's more likely that data is required anyways.
Interfaces are rarely used because of this, since usually you can make assumptions or don't really require the data to do what you need to do.
An interface, defines merely the interface. Later, you can define method (on other classes), which accepted interfaces as parameters (or more accurately, object which implement that interface). This way your method can operate on a large variety of objects, whose only commonality is that they implement that interface.
First, they give you an additional layer of abstraction. You can say "For this function, this parameter must be an object that has these methods with these parameters". And you probably want to also set the meaning of these methods, in somehow abstracted terms, yet allowing you to reason about the code. In duck-typed languages you get that for free. No need for explicit, syntax "interfaces". Yet you probably still create a set of conceptual interfaces, something like contracts (like in Design by Contract).
Furthermore, interfaces are sometimes used for less "pure" purposes. In Java, they can be used to emulate multiple inheritance. In C++, you can use them to reduce compile times.
In general, they reduce coupling in your code. That's a good thing.
Your code may also be easier to test this way.
Let's say you want to keep track of a collection of stuff. Said collections must support a bunch of things, like adding and removing items, and checking if an item is in the collection.
You could then specify an interface ICollection with the methods add(), remove() and contains().
Code that doesn't need to know what kind of collection (List, Array, Hash-table, Red-black tree, etc) could accept objects that implemented the interface and work with them without knowing their actual type.
In .Net, I create base classes and inherit from them when the classes are somehow related. For example, base class Person could be inherited by Employee and Customer. Person might have common properties like address fields, name, telephone, and so forth. Employee might have its own department property. Customer has other exclusive properties.
Since a class can only inherit from one other class in .Net, I use interfaces for additional shared functionality. Sometimes interfaces are shared by classes that are otherwise unrelated. Using an interface creates a contract that developers will know is shared by all of the other classes implementing it. I also forces those classes to implement all of its members.
In C# interfaces are also extremely useful for allowing polymorphism for classes that do not share the same base classes. Meaning, since we cannot have multiple inheritance you can use interfaces to allow different types to be used. It's also a way to allow you to expose private members for use without reflection (explicit implementation), so it can be a good way to implement functionality while keeping your object model clean.
For example:
public interface IExample
{
void Foo();
}
public class Example : IExample
{
// explicit implementation syntax
void IExample.Foo() { ... }
}
/* Usage */
Example e = new Example();
e.Foo(); // error, Foo does not exist
((IExample)e).Foo(); // success
I think you need to get a good understand of design patterns so see there power.
Check out
Head First Design Patterns