1. Overview
Although the definition of a wrapper class is simple, it’s used in many different ways in software engineering.
In this tutorial, we’ll discuss what wrapper classes are and see several examples of them.
2. What Is a Wrapper Class?
A wrapper class, as its name implies, wraps another component. The component might be an object of another class or a simple type. The wrapper class doesn’t change the behavior of the encapsulated component. Apparently, this definition is broad. Therefore, there are many examples of wrapper classes each with different purposes.
For instance, wrapper classes in Java wrap primitive data types. The Integer class wraps the primitive data type int, as an example. Conversion from the primitive data type to the wrapper class and the opposite are easy using boxing and unboxing, respectively.
Additionally, the wrapper classes in Java provide other methods for comparison and conversion to and from other types. Therefore, wrapper classes provide a means to work with the primitive data types in an object-oriented manner. We can use them with classes and interfaces that don’t support primitive data types. For example, the classes and interfaces in the Java Collections Framework can’t hold primitives but can hold wrapper classes.
Wrapper classes that encapsulate primitive data types aren’t specific to Java. Other languages also provide wrapper classes, for instance, inline classes in Kotlin.
We’ll see other usages of wrapper classes in the next section.
3. Examples of Wrapper Classes
We’ll discuss examples of wrapper classes that don’t encapsulate a primitive type.
3.1. The Adapter Class in the Adapter Design Pattern
The Adapter pattern is a structural design pattern that converts the interface of a class to another:
The Client uses the Target interface, but it can’t use the Adaptee class since the interface of the Adaptee class is different from the Target interface. However, the Adapter class, which implements the Target interface, can call the methods of the Adaptee class. Therefore, it converts the Target interface to the interface of the Adaptee class. As a result, the Client can use the Adaptee class by means of the Adapter class.
The Adapter class is a wrapper class that wraps the Adaptee. Indeed, the Adapter pattern is also known as the Wrapper pattern.
The structure in the class diagram is known as the object adapter which depends on object composition. There’s also another form of the adapter pattern which uses multiple inheritance. It’s known as the class adapter.
3.2. The ConcreteDecorator Class in the Decorator Design Pattern
The Decorator pattern is a structural design pattern that adds new functionality to an interface by wrapping the original class:
The Component interface defines the common interface for both wrappers and wrapped objects. We can add new functionalities to the Component interface dynamically. The Decorator interface has a reference to the decorated object, Component. Subclasses like ConcreteDecoratorA and ConcreteDecoratorB, which implement the Decorator interface, add additional behaviors to the Component object before or after forwarding the request to it.
The concrete decorator classes, i.e., the ConcreteDecoratorA and ConcreteDecoratorB classes, are the wrapper classes. They wrap the Component object and extend its functionality.
Another name for the Decorator pattern is the Wrapper pattern, just like the Adapter pattern.
3.3. The Proxy Class in the Proxy Design Pattern
The Proxy pattern is a structural design pattern that provides a substitute for another object to control access to it:
The Client uses the Proxy class, which implements the Subject interface. Thanks to implementing the same interface, we can substitute the Proxy object for the RealSubject object. The Proxy object has a reference to the RealSubject object and delegates the calls to the RealSubject object. However, it can perform additional functionality while accessing the RealSubject object.
The Proxy class acts as a wrapper for the RealSubject class in this case.
3.4. The Facade Class in the Facade Design Pattern
The Facade pattern is a structural design pattern that provides a simplified interface to a more complex set of subsystem classes:
Clients interact with the Facade object and the Facade object delegates client requests to the underlying subsystem objects. The classes in the subsystem may have several kinds of dependencies between each other.
The Facade class in this pattern acts as a wrapper class for the more complex underlying classes. Clients interact with the Facade object instead of interacting with the objects in the subsystem.
The main difference between the Facade class and the other wrapper classes we’ve discussed is that it wraps multiple classes.
4. Conclusion
In this article, we discussed what wrapper classes are. Firstly, we learned the usage of wrapper classes that encapsulate primitive types in object-oriented languages.
Then, we saw examples of wrapper classes used in several design patterns. We learned that the Adapter class in the Adapter design pattern, the ConcreteDecorator class in the Decorator design pattern, the Proxy class in the Proxy design pattern, and the Facade class in the Facade design pattern are examples of wrapper classes each having a specific purpose.