How does inheritance expose parent implementation to subclasses? - oop

Just been reading GoF and they state inheritance exposes a subclass to details of its parent's implementation. If the parent class used private member variables and protected functions I dont see how the implementation is being exposed?

This is a bad answer, but here goes, anyway.
When you inherit a class, the Intellisense or Code Completion will let you know which functions and variables (public and protected) you can access or override. That's a partial answer to "how does inheritance expose parent implementation to subclasses?" because you need to know which functions and variables you can access or manipulate.
If you didn't write the parent class, you would need to consult some documentation that will tell you which functions you may override and that function's place (when and from where it's called) in the parent class's implementation. This information lets you know how a parent class is implemented.
If you wrote the parent class yourself, then you already know its behaviors. When you create your child class, you already have in mind how the parent class works, thus you know which variables and functions to access or override.

Related

Registering all classes that inherit from a particular abstract class in Kotlin

I have a singleton object called registry.
I also have an abstract base class, say Operation with an abstract field called name. I expect other people to subclass this abstract class and create classes denoting specific operations. I want to be able to store name -> Subclass mapping in my registry object.
Ideally, people who subclass this will not even know about this registration. But if that is unavoidable, I prefer them to write as little code as possible just next to their class declaration.
What is the best way of doing this?
The issue here is name being abstract.
If name were a constructor parameter, then you could simply put the code in the your abstract class's constructor. Every subclass, sub-subclass,… instance will call that constructor (directly or indirectly), so it would always get called. (That doesn't apply to a few special cases such as deserialisation and cloning, so you might have to handle those explicitly.)
However, your abstract class's constructor will get called before the sub(sub…)class constructor(s), and so the instance won't be fully initialised and its name property might not be available yet.
The options I see are:
Refactor your class so that the name is a constructor parameter (and can't be changed thereafter), and add your code to the constructor. (If that restriction is feasible, then this is the simplest solution, both for you and for implementers of subclasses, who won't need to do anything extra.)
Provide a method that subclasses can call once the name has been set up. (You'll have to make it clear in the documentation that subclasses must call that method; unfortunately, I don't know of any way to enforce it.)
It may be possible to use annotations and compiler plug-ins and/or runtime libraries, similar to frameworks such as Spring. But I don't know the details, and that's likely to take much more work; it may also need your implementers to add plug-ins and/or libraries to their project, so probably isn't worth it unless you're doing a lot of other frameworky stuff too.
In each case, you can get the name value and the concrete subclass (using this::class or this::class.java), and store them in your registry. (It doesn't look like you're asking about the internals of the registry; I assume you have that side of things covered.)

Dependency inversion principle application

According to Dependency Inversion Principle, a class should not interact with another directly, it should be done using abstraction. That being said, objects are made of type abstract class or interface and are referred to class implementing it. Now my question is if that is the case how can we use additional methods defined in child class? And if not, what is the point of having capability of defining additional methods in child class?
My question is if we try to follow above principle, then we can never use those additional methods. Or there is something that i am missing?
Please reply if this question is not understandable, i will add an example.

Make public class open internally but closed externally kotlin

I have a public abstract class which I want other classes in the module to extend, but I do not want to to be extendible externally.
I am aware I could make it sealed, but it has many subclasses and would be cumbersome to have them all in the same file. How can this be achieved?
You can define its constructor as internal. Subclasses must call the superclass' constructor, so only files that can see that constructor will be able to subclass your class.
You can make it sealed, but declare just one internal (and not sealed) subclass in the same file. Then other classes in the module can see and extend the internal subclass, and so your original class.
Note that classes which extend subclasses of a sealed class (indirect inheritors) can be placed anywhere, not necessarily in the same file.
EDIT: the drawback is that the extending classes must also be internal (or even less visible). Louis Wasserman's solution avoids this and is simpler.

Reasoning behind open modifier for overriden methods

When overriding a method in Kotlin, the base class defining the method and the method itself must be declared open.
After overriding the method the derived class is final by default, while the overridden method is open by default. From the reference documentation:
A member marked override is itself open, i.e. it may be overridden in subclasses. If you want to prohibit re-overriding, use final.
I wonder why the Kotlin-Team made this design decision instead of making the overridden method final as well, which is the default for the derived class and every non-overriden method. I couldn't find any hint while searching the web?
Does anyone have a link to the reasoning behind this design decision or may motivate it?
It's just much more practical. If the method is open, it means that it's designed to be overridden, and such methods are normally overridden multiple times in a class hierarchy. And marking the derived class as open is much easier than repeating the open modifier for all overridden methods as well.
You could argue that these properties are actually correlating. If the class is explicitly marked as open, all properties and methods which were defined as open are treated the same way in all subclasses. If the subclass is not open, the methods are not overridable, regardless of their own modifiers.
As you might have noticed as well, all modifiers of the original definition are inherited. So you don't have to duplicate that information, only when you want to change the signature, you'll have to define it explicitly.

Why Interfaces can not have constructor but abstract classes have constructor

We all know that we can not create the object of both interface and abstract class.But why we are allowed to have constructor in abstract class but not in interface? object of both can not be created.I want very straight forward answer not very complex answer.
Interfaces (at least in .NET and Java, for example) are meant to serve exclusively as what they are named for - to guarantee a certain interface (i.e. set of (public) members) in all implementing classes.
Interfaces are not supposed to have a state, and they are not even supposed to define something like an initial state. Without an initial state, nothing reasonable would be left for a constructor of an interface to be done.
An interface is just a set of member signatures that must be fulfilled by an implementation. Why you can't define constructors? Because constructors are an implementation detail.
Let's say that when you want to hire someone you're not focused on who's the candidate but what can do the candidate (this is a simplification). Does your candidate own desired tech background? Can your candidate do teamwork? From OOP's point of view, you know what a candidate must fulfill to work with you. Therefore, I don't care about a candidate's mother and when/how candidate was born: I care about what properties and behaviors are acceptable for me today. So you would define an interface like CanWorkOnMyCompany for that matter.
In the other hand, an abstract class is a regular class on which some members are signatures and a derived class must provide an implementation to them. That is, you can't instantiate an abstract class because it's not fully implemented.
Probably you could argue that an abstract class can provide no abstract member, but it's not their purpose.
Constructors are for initializing the state of a new instance.
Abstract classes can define state and can have constructors to initialize it.
Interfaces can't define any state and so have no need for constructors.