Stopping inheritance without using final - java

Is there any other method of stopping inheritance of a class apart from declaring it as final or by declaring its constructor as private?

A comment
//Do not inherit please

Two more options:
make each method final, so people can't override them. You avoid accidental calling of methods from subclass this way. This doesn't stop subclassing though.
put check into constructor for class:
if (this.getClass() != MyClass.class) {
throw new RuntimeException("Subclasses not allowed");
}
Then nobody will be able to instantiate subclass of your class.
(Not that I suggest using these techniques, it just came to my mind. I would use final class and/or private constructor)

Use final
Use private constructors
Use a comment:
// do not inherit
Use a javadoc comment
Make every method final, so people can't override them
Use a runtime check in the class constructor:
if (this.getClass() != MyClass.class) {
throw new RuntimeException("Subclasses not allowed");
}

Final was created to solve this problem.

Make your constructors private and provide factory functions to create instances.
This can be especially helpful when you want to choose an appropriate implementation from multiple, but don't want to allow arbitrary subclassing as in
abstract class Matrix {
public static Matrix fromDoubleArray(double[][] elemens) {
if (isSparse(elements)) {
return new SparseMatrix(elements);
} else {
return new DenseMatrix(elements);
}
}
private Matrix() { ... } // Even though it's private, inner sub-classes can still use it
private static class SparseMatrix extends Matrix { ... }
}

Using final is the canonical way.
public final class FinalClass {
// Class definition
}
If you want to prevent individual methods from being overridden, you can declare them as final instead. (I'm just guessing here, as to why you would want to avoid making the whole class final.)

I'd have to say it's typically bad form. Though there are almost always cases where something is valid, I'd have to saying stopping inheritance in an OO world is normally not a good idea. Read up on the Open-Closed Principle and here. Protect your functionality but don't make it impossible for the guy who comes in and supports it...

Without using a final class, you can basically make all the constructors private:
public class A {
private A() {} //Overriding default constructor of Java
}
Which although will also make this class abstract-ish by disallowing creating an object of this class, yet as any inheritance requires super(); in the constructor, and because the constructor is private, a compilation error will be the maximum you can get when one tries to inherit that class.
Yet, I would recommend using final instead as it is less code and includes the option of creating objects.

Related

Can we avoid inheritance without using final keyword?

I just want to know that can i have 2 classes A and B.
I don't want to allow class B to extends class A.
What technique should i apply in class A so class B cannot inherit class A.
Don't want to make class A final. Any other solution instead of making class A final?
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.
https://stackoverflow.com/a/10464466/5010396
This is not possible in "nice ways". The java language allows you to either have the final keyword on your class definition, or to not have it.
As pointed out by others: you can make all constructors private, then subclassing becomes practically impossible, as the subclass constructors have no super class constructor to call.
In case you need to instantiate A, you could still have a factory method, like:
public class A {
private A() { ... }
private A(String foo) { ... }
public static A newInstance(String foo) { return new A(foo); }
for example.
But keep in mind: code is written for your human readers. If your intent is to have a final class, then the correct answer is to use that keyword final.
Plus: making your class final allows the JIT to do a few more things, as it doesn't have to worry about polymorphism at any point (so it can directly inline method code, without any additional checks). So using final can result in slightly improved performance. On the other hand, it limits your ability to unit test things (for example: standard Mockito can't mock final classes).
You can mark the constructor of A class as private. :)
PS: If you also want to avoid reflection attacks then throw some Error from constructor
and also mark it private.
You have an option to restrict in constructor like this.
if (this.getClass() != MyClass.class) {
throw new RuntimeException("Subclasses not allowed");
}
For further details check the post.
https://stackoverflow.com/a/451229/6742601
I don't understand the specific use case of your requirement but this could work.
If you are open to make changes in B
In B's every constructor check for is it is an instance of A then throw an error.
if(A.class.isAssignableFrom(B.class)) {
System.out.println(true);
throw new IllegalStateException();
}
else
System.out.println(false);
You can do one of the following to avoid inheritance without using final keyword:
Use private constructor(s).
Mark every method final so children can't override them.
Throw Runtime exception in the constructor if want to limit inheritance for some unwanted children (although v.rude) e.g
if (this.getClass() != FavoriteChild.class) throw new RuntimeException("Not Allowed")

How to avoid subclass without use of final Keyword in Java

final class AbsTest {}
class BTest extends AbsTest {}
How to prevent creation of subclass(es) without using the final keyword?
Here are the few options
Create Private Constructor
make each method final, so people can't override them. You avoid accidental calling of methods from subclass this way. This doesn't stop subclassing though.
put check into constructor for class:
if (this.getClass() != abc.class)
{
throw new RuntimeException("Subclasses not allowed");
}
But final is provided to solve such problem I must say, so better to go with final!!!
In above code how to prevent to create subclass without use of "final"
keyword
You can declare private constructors to avoid creation of Object.
private AbsTest() {
}

Forcing subclasses to have a particular factory method or constructor

I am 70% confident that this is impossible, but is there a way to make sure that subclasses have a particular constructor or factory method?
In this case, I am trying to create a StringSerializable that would require subclasses to have the following methods
toString, which converts the object to a String.
fromString, which gets an instance from a String.
Obviously, in the first case, I can just make toString abstract. On the other hand, having a nonstatic fromString seems to be problematic. However, I can't create an abstract static method. I also do not think that a constructor is entirely appropriate.
You're correct; it's impossible to force it at compile time. There are various tricks you could do at runtime (such as using reflection in tests), but that's about it.
But ask yourself: why do you want to require that? You can't dynamically invoke a static method or constructor (except through reflection), so how exactly would you use those required factories, if you had them?
If it's just for consistency in the code (which is a good thing!), then you'll just have to ensure that consistency as you develop the code base. A comment in the base class can go a long way here, as can code reviews and other "soft" techniques.
If you plan to use the factories in reflection, then similar reflection can be used in tests to make sure that each subclass has the bits it needs.
Another option is to create a non-static factory:
public interface FooMaker() {
Foo create(String arg);
}
... and use that, rather than a static fromString method.
There again you have the same problem of "how do I ensure that every subclass has a FooMaker implementation?" and again I would say that you shouldn't worry about that. If you make the FooMaker the "starting point" of your code, rather than the subclasses, then it doesn't matter what the subclasses are doing; all that matters is that your FooMakers give you a way of going from string to Foos, and each Foo has a way of going back to a string.
the following code does ensure that every subclass needs to implement the static method, if the subclass does not implement the method it will fail when classes are constructed, as close as you can get to a compile time error, but not at compile time
the exception thrown is very clear and the programm will instantly fail when started
public abstract class Base {
static Functional test;
static {
if(test == null) {
throw new RuntimeException("You need to provide an implementation for the implemntMe method in class base");
}
}
private interface Functional {
Base implementMe(int whatever, boolean anotherParameter);
}
public static void main(final String[] args) {
}
}
the private interface construct ensures that only lambdas can be used to implement the method
a subclass would have to look like this
public SubClass extends Base {
static {
test = (int whatever, boolean anotherParameter) -> {
Subclass tmp = new Subclass();
//construct object
tmp.setWhatever(whatever);
return tmp;
}
}
}
lamdas are like inline methods that implement a functional interface, an interface which has only one abstract method
you can also declare the interface publicly at any other place and implement it with an anonymous inner class,
but my way makes sure that programers have to copy and paste code to reuse it,
or need to copy the object of Functional from another class

Java Constructor Inheritance

I was wondering why in java constructors are not inherited? You know when you have a class like this:
public class Super {
public Super(ServiceA serviceA, ServiceB serviceB, ServiceC serviceC){
this.serviceA = serviceA;
//etc
}
}
Later when you inherit from Super, java will complain that there is no default constructor defined. The solution is obviously something like:
public class Son extends Super{
public Son(ServiceA serviceA, ServiceB serviceB, ServiceC serviceC){
super(serviceA,serviceB,serviceC);
}
}
This code is repetitive, not DRY and useless (IMHO)... so that brings the question again:
Why java doesn't support constructor inheritance? Is there any benefit in not allowing this inheritance?
Suppose constructors were inherited... then because every class eventually derives from Object, every class would end up with a parameterless constructor. That's a bad idea. What exactly would you expect:
FileInputStream stream = new FileInputStream();
to do?
Now potentially there should be a way of easily creating the "pass-through" constructors which are fairly common, but I don't think it should be the default. The parameters needed to construct a subclass are often different from those required by the superclass.
When you inherit from Super this is what in reality happens:
public class Son extends Super{
// If you dont declare a constructor of any type, adefault one will appear.
public Son(){
// If you dont call any other constructor in the first line a call to super() will be placed instead.
super();
}
}
So, that is the reason, because you have to call your unique constructor, since"Super" doesn't have a default one.
Now, trying to guess why Java doesn't support constructor inheritance, probably because a constructor only makes sense if it's talking about concrete instances, and you shouldn't be able to create an instance of something when you don't know how it's defined (by polymorphism).
Because constructing your subclass object may be done in a different way from how your superclass is constructed. You may not want clients of the subclass to be able to call certain constructors available in the superclass.
A silly example:
class Super {
protected final Number value;
public Super(Number value){
this.value = value;
}
}
class Sub {
public Sub(){ super(Integer.valueOf(0)); }
void doSomeStuff(){
// We know this.value is an Integer, so it's safe to cast.
doSomethingWithAnInteger((Integer)this.value);
}
}
// Client code:
Sub s = new Sub(Long.valueOf(666L)): // Devilish invocation of Super constructor!
s.doSomeStuff(); // throws ClassCastException
Or even simpler:
class Super {
private final String msg;
Super(String msg){
if (msg == null) throw new NullPointerException();
this.msg = msg;
}
}
class Sub {
private final String detail;
Sub(String msg, String detail){
super(msg);
if (detail == null) throw new NullPointerException();
this.detail = detail;
}
void print(){
// detail is never null, so this method won't fail
System.out.println(detail.concat(": ").concat(msg));
}
}
// Client code:
Sub s = new Sub("message"); // Calling Super constructor - detail is never initialized!
s.print(); // throws NullPointerException
From this example, you see that you'd need some way of declaring that "I want to inherit these constructors" or "I want to inherit all constructors except for these", and then you'd also have to specify a default constructor inheritance preference just in case someone adds a new constructor in the superclass... or you could just require that you repeat the constructors from the superclass if you want to "inherit" them, which arguably is the more obvious way of doing it.
Because constructors are an implementation detail - they're not something that a user of an interface/superclass can actually invoke at all. By the time they get an instance, it's already been constructed; and vice-versa, at the time you construct an object there's by definition no variable it's currently assigned to.
Think about what it would mean to force all subclasses to have an inherited constructor. I argue it's clearer to pass the variables in directly than for the class to "magically" have a constructor with a certain number of arguments just because it's parent does.
Constructors are not polymorphic.
When dealing with already constructed classes, you could be dealing with the declared type of the object, or any of its subclasses. That's what inheritance is useful for.
Constructor are always called on the specific type,eg new String(). Hypothetical subclasses have no role in this.
David's answer is correct. I'd like to add that you might be getting a sign from God that your design is messed up, and that "Son" ought not to be a subclass of "Super", but that, instead, Super has some implementation detail best expressed by having the functionality that Son provides, as a strategy of sorts.
EDIT: Jon Skeet's answer is awesomest.
Because a (super)class must have complete control over how it is constructed. If the programmer decides that it doesn't make sense to provide a default (no args) constructor as part of the class's contract, then the compiler should not provide one.
You essentially do inherit the constuctors in the sense that you can simply call super if and when appropriate, it's just that it would be error prone for reasons others have mentioned if it happened by default. The compiler can't presume when it is appropriate and when it isn't.
The job of the compiler is to provide as much flexibility as possible while reducing complexity and risk of unintended side-effects.
I don't know any language where subclasses inherit constructors (but then, I am not much of a programming polyglott).
Here's a discussion about the same question concerning C#. The general consensus seems to be that it would complicate the language, introduce the potential for nasty side effects to changes in a base class, and generally shouldn't be necessary in a good design.
A derived class is not the the same class as its base class and you may or may not care whether any members of the base class are initialized at the time of the construction of the derived class. That is a determination made by the programmer not by the compiler.

simulation of static class in java

What do you think of the following way to simulate a static class in java?
You can add non static methods but you wouldn't be able to call them.
/**
* Utility class: this class contains only static methods and behaves as a static class.
*/
// ... prevent instantiation with abstract keyword
public abstract class Utilities
{
// ... prevent inheritance with private constructor
private Utilities() {}
// ... all your static methods here
public static Person convert(String foo) {...}
}
That is the usual way. However, there is not need for the abstract keyword. Using a private constructor is sufficient because
it prevents the creation of objects (from outside the class)
it prevents inheritance
The abstract keyword suggests the user that users of the class might implemented the class what is not the case here.
Item 4 in Effective Java (a very... effective book) says:
// Noninstantiable utility class
public final class Utility {
private Utility() {
throw new AssertionError();
}
}
because the explicit costructor is private:
you cannot instantiate it
you cannot extend it (as if it was declared as final)
The AssertionError isn't required but it provides another small benefit: it prevents that the costructior is accidentally invoked from within the class.
You can also create a specific annotation, like #BagOfFunction, and annotate your class:
#BagOfFunctions
public final class Utility {
private Utility() {
throw new AssertionError();
}
}
basically you trade a comment for a self-documenting annotation.
My FindBugs plugin suggests rather final class instead of abstract class. And I use that in my project. It seems to be a widespread idiom if it became a rule that is checked by FindBugs.
i would say, if you habe already a private constructor
private Utilities() {}
the abstract keyword is not neccessary. rather make it final.
the difference to your version is marginal, for any practical means.
I prefer making such classes final, but not abstract. Though it is just a matter of personal style.
By the way, I suppose it is still possible to call its instance methods if you put some energies. E.g. one can try using objenesis to create instance of class.
I'll have to agree with those above. Use "final" instead of "abstract". Remember, words like "final" and "abstract" are as much a means of communicating with your fellow programmers as they are instructions to the machine. Abstract implies that there will be descendant classes later, whereas final decidedly means that you will not, save through refactoring, see anything descended of this class (which is your intended meaning).
Further, in most standards I've seen, and consistently in my company, it is considered best practice to make the abstract class something which is specifically left unused, save as a parent of other classes. "Abstract" is treated as "blueprint" or "general structure", you would never drive an "abstract" car. On the other hand, final classes are instantiated perpetually, especially with Factory patterns.
My suggestion is: prevent incorrect use (i.e. instantiation) by placing javadocs
Isn't that simpler? I think your teammates are able to read ;)

Categories

Resources