There are two common definitions of encapsulation:
A language mechanism for restricting direct access to some of the
object's components.
A language construct that facilitates the bundling of data with
the methods (or other functions) operating on that data.
Common practice is never to use public properties but use getters/setters instead. If public properties break encapsulation, why modern programming languages provide the possibility to use them?
The main reason is that public fields in older languages like Java are transparent, in the sense that an expression obj.field always gets the value of the field and does nothing else, and obj.field = value always assigns a value to the field and does nothing else. Modern languages often have mechanisms to allow these syntactical forms to be overridden, so that the syntax for field access or assignment can have user-defined behaviour. That means a class can expose a field publicly without making any guarantees about its own implementation, so that properties in these languages do not violate encapsulation. (Technically, this is the difference between a field and a property, and you should say that public fields violate encapsulation but public properties don't.)
A few other reasons:
Encapsulation is an object-oriented design principle, but most modern languages are not strictly object-oriented. Modern languages are typically multi-paradigm, and don't force the programmer to adopt a particular paradigm.
Encapsulation has benefits which should be weighed against the benefits of violating encapsulation in some circumstances. For example, Java has reflection, which absolutely violates encapsulation; but reflection is very useful for things like serialisation or object-relational mapping.
One of the main benefits of encapsulation is that by making each class responsible for preserving its own invariant, all of the code which has that responsibility is in one place and it's easier to make sure that the invariant is preserved. Exposing immutable fields doesn't violate encapsulation in this sense, because merely accessing a field can't break a class's invariant; and if literally every possible value for a field is acceptable by the invariant then arguably exposing a mutable field doesn't violate encapsulation in this sense either.
Related
I have read a definition of encapsulation which stated that "Encapsulation is the wrapping of data and functions into a single unit called class" .My question is that can we not use the term object instead of class in the definition because at last objects are created using the classes and objects only encapsulate data and functions inside them?
I don't have a problem with replacing "class" with "object" in the example sentence. It remains valid in class-based OOP languages while being more appropriate for prototype-based OOP languages. Classes are just a type system for OOP after all and not as fundamentally essential as encapsulation is.
I would, however, want to improve that sentence to make it clear that data and functions aren't "wrapped" in the same way. Data must be hidden and only be accessible to methods of an object.
The more important question to consider is why encapsulation is essential to true oop. Objects are to hide their attributes and inner workings, and present an interface for use by other objects. oop begins to break down when this encapsulation is broken. Code becomes harder to maintain if everyone has their hands on everyone else’s data. Consider setters and getters and all the ways we tend to break encapsulation. True object thinking is not primarily about classes and polymorphism. It is definitely about encapsulation and interfacing between objects.
Not every class has objects.
We can have static classes that have no objects.
If the definition were changed to use the word "object", these classes would not be covered. With "class", both static and non static classes are covered.
Even if a class is not static, it could have static data and functionality, again the term class is more appropriate.
Other classes may be abstract and therefore have no objects, they may still provide some encapsulation.
Template classes could also be though of as being capable of encapsulation even though there will be no objects of the template itself - only objects of "concrete" classes with specific types provided for the templates type parameters.
Also, the word "single" becomes a bit confusing if we apply it to objects since we can have multiple object of a class.
Cid's comment offers an additional reason for "class" over "object".
I assume you have a rough idea of what encapsulation is? So you are asking why couldn't the definition bee rephrased to
Encapsulation is the wrapping of data and functions into a single unit called an object.
Because encapsulation has nothing to do with objects at all. You can create some class called Car and it has some fields like engine, seats, steeringWheel and some methods applyBrakes, openWindow as well as some private members. Now you can say that the class encapsulates the inner workings of a car into a single unit - the Car class.
See? I didn't say anything about objects. Car objects are really just a bunch of references in memory pointing to other Engine, Seat and SteeringWheel objects.
In my opinion, "data" is the problematic term. Classes encapsulate attributes and methods that work on these attributes together. "data" suggests actual data and not meta data. That is probably why you thought of objects instead of classes.
Other than that, I would not replace class with object here, because it leaves out the important feature that all objects from one class have the same methods. With object, one could interpret that each object has its own set of functions.
The benefits of using composition over inheritance are quite well known;
What are the cases in which the opposite is preferable?
Practically, I can see the advantage of forcing a base constructor, but I would like to know other people's opinion about other cases/domains.
I believe the famous recommendation of "favor composition over inheritance" was coined in the GoF Design Patterns book.
It says (p.20):
Favor object composition over class inheritance.
Ideally, you shouldn't have to create new components to achieve reuse.
You should be able to get all the functionality you need just by
assembling existing components through object composition. But this is
rarely the case, because the set of available components is never
quite rich enough in practice. Reuse by inheritance makes it easier to
make new components that can be composed with old ones. Inheritance
and object composition thus work together.
Nevertheless, our experience is that designers overuse inheritance as
a reuse technique, and designs are often made more reusable (and
simpler) by depending more on object composition. You'll see object
composition applied again and again in the design patterns.
Notice that this statement refers to class inheritance, and must be distinguished from interface inheritance which is fine.
Dynamism
Both are ways to achieve reusability, but the advantage of composition over inheritance is dynamism. Since the composition can be changed dynamically at runtime this represents a great advantage, whereas inheritance is statically defined at compile time.
Encapsulation
Also, composition is based on using the public interfaces of the composed objects, therefore objects respect each other's public interfaces and therefore this fosters encapsulation. On the other hand, inheritance breaks encapsulation since child components typically consume a protected interface from the parent. It is a well known problem that changes in the parent class can break the child classes, the famous base class problem. Also in inheritance parent classes define the physical representation of subclasses, therefore child clases depend on parent classes to evolve.
Cohesion
Another advantage of composition is that it keeps classes focused on one task and this foster cohesion as well.
Liabilities
Evidently a problem with composition is that you will have more objects and fewer classes. That makes a little more difficult to visualize your design and how it achieves its goals. When debugging code it is harder to know what is going on unless you know what exact instance of a given composite is currently being used by an object. So composition makes designs a bit harder to understand in my opinion.
Since the advantages of composition are multiple that's why it is suggested to favor it over inheritance, but that does not mean inheritance is always bad. You can achieve a great deal when inheritance is properly used.
Interesting References
I would suggest a study of GoF Design Patterns to see good examples of both types of reusability, for instance a Strategy Pattern that uses composition vs a Template Method that uses inheritance.
Most of the patterns make a great use of interface inheritance and then object composition to achieve their goals and only a few use class inheritance as a reusability mechanism.
If you want to delve more the book Holub on Patterns, on chapter 2 has a section called Why extends is Evil that delve much more on the liabilities of class inheritance.
The book mentions three specific aspects
Losing Flexibility: The first problem is that explicit use of a concrete-class name locks you into a specific implementation, making
down-the-line changes unnecessarily difficult.
Coupling: A more important problem with implementation inheritance is coupling, the undesirable reliance of one part of a
program on another part. Global variables are the classic example of
why strong coupling is bad. If you change the type of a global
variable, for example, all the code that uses that variable—that is
coupled to the variable—can be affected, so all this code must be
examined, modified, and retested. Moreover, all the methods that use
the variable are coupled to each other through the variable. That is,
one method may incorrectly affect the behavior of another method
simply by changing the variable’s value at an awkward time. This
problem is particularly hideous in multithreaded programs.
Fragile-Base-Class Problem: In an implementation-inheritance system (one that uses extends), the derived classes are tightly
coupled to the base classes, and this close connection is undesirable.
Designers have applied the moniker “the fragile-base-class problem” to
describe this behavior. Base classes are considered “fragile” because
you can modify a base class in a seemingly safe way, but this new
behavior, when inherited by the derived classes, may cause the derived
classes to malfunction.
The only advantage of inheritance over composition that I can think of is that it can potentially save you from a lot of boiler plate method delegation.
If you truly have an is-a relationship and you simply want all the methods from a base class in your subclass, then inheritance gives you all those methods for free.
It's a complete debatable or argumentation question and broad as well.
AFAIK, when we talk about containership (or) something containing another thing we go for Composition; i.e, An entity contains another entity; which also gives a HAS A relationship. Example: EntityA has a EntityB.
See Decorator design pattern, which is based on the concept of Composition.
But when we talk about Inheritance we talk about IS A relationship. i.e, EntityA Is A EntityB (or) EntityA Is type of a EntityB
One special case when I find inheritance the best solution is when I use a runtime-generated class that need additional methods. For example (in C#):
public abstract class Rule{
/* properties here */
public Authorization Authorization { get; set; }
public abstract bool IsValid(dynamic request, User currentUser);
}
The generated template:
public class Generated_1Rule : Rule{
public override bool IsValid(dynamic request, User currentUser){
// the user script is here
}
}
Example of user script:
return Authorization.IsAuthorized("Module_ID_001", currentUser);
The benefit is that you can add functionality to the generated script “compiled-ly”, and it’s less breaking than inheriting from interface / composition since it is compiled.
I've been told recently a good practice in object oriented programming that you should always allow inheritance from your classes. I really don't think so, but I have no solid arguments on my mind.
Real-world examples of blocked inheritance:
No C++ STL class (specialized class template) allows inheritance (having non-virtual destructors).
Java has its final class modifier that applies to many standard components, like java.lang.String.
Possible reasons I think are:
Security, since subclass might have access to sensitive internals. (I don't think so -- they won't access private members.)
Performance, since a subclass could mess up our efficient implementations by overriding some of the member functions. (Children won't override non-virtual functions.)
To enforce composition over inheritance. (I fully agree. We shouldn't favor inheritance when it's not needed.)
So my question is: In what circumstances should I intentionally block inheritance?
In fact, the practice that I try to follow, and that Josh Bloch recommends, in his Effective Java book, is exactly the inverse rule of the one you've been told: Unless you have thought about inheritance, designed your class to be inherited, and documented how your class must be inherited, you should always disable inheritance.
I would recommend reading this chapter of Effective Java (you won't regret buying it), and showing it to the person who told you about this rule.
The most obvious reason to disallow inheritance is immutability. An immutable object is simple to use (only one state), can be cached, shared between many objects, and is inherently thread-safe. If the class is inheritable, anyone can extend the class and make it mutable by adding mutable attributes.
Well for starters, only disallow inheritance if you are positive that you don't want others to be extending your class. Preventing inheritance for trivial reasons (such as performance) is usually not recommended, as code reuse often outweighs the small performance gains you can achieve by marking your class final.
That being said, here are several examples when you might want to explicitly prevent inheritance:
You are writing a commercial, closed-source class, and you don't want people to be able to change the functionality down the line. This is a good reason to prevent class inheritance, as you don't want to have to give support for it later on if people have overridden your methods and/or extended your classes, and are complaining that they are getting unexpected results.
You are designing an immutable class. By marking the class final, you are preventing subclasses from compromising the immutable behavior of your class. For example, if you were allowed to subclass String, others could make their own implementations that allows Strings to be modified. Now no code that takes a type String can be certain that the object is immutable.
You want to force composition over inheritance. This is desirable when you want to avoid tight coupling between classes (i.e. you don't want groups of classes that are highly dependent on one another).
You want to encourage inlining by the compiler. Marking classes and methods as final may result in small performance gains, as it will ensure that Java doesn't have to look up the right class method to invoke for an object at runtime. Non-final methods are marked as virtual so that they can be properly extended if needed, final methods can be directly linked or compiled inline in the class. Note that the performance gain you can achieve by doing this is often insignificant (especially if your class' methods are large).
Just my 0.02 on this...
Allowing inheritance on a class allows people to deal with unforeseen issues. (ex. the monkeypatching that often occurs in RoR. It can be ugly but it's reality vs. pedantry). Having said that, I'm not a big fan of gratuitous inheritance. The relationship between base and subclasses can be brittle. Deep inheritance hierarchies are hard to grok.
One case I can think of disallowing inheritance is enforcing immutability. This is important for things like the Java String class.
I have seen many people in the Scala community advise on avoiding subtyping "like a plague". What are the various reasons against the use of subtyping? What are the alternatives?
Types determine the granularity of composition, i.e. of extensibility.
For example, an interface, e.g. Comparable, that combines (thus conflates) equality and relational operators. Thus it is impossible to compose on just one of the equality or relational interface.
In general, the substitution principle of inheritance is undecidable. Russell's paradox implies that any set that is extensible (i.e. does not enumerate the type of every possible member or subtype), can include itself, i.e. is a subtype of itself. But in order to identify (decide) what is a subtype and not itself, the invariants of itself must be completely enumerated, thus it is no longer extensible. This is the paradox that subtyped extensibility makes inheritance undecidable. This paradox must exist, else knowledge would be static and thus knowledge formation wouldn't exist.
Function composition is the surjective substitution of subtyping, because the input of a function can be substituted for its output, i.e. any where the output type is expected, the input type can be substituted, by wrapping it in the function call. But composition does not make the bijective contract of subtyping-- accessing the interface of the output of a function, does not access the input instance of the function.
Thus composition does not have to maintain the future (i.e. unbounded) invariants and thus can be both extensible and decidable. Subtyping can be MUCH more powerful where it is provably decidable, because it maintains this bijective contract, e.g. a function that sorts a immutable list of the supertype, can operate on the immutable list of the subtype.
So the conclusion is to enumerate all the invariants of each type (i.e. of its interfaces), make these types orthogonal (maximize granularity of composition), and then use function composition to accomplish extension where those invariants would not be orthogonal. Thus a subtype is appropriate only where it provably models the invariants of the supertype interface, and the additional interface(s) of the subtype are provably orthogonal to the invariants of the supertype interface. Thus the invariants of interfaces should be orthogonal.
Category theory provides rules for the model of the invariants of each subtype, i.e. of Functor, Applicative, and Monad, which preserve function composition on lifted types, i.e. see the aforementioned example of the power of subtyping for lists.
One reason is that equals() is very hard to get right when sub-typing is involved. See How to Write an Equality Method in Java. Specifically "Pitfall #4: Failing to define equals as an equivalence relation". In essence: to get equality right under sub-typing, you need a double dispatch.
I think the general context is for the lanaguage to be as "pure" as possible (ie using as much as possible pure functions), and comes from the comparison with Haskell.
From "Ruminations of a Programmer"
Scala, being a hybrid OO-FP language has to take care of issues like subtyping (which Haskell does not have).
As mentioned in this PSE answer:
no way to restrict a subtype so that it can't do more than the type it inherits from.
For example, if the base class is immutable and defines a pure method foo(...), derived classes must not be mutable or override foo() with a function that is not pure
But the actual recommendation would be to use the best solution adapted to the program you are currently developing.
Focusing on subtyping, ignoring the issues related to classes, inheritance, OOP, etc.. We have the idea subtyping represents a isa relation between types. For example, types A and B have different operations but if A isa B we then can use any of B's operations on an A.
OTOH, using another traditional relation, if C hasa B then we can reuse any of B's operations on a C. Usually languages let you write one with a nicer syntax, a.opOnB instead of a.super.opOnB as it would be in the case of composition, c.b.opOnB
The problem is that in many cases there's more than one way to relate two types. For example Real can be embedded in Complex assuming 0 on the imaginary part, but Complex can be embedded in Real by ignoring the imaginary part, so both can be seen as subtypes of the other and subtyping forces one relation to be viewed as preferred. Also, there are more possible relations (e.g. view Complex as a Real using theta component of polar representation).
In formal terminology we usually say morphism to such relations between types and there are special kinds of morphisms for relations with different properties (e.g. isomorphism, homomorphism).
In a language with subtyping usually there's much more sugar on isa relations and given many possible embeddings we tend to see unnecessary friction whenever we're using the unpreferred relation. If we bring inheritance, classes and OOP to the mix the problem becomes much more visible and messy.
My answer does not answer why it is avoided but tries to give another hint at why it can be avoided.
Using "type classes" you can add an abstraction over existing types/classes without modifying them. Inheritance is used to express that some classes are specializations of a more abstract class. But with type classes you can take any existing classes and express that they all share a common property, for example they are Comparable. And as long as you are not concerned with them being Comparable you don't even notice it. The classes don't inherit any methods from some abstract Comparable type as long as you don't use them. It's a bit like programming in dynamic languages.
Further reads:
http://blog.tmorris.net/the-power-of-type-classes-with-scala-implicit-defs/
http://debasishg.blogspot.com/2010/07/refactoring-into-scala-type-classes.html
I don't know Scala, but I think the mantra 'prefer composition over inheritance' applies for Scala exactly the way it does for every other OO programming language (and subtyping is often used with the same meaning as 'inheritance'). Here
Prefer composition over inheritance?
you will find some more information.
I think lots of Scala programmers are former Java programmers. They are used to think in term of Object Oriented subtyping and they should be able to easily find OO-like solution for most problems. But Functional Programing is a new paradigm to discover, so people ask for a different kind of solutions.
This is the best paper I have found on the subject. A motivating quote from the paper –
We argue that while some of the simpler aspects of object-oriented languages are
compatible with ML, adding a full-fledged class-based object system to ML leads to an excessively complex
type system and relatively little expressive gain
What are the different types of encapsulation?
Am I right in thinking this basically refers to central OO concepts such as Abstraction, Polymorphism and Inheritance?
My understanding of encapsulation is that it is a method of hiding data / functionality, but I never really considered Polymorphism or Inheritance a form of encapsulation, although I can see how polymorphism could be considered encapsulation as it can hide the exact type of the object you are interacting with.
So, would you say that's about it, or am I missing some core concepts?
edit I just noticed in the comments someone mentioned it could refer to private / public methods, perhaps I'm thinking in to the question too much and expecting a more complicated answer than it really is?
You're thinking too much I think.
http://en.wikipedia.org/wiki/Information_hiding
Excerpt from this article:
Information hiding in computer science is the principle of hiding of design decisions in a computer program that are most likely to change, thus protecting other parts of the program from change if the design decision is changed. The protection involves providing a stable interface which shields the remainder of the program from the implementation (the details that are most likely to change).
One common form of encapsulation is using properties to hide private data fields. An even more common form is the use of OO to encapsulate the complexity of software into well divisoned classes with roles and responsibilities. This is a key tennant of OO, as it moves from a monolithic procedural design style to a more structured style which strives to hide all irrelevant information except that which pertains to the particular task your working on.
It is my view and understanding that the term encapsulation (to encapsulate) is the art/science of capturing the essence of something for the purpose of display. In fact, by definition - to encapsulate is to package something or enclose it in another container. Therefore the term encapsulation would mean to take the essence of what you are attempting to achieve and packaging it in a useful form so that it can be reused as necessary.
So to interpret this, it would mean to package material in a form that would make it more useful later.
So really...interpret this as you see fit. I see it as taking a bunch of algorithms and utilities and creating a class structure that can be used as an API in other projects. This encapsulated code could be inherited and/or extended to make it useful for modified purposes without changing the underlying essence of the API.
Therefore, abstraction, polymorphism and inheritance aren't forms of encapsulation, but forms of extending and modifying encapsulated code.
Different forms of encapsulation would mean the modifiers on properties, methods, fields and classes - that is public, private, static, virtual (in C#). Everything else (i.e. overloads, overrides, shadows) is a modification or an extension to that encapsulation.
You may consider the modified code an encapsulation which could then be further inherited/abstracted/extended, but the package which is to be extended is the encapsulated product.
Encapsulation is defined by the International Organisation for Standardization's International Standard: "Information technology – Open Distributed Processing," ISO/IEC 10746, 1998.
It's defined in terms of more primitive definitions:
Entity: Any concrete or abstract thing of interest.
Object: A model of an entity. An object is characterised by its behaviour and,
dually, by its state.
Behaviour (of an object): A collection of actions with a set of constraints on
when they may occur.
Interface: An abstraction of the behaviour of an object that consists of a
subset of the interactions of that object together with a set of constraints
on when they may occur.
Encapsulation: the property that the information contained in an object is
accessible only through interactions at the interfaces supported by the
object.
The ISO does not define different types of encapsulation.
Other posts have mentioned information hiding. The ISO does not define encapsulation explicitly in terms of information hiding, though it does seem implicit, see "Encapsulation theory fundamentals," at http://www.edmundkirwan.com/pub/
Ed.
Encapsulation is more than simply information hiding. That is one aspect of it. It has to do with the interface to a module. An interface provides two very important functions: encapsulation and abstraction.
Abstraction is when a client of a module does not need to know more than what is in the interface.
and
Encapsulation is when a client of a module isn't able to know more than what is in the interface.
(Both definitions from Using UML by Perdita Stevens)
Since encapsulation simply refers to "information hiding" then I would imagine that a lot of things can be categorized as encapsulation. However I tend to think of encapsulation as "implementation hiding", in other words it is a tool that I use to create loose coupling between anything I write and anything client of what I have written.
So I tend to believe, pragmatically, that encapsulation is any paradigm or best-practice that allows me to present a clean, solid interface to any client.
Generally the usage of the word is pretty close to what it says. You encapsulate something when you contain it, and don't let any of the deals loose. The best way to think about it is that you are taking something and putting it into a black-box where no one can see the details anymore. The box hides everything, providing some other disassociated interface in its place.
Information hiding is just one aspect of encapsulation, since along with the data you can also hide any of the details of the code itself. The purpose of encapsulating a part of your system is to draw that bit of complexity away from the whole, thus making it easier to understand the separate details (on both sides). More?
Paul.
"Candidate Definitions for Encapsulation:
Physically grouping together related operations or things.
GateKeeper of state or data.
Hiding implementation."
Sourced from: Encapsulation Definition
There are two parts/ways to achieve Encapsulation:
First, encapsulation is a technique that packages related data and behaviors into a single unit, i.e, Physical grouping of operations(behaviors)
E.g.:-
class Person {
String name;
int age;
void talk() {
}
void think() {
}
void work() {
}
void play() {
}
}
Second, encapsulation is a technique for protecting data from misuse by the outside world, which is referred as ‘information hiding’ or ‘data hiding’.
E.g.:-
class Person {
private String name;
private int age;
public String getName() {
return name;
}
public String getAge() {
return age;
}
}
Sourced from: What is Encapsulation in Java - the WHAT, WHY and HOW, spoiler author cites Interface as an example, which is not true. Interface are for Abstraction