Is there any way in Java to enforce a subclass or interface implementation to have a constructor with a given signature?
Let's say that I´ve got either:
public interface MyInterface {
// any methods
}
or
public abstract class MyBaseClass {
// any abstract methods
}
Now, is it possible to do anything to require
public class MySubClass extends MyBaseClass {
public MySubClass(String s) { }
}
or
public class MySubClass implements MyInterface {
public MySubClass(String s) { }
}
to always have a constructor that takes a String as it´s only input parameter?
The obvious workaround is to create a factory interface with a method taking a String and inject it where required. Which is not what I would like to do.
Not really, the closest I think you can get is something like:
abstract class B {
public B(String s) {
}
}
public class A extends B {
public A(String s) {
super(s);
}
}
This forces A to implement a non default constructor which must call super(String) but can not prevent the following:
public class A extends B {
public A() {
super("");
}
}
There have been many times where I wished something like this existed, but sadly it doesn't. Even something like what David Soroko suggested wouldn't work because a subclass still wouldn't be forced to have a String constructor - it can just pass any String it likes to super. Simply put, there is no such thing within the Java syntax itself.
I suppose the closest one could get to such a capability is if someone built an annotation processor that allows you to use an annotation like #MustHaveUnaryConstructor(String.class) and then if any subclass does not have such a constructor, it causes compilation to fail and tells you which subclass broke the contract. But I haven't found such a thing and I don't know enough about annotation processing to build one myself. So TL;DR, no, you can't.
Related
I have a method in an abstract class that calls an abstract method, for which the subclasses must provide the implementation.
public abstract class AClass {
public void foo() {
...
fooToImplement();
...
}
// DON'T CALL THIS METHOD, ONLY PROVIDE IMPLEMENTATION!
protected abstract void fooToImplement();
}
I want to make sure that the subclasses don't call fooToImplement(), they should always use foo() instead. The behavior is something like a "private abstract" method, but that's not possible in Java.
Is there some alternative? Thanks!
If you don't want your subclasses to be able to call this method you could use strategy: Extract the behavior of the method into an interface and pass an implementation of this interface to the object. E.g.
IStrategy {
public void fooToImplement();
}
AClass {
public AClass(IStrategy impl) {...}
public void foo() {
...
strategy.fooToImplement();
...
}
}
Delegation instead of inheritance. In java 8 this would be a little bit easier.
If your implementation of IStrategy would need access to the data of the object AClass, you could try to implement it as an inner class.
The method has to be visible by your subclass if you want it to be overriden.
You have to use a class witch does not extends AClass as caller.
public class BClass extends ACLass {
#Override
protected void fooToImplement() {
System.out.println("override me im famous");
}
}
public class CClass {
private BCLass bInstance;
public void doSomething(){
bInstance.foo();
// !!! NO ACCESS TO fooImplement()
}
}
Since fooToImplement() needs to be visible to subclasses to be implemented there and there's no way to distinguish between "implement visibility" and "execution rights", you can't do this by inheritance.
You could however combine your object with another object that contains fooToImplement() by composition:
interface FooImplementation {
void fooToImplement(AClass a);
}
public abstract class AClass {
private final FooImplementation fooImpl;
protected AClass(FooImplementation fooImpl) {
this.fooImpl = fooImpl;
}
public void foo() {
...
fooImpl.fooToImplement(this);
...
}
}
That wouldn't prevent anyone from outside the class from using yourFooImpl.fooToImplement(yourAClass) however. To prevent this you could create a class that provides the information that fooToImplement() needs, but that can only be instanciated from within AClass:
interface FooImplementation {
void fooToImplement(AClass.AClassFooView a);
}
public abstract class AClass {
private final FooImplementation fooImpl;
protected AClass(FooImplementation fooImpl) {
this.fooImpl = fooImpl;
}
public class AClassFooView {
...
private AClassFooView() {
}
}
public void foo() {
...
fooImpl.fooToImplement(this.new AClassFooView());
...
}
}
But fooToImplement could pass the reference to AClassFooView to other classes...
However depending on the implementors of your class making absolutely sure in the documentation, that nobody should call fooToImplement() could also be an alternative.
Ultimately you have to trust the implementors, since there's also the the possibility of someone using reflection to get access to private members, reverse engeneering+changing+recompiling your class ect..
You can use AOP to this, for example add aspect #Before to fooToImplement() and check stacktrace of calling and throw IllegalArgumentException if fooToImplement() be called any method except foo(), something like:
if(!Thread.currentThread().getStackTrace()[1].getMethodName().equals("foo")) {
throw new IllegalArgumentException("You musn't call fooToImplement() directly"+
", using foo() instead");
}
However this way has two problem:
perfomance
runtime exception
Say I'm making a class that implements an interface, and have code like this:
public void setGoalLocation(Location loc)
{
goal = loc;
}
The code doesn't compile, because it demands that I implement a "setGoalLocation(Ilocation loc)" method, where "Ilocation" is an interface and "Location" is an actual concrete class that implements it.
This means that I have to do something like this:
public void setGoalLocation(ILocation loc)
{
goal = (Location)loc;
}
That just seems really awkward. And funnily enough, Java doesn't seem to care about other methods returning Location instead of the interface ILocation. This works:
public Location getStartLocation()
{
return start;
}
...even though the "required" method would be a "public ILocation getStartLocation". Can anyone explain why this is, and any help for making the code less awkward? I'd like to be able to use a Location as a parameter, not an ILocation.
The problem is that the interface requires a method that accepts anything as an argument that is a subtype of ILocation, not just an object of the specific type Location. If you had another concrete type Position that was a subtype of ILocation, then implementing the interface would require you to accept a Position object as well as a Location object.
Note that in your work-around using a cast, you'd get a ClassCastException at run time if you happened to pass a Position instead of a Location object.
As a design issue, to get around this you could define your interface as a generic:
interface <T extends ILocation> TheInterface {
void setGoalLocation(T loc);
}
Then your concrete class can bound the generic parameter:
public class MyClass implements TheInterface<Location> {
public void setGoalLocation(Location loc) {
. . .
}
}
As to return types, that works because any Location object is an ILocation, so when you return a Location you are returning an ILocation.
Java supports covariant return types where the return type of a method in a subclass (or interface implementation) can return a subclass (or implementation) of the declared type. So in general, the following is allowed
public class A {}
public class B extends A {}
public class C {
A getSomething();
}
public class D extends C {
B getSomething();
}
If the interface has a method that takes an interface type, you cannot override it with a different signature.
public interface I {
void setSomething(ISomething somethingInterface);
}
You cannot do
public class Something implements ISomething {}
public class MyI implements I {
void setSomething(Something somethingInterface);
}
Can have an abstract class implementing all of its methods-- with no abstract methods in it.
Eg.:
public abstract class someClass {
int a;
public someClass (int a) { this.a = a; }
public void m1 () { /* do something */ }
private void m2 () { /* do something else */ }
}
What's the advantage, if any, of having such an abstract class compared to having the same class as a concrete one instead?
One i can think of is that, when i declare it as abstract, it won't be instantiated.
however, i can have the same effect by making it concrete and its constructor(s) private.
TIA.
//==================
EDIT: One other use I can think of:
it may be extending another abstract class or implementing an interface without implementing that class's abstract methods-- although it is implementing all methods of its own. for whatever it' worth.
It has a conceptual meaning: this class has a behaviour which makes no sense on its own.
Granted, it's difficult to imagine such a scenario without well-defined extension points (i.e. abstract methods), but occasionally it will be a reasonably accurate model of your problem.
You can have something like this:
public abstract class ObjectWithId {
private final String id;
public ObjectWithId( String id ) {
this.id = id;
}
public final String getId() {
return id;
}
}
And then you can extend it to declare different types of objects that have ids. Here you have a fully specified and implemented behaviour but no restriction on any other behaviours subclasses may exhibit.
Note though that a much neater way to model the same thing is to use composition instead of inheritance.
public final class ObjectWithId<T> {
private final String id;
private final T ob;
public ObjectWithId( String id, T ob ) {
this.id = id;
this.ob = ob;
}
public String getId() {
return id;
}
public T getObject() {
return ob;
}
}
But before generics were introduced (up to Java version 1.4), this wouldn't have been as elegant and obviously better than the abstract class solution because you'd have had to trade in type safety.
you can declare to implement an interface and don't provide implementation and then each child implicitly gets interface extended
you prevent to create instance of this class
you in future provide common implementation to all children
As you pointed out, you can prevent the class from being instantiated by making it's constructor private. Othere than that, there is no benefit whatsoever. This is probably supported just to provide language completeness.
We generally use Abstraction concept with inheritance
Consider using abstract classes if any of these statements apply to
your situation:
You want to share code among several closely related classes.
To answer your question,
Why declare a class with concrete methods Abstract?
One possible reason is to support inheritance without actually creating objects
Assume you have two classes one Abstract and other Concrete
Abstract class : AbsClass
abstract class AbsClass {
int a = 5;
//Constructor
public AbsClass() {
System.out.println(a);
}
void methodA() {
System.out.println(a + 10);
}
}
and
Concrete class : ConcreteClass
class ConcreteClass {
int a = 10;
//Made the constructor Private to prevent from creating objects of this class
private ConcreteClass() {
System.out.println(a);
}
void methodA() {
System.out.println(a + 10);
}
}
The above two classes should function similarly (?) Until you try to Subclass them
class AbsImplementer extends AbsClass {
//Works fine
}
class ConcImplementer extends ConcreteClass {
//Compilation Error Implicit super constructor ConcreteClass() is not visible
}
The practical difference is that you can't create an instance of it. You would have to subclass it and create an instance of the subclass.
As to WHY you would want to do this, in practice ... I'm hard pressed to think of a good reason. You could say that the class is only meaningful if someone creates a subclass that implements some function. But then why not make that function abstract in the super-class?
I wouldn't rule out the possibility that someone might come up with some example where this makes sense, but I can't think of one. Just because it's possible to write a piece of code and that code compiles successfully doesn't mean that that it makes sense. I mean, I can write "total_price = item_price * zip_code + customer_height_in_cubits - 7.879", but that doesn't mean such a line of code would be meaningful.
Well assume that you don't care whether the methods of the abstract class are implemented or abstract, but by design it has to be abstract so that when someone extends it, they have to add more methods or override the existing ones or use as is. If they don't want to override the methods then the default behavior is already provided in that abstract class.
In this abstract class, the only criteria you enforce is - one simply cannot instantiate that class and they have to have their only version of class before using it.
So in general, abstract class with few or all methods being implemented, is much better than having an interface which has no methods implemented at all. This is based on the assumption that you are using it as a single inheritance.
Consider something similar to the NVI pattern (not sure what you'd call it in Java):
public abstract class A {
public final void doSomething() {
System.out.println("required");
doOptional();
}
protected void doOptional() {
System.out.println("optional");
}
}
public class B extends A {
#Override
protected void doOptional() {
System.out.println("overridden");
}
}
For your public API, you only expose a public final method which cannot be overridden. It performs some required work inside there and an optional method. When extending this class, you can only override doOptional().
Calling B.doSomething() will always print "required" before it proceeds.
Since doOptional() is not abstract, there's no purely code reason that class A needs to be abstract. But it might be desired for your particular project. For example, a base service that is always extended into specific sub-projects.
This can be useful for cases when the classes derived from the abstract base class must have some behaviour that is different from each other but that behaviour can not be abstracted as residing within a method that has the same signature for all the classes. Being unable to share a signature can occur if the different behaviour requires methods that are passed different primitive types. Because they use primitive types you can not use generics to express the similarity.
An abstract base class without any abstract methods is acting a bit like a marker interface, in that it is declaring that implementing classes must provide some behaviour without having that behaviour encapsulated within a new method with a signature that is the same for all implementations. You would use an abstract base class rather than a marker interface when the implementing classes have some behaviour in common, especially if the base class can implement it for the derived classes.
For example:
abstract class Sender {
protected final void beginMessage() {
...
}
protected final void endMessage() {
...
}
protected final void appendToMessage(int x) {
...
}
}
final class LongSender extends Sender {
public void send(int a, int b, int c) {
beginMessage();
appendToMessage(a);
appendToMessage(b);
appendToMessage(c);
endMessage();
}
}
final class ShortSender extends Sender {
public void send(int a) {
beginMessage();
appendToMessage(a);
endMessage();
}
}
It can be useful if you consider it an utility class.
Can have an abstract class implementing all of its methods-- with no abstract methods in it.
Eg.:
public abstract class someClass {
int a;
public someClass (int a) { this.a = a; }
public void m1 () { /* do something */ }
private void m2 () { /* do something else */ }
}
What's the advantage, if any, of having such an abstract class compared to having the same class as a concrete one instead?
One i can think of is that, when i declare it as abstract, it won't be instantiated.
however, i can have the same effect by making it concrete and its constructor(s) private.
TIA.
//==================
EDIT: One other use I can think of:
it may be extending another abstract class or implementing an interface without implementing that class's abstract methods-- although it is implementing all methods of its own. for whatever it' worth.
It has a conceptual meaning: this class has a behaviour which makes no sense on its own.
Granted, it's difficult to imagine such a scenario without well-defined extension points (i.e. abstract methods), but occasionally it will be a reasonably accurate model of your problem.
You can have something like this:
public abstract class ObjectWithId {
private final String id;
public ObjectWithId( String id ) {
this.id = id;
}
public final String getId() {
return id;
}
}
And then you can extend it to declare different types of objects that have ids. Here you have a fully specified and implemented behaviour but no restriction on any other behaviours subclasses may exhibit.
Note though that a much neater way to model the same thing is to use composition instead of inheritance.
public final class ObjectWithId<T> {
private final String id;
private final T ob;
public ObjectWithId( String id, T ob ) {
this.id = id;
this.ob = ob;
}
public String getId() {
return id;
}
public T getObject() {
return ob;
}
}
But before generics were introduced (up to Java version 1.4), this wouldn't have been as elegant and obviously better than the abstract class solution because you'd have had to trade in type safety.
you can declare to implement an interface and don't provide implementation and then each child implicitly gets interface extended
you prevent to create instance of this class
you in future provide common implementation to all children
As you pointed out, you can prevent the class from being instantiated by making it's constructor private. Othere than that, there is no benefit whatsoever. This is probably supported just to provide language completeness.
We generally use Abstraction concept with inheritance
Consider using abstract classes if any of these statements apply to
your situation:
You want to share code among several closely related classes.
To answer your question,
Why declare a class with concrete methods Abstract?
One possible reason is to support inheritance without actually creating objects
Assume you have two classes one Abstract and other Concrete
Abstract class : AbsClass
abstract class AbsClass {
int a = 5;
//Constructor
public AbsClass() {
System.out.println(a);
}
void methodA() {
System.out.println(a + 10);
}
}
and
Concrete class : ConcreteClass
class ConcreteClass {
int a = 10;
//Made the constructor Private to prevent from creating objects of this class
private ConcreteClass() {
System.out.println(a);
}
void methodA() {
System.out.println(a + 10);
}
}
The above two classes should function similarly (?) Until you try to Subclass them
class AbsImplementer extends AbsClass {
//Works fine
}
class ConcImplementer extends ConcreteClass {
//Compilation Error Implicit super constructor ConcreteClass() is not visible
}
The practical difference is that you can't create an instance of it. You would have to subclass it and create an instance of the subclass.
As to WHY you would want to do this, in practice ... I'm hard pressed to think of a good reason. You could say that the class is only meaningful if someone creates a subclass that implements some function. But then why not make that function abstract in the super-class?
I wouldn't rule out the possibility that someone might come up with some example where this makes sense, but I can't think of one. Just because it's possible to write a piece of code and that code compiles successfully doesn't mean that that it makes sense. I mean, I can write "total_price = item_price * zip_code + customer_height_in_cubits - 7.879", but that doesn't mean such a line of code would be meaningful.
Well assume that you don't care whether the methods of the abstract class are implemented or abstract, but by design it has to be abstract so that when someone extends it, they have to add more methods or override the existing ones or use as is. If they don't want to override the methods then the default behavior is already provided in that abstract class.
In this abstract class, the only criteria you enforce is - one simply cannot instantiate that class and they have to have their only version of class before using it.
So in general, abstract class with few or all methods being implemented, is much better than having an interface which has no methods implemented at all. This is based on the assumption that you are using it as a single inheritance.
Consider something similar to the NVI pattern (not sure what you'd call it in Java):
public abstract class A {
public final void doSomething() {
System.out.println("required");
doOptional();
}
protected void doOptional() {
System.out.println("optional");
}
}
public class B extends A {
#Override
protected void doOptional() {
System.out.println("overridden");
}
}
For your public API, you only expose a public final method which cannot be overridden. It performs some required work inside there and an optional method. When extending this class, you can only override doOptional().
Calling B.doSomething() will always print "required" before it proceeds.
Since doOptional() is not abstract, there's no purely code reason that class A needs to be abstract. But it might be desired for your particular project. For example, a base service that is always extended into specific sub-projects.
This can be useful for cases when the classes derived from the abstract base class must have some behaviour that is different from each other but that behaviour can not be abstracted as residing within a method that has the same signature for all the classes. Being unable to share a signature can occur if the different behaviour requires methods that are passed different primitive types. Because they use primitive types you can not use generics to express the similarity.
An abstract base class without any abstract methods is acting a bit like a marker interface, in that it is declaring that implementing classes must provide some behaviour without having that behaviour encapsulated within a new method with a signature that is the same for all implementations. You would use an abstract base class rather than a marker interface when the implementing classes have some behaviour in common, especially if the base class can implement it for the derived classes.
For example:
abstract class Sender {
protected final void beginMessage() {
...
}
protected final void endMessage() {
...
}
protected final void appendToMessage(int x) {
...
}
}
final class LongSender extends Sender {
public void send(int a, int b, int c) {
beginMessage();
appendToMessage(a);
appendToMessage(b);
appendToMessage(c);
endMessage();
}
}
final class ShortSender extends Sender {
public void send(int a) {
beginMessage();
appendToMessage(a);
endMessage();
}
}
It can be useful if you consider it an utility class.
I have a list of objects which extend from a base class. Now I want to apply a specific operation only on one instance of classes in the list.
Is the use of instanceof a good practice there? Or should I rather differ the objects by eg a custom enum?
abstract class Base;
class Foo extends Base;
class Bar extends Base;
List<Base> bases;
for (Base base : bases) {
if (base instanceof Bar.class) {
//execute my custom operation on the base object
doSomething((Bar) base);
}
}
If that approach is not that nice in general, how could I do better?
There does not really seem to be any reason to use instance of here. It might make sense to have the base class default the behavior to doing nothing and override it in extending classes when needed. This way you only override it if needed (I on.y left this as an abstract class to follow with the question its not needed for this example).
For example:
abstract class Base{
public void doSomething(){}
}
public class B0 extends Base{
#Override
public void doSomething(){//actually do something}
}
public class B1 extends Base{}
An example of using this could be something like:
public class SomeOtherClass{
public void something(List<Base> bases){
for(Base base:bases)
base.doSomething();
}
}
abstract class Base;//abstract function doSomething()
class Foo extends Base;//implements doSomething()
class Bar extends Base;//dito
List<Base> bases;
for (Base base : bases) {
base.doSomething();
}
To answer your question: it is not a good idea to use instanceof.
Instance of is not a good practice here.
Correct solution will depend on what exactly is going on inside that doSomething method.
If you do it your way then, besides other things, you violate Liskov Substitution Principle. I assume that you decided that you need these hierarchy in the first place because of something and I also assume that subtypes have some more behavior than only doSomething method. In this case, what you can do is shown below. Basically only types that should doSomething actually do it and rest of the types do something like no operation. In that way you can use these objects without needing to know what type they really are.
You should also ask yourself if you really need Base class to be abstract class. Maybe all you need is a interface. There might be better approach but basing on the information I have and what I've assumed then this seems to be alright.
public abstract class Base
{
public abstract void doSomething();
public void someOtherMethod()
{
// which does stuff
}
}
public class SubTypeWhichCanDoSomething extends Base
{
#Override
public void doSomething()
{
// actually implement method and DO something
}
}
public class DoesNothing extends Base
{
#Override
public void doSomething()
{
// does nothing
return;
}
}
// then your code looks like these
for(Base base : bases)
{
base.doSomething();
}