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.
Related
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.)
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.
I'm looking at a VB.NET class (that I didn't write) that is declared MustInherit (abstract in C#, I believe) that has three methods, all of which are defined as Shared (static in C#). There are no properties or fields in the class - only the three methods. From an OO perspective, does this make any sense?
My thinking is no, because by making it MustInherit, you're essentially saying you can't create an instance of this class - you must inherit from it and create an instance of the derived class. But since all the methods are shared, you'll never actually create an instance of the parent class anyway, so the MustInherit does no good. You might as well not mark it MustInherit and just inherit from it whenever you want.
Is there a situation where creating a class this way makes sense?
As others have said, it sounds like they really wanted a C# static class. VB's equivalent to "static" is "shared", but you can't mark classes "shared" in VB. The difference is that someone could inherit from this class and then create an instance. C# static classes are sealed.
What they should have done is use a Module. A VB Module and C# static class are virtually identical: members are associated with the type rather than an instance and you cannot inherit from them.
From an OO perspective, this doesn't make a lot of sense.
However, VB doesn't have a way to flag a class as Shared, like C# does. In C#, you'd likely flag this class as a static class - the MustInherit was most likely added to try to prevent people from creating an instance of it, even though it's basically a static class.
In C# a class can be declared as static (= Shared), and I think VB.NET doesn't allow that, so as a workaround it is marked abstract (MustInherit) so that it's never instantiated
I have a few questions for you wise people involving OO design with Interfaces and abstract base classes. Consider the following scenario:
I have an abstract bass class "DataObjectBase" and a derived class "UserDataObject." I also have an interface "IDataObject." The interface of course exposes all of the public methods and properties that my Data Objects must expose, and you can probably guess that the abstract base implements the methods and properties common to all Data Objects.
My question is, if the abstract bass class DataObjectBase implements everything specified in the interface IDataObject, should the interface be declared on the base class, or on the derived classes(s)?
In C# interfaces declared on the base class are implicity applied to the derived classes, but is this the best practice? It seems to me that implementing the interface on the base class makes it less obvious that the derived class implements the interface, but then again requires the Interface to be specified for each derived class.
Additionally, if the base class was NOT abstract, would the reccomendation change?
A second sub-question: If the base class implements all of the methods/properties of the IDataObject interface, is the interface even needed? The base class typename can simply be used in place of the interface name, ie:
private DataObjectBase _dataObject;
private IDataObject _dataObject;
In the above example (where again the base implements everything exposed by the interface) both can be assigned the same derived types. Personally I always use the interface in these situations, but I am intrested in hearing peoples thoughts.
Thanks in advance.
My way of thinking about such problems is to consider the different people reading the code, the "roles" if you like. Also consider the overall maintainability of the system.
First there is some code expecting to use the Interface. It's written in terms of the interface, the author has (should have) no interest in the implementation. That's why we provide the Interface class. From that perspective the Abstract Base Class is just one of many possible implementation hierarchies. Don't tell this role about implementation details. Keep the Interface.
Then we have the role who is designing an implementation. They come up with one possible approach and discover some variations, so they want to pull common code together. Abstract Base Class - fill in the common stuff here, let detailed implementers fill in the gaps. Help them by providing abstract methods saying "your code goes here". Note that these methods need not only be the ones in the Interface. Also note that this Abstract Base Class might even implement more that one Interface! (eg. It's CleverThingWorker but also a IntermediateWorkPersister.)
Then we have the role who actually do the fine detailed implementation. Fill in the gaps here. Dead easy to understand. In this case you don't even need to consider the Interface as such. Your job is to make that abstract class concrete.
Bottom line ... I use both Interfaces and Base classes. You put the Interface on the Base Class. We don't add value by adding it to the implementation class.
If your user classes will always inherit from one base class, then you don't need the interface. If there is a possibility that you will have classes that match the interface but are not derived from the base class, then use the interface.
As for the interface being hidden in the base class and hence not immediately visible in the user class, this is normal and can be dealt withg by the compiler. This is also where good naming conventions come in - your UserDataObject has a name that matches IDataObject, as does DataObjectBase. You could add a comment to the class file that says it inherits from IDataObject, but it will be visible that it inherits from DataObjectBase, which in turn looks like it inherits from IDataObject by its name.
The other thing that needs to be mentioned is that the use of interfaces makes it easier to implement automated tests.
Say, for example, that one of the methods of the interface is supposed to throw a exception - such as 'DatabaseConnectionLostException' - and you want to test client code to check that it behaves correctly in such a situation.
It is a simple matter to provide an implementation of the interface that throws the exception, allowing the test to be written.
If you used the abstract base class instead of the interface, this operation would be quite a bit trickier (OK, you can use Mocks, but the interface solution is much cleaner)
If I have an abstract class and derived classes of that class, am I correct that, according to good and practical design practice, that the derived classes should not provide extra public methods (they should only implement abstract classes and optionally override parent methods)?
Furthermore, is it acceptable practice to have a different constructor method signature for each derived class?
Personally, I see no problem with either.
As for extra public methods on derived classes:
There is limited usefulness in this, in many cases. The extra methods will not be usable when the class has been cast or set to an reference to the base class, which severely limits usefulness of this practice. That being said, there isn't anything particularly wrong with this approach. Subclasses are meant to add specific behavior - sometimes, in a class hierarchy, there is new behavior in a subclass that isn't appropriate for the base class. If the subclass is going to be used frequently on its own, it seems perfectly reasonable for the extra behavior to be modeled in the methods.
As for constructor signatures -
I see no problem with this either. Subclasses often need more information to be put into a usable state than the abstract class. That being said, I typically make sure to implement every constructor in the base class, plus add the new parameters required for the subclass.
That being said:
Unless there is good reason, I'd avoid having a subclass constructor with fewer parameters than the base class ... why would I be able to specify something on a more generic case and not the specific case? I find that it's usually confusing when subclasses have completely different construction options than their base classes.
This is the beauty of derived classes.
While a Pen class might have a write() function, a RetractablePen class which extends Pen might also have a retractPoint() function.
When you extend a class it means -- literally -- extending the functionality of it.
It's fine in general.
What you want to avoid is using the specific in the generic. i.e.
foreach(Animal a in myFarm.Animals)
{
a.Feed();
// this is a bit grim
if( a is Horse )
{
((Horse)a).CleanStable();
}
}
So it's not the act of adding the public method but rather where you call them from.
It's perfectly acceptable to add additional public methods to your derived classes. It's also perfectly acceptable to give them different contructors. (In fact, this is quite common.)
No, it's perfectly reasonable (and sometimes very necessary by design) to add additional public methods. Consider the (completely contrived) situation of a Shape abstract base class that has a Location member and a Size method. When you derive Polygon from Shape, for example, you may want to add a public method called GetNumberOfSides(), for example; but you don't want to have that when you derive Circle from Shape.
In the same way, the derived types may have very different construction requirements; it's not really possible to know what all the requirements may be when defining the abstract base class, so feel free to have differing signatures. Just because your dervied types will be polymorphic to the abstract base class doesn't mean that that base class imposes strict limitations on how you can implement the abstractions defined in that base class; you're free to pretty much do it however you want.
If you respect the Liskov substitution principle, you can do what you want.
Of course, add a method to a derived class doesn't violate the principle at all.
the derived classes should not provide extra public methods
Can a dog do things that an animal can't?
Furthermore, is it acceptable practice to have a different constructor method signature for each derived class?
There's no problem here. Derived types are not required to match constructor signatures of their siblings or parents.
It is not only acceptable, it is often necessary for the constructors to be different. For example, if we have an (immutable) Rectangle class and extend it with an (immutable) Square, the constructor of Square should be (to use Java for the moment)
public Square(double size)
while the constructor of Rectangle would be
public Rectangle(double width, double height)
What does need to happen is that the subclass constructor should call some appropriate superclass constructor.
As to extra public methods, it may depend on the use. For the Square case, I would not add any extra methods. In Java, however, there is a subclass PrintWriter of Writer
whose purpose is to add some convenience methods. In this case I think it okay (Java certainly has some bad examples but I don't think this is one of them). I would also expect the possibility of some extra methods for container/subpart types.
What you shouldn't do is change the super classes methods in a way that violates the expectations of the super class.