First and foremost, the Decorator has nothing to do with inheritance. If you are extending a class, that is bog standard polymorphism. A Decorator has the same interface as the class you are trying to extend, and takes another class of the same type to wrap it.
Decorators are used often in middleware. I.e. wrapping a service to provide logic before and after the thing you are extending.
Take for example an interface for processing web requests:
public interface WebService {
void handle(HttpRequest request, HttpResponse response)
}
You could have your fancy web service implementation that does things, but then you need to add in some telemetry. In that case you can use a Decorator to handle the telemetry part without changing anything in your working code. The decorator would look something like this:
public class TelemetryWebService {
private WebService wrapped
public TelemetryWebService(WebService handler) {
wrapped = handler
}
public handle(HttpRequest request, HttpResponse response) {
context = new TelemetryContext(request)
context.sendBeginMessage(request)
wrapped.handle(request, response)
context.sendEndMessage(request)
}
}
That's what a Decorator is.
Now, if you extend a class that's called polymorphism. Your object oriented language has keywords to manage the scope of variables. The common convention is as follows:
private
attributes only belong to the class they are defined in
protected
attributes can be accessed by the class they are defined in as well as any class that extends that
public
attributes can be accessed by any code with a reference to your object
So if you want to expose the internal state of your base class, you have to make a conscious decision to make that state available. To protect yourself from things outside your class changing how it works, it's best to make that state available as read only. That's commonly done as a "getter" method. Some languages have some syntactic sugar called properties. Either way, be careful about what you allow to change the state in your class.