This seems to be basic question. But worth to clarify before interviews.
I have a non abstract method in abstract class. Its concrete class overridden that method. But I want to call the parent class's original method to invoke rather than overridden method. Is there any way to do it ?
As I can understand there's no way to invoke original method ?
public abstract class Testabstract {
public void t1() {
System.out.println("parent");
}
}
public class Testconcrete extends Testabstract {
public void t2() {
System.out.println("child11");
}
public void t1() {
System.out.println("childss");
}
}
public class Main {
public static void main(String[] args) {
Testconcrete a = new Testconcrete();
a.super.t1();// compile error
a.t2();
}
}
No, you can't directly invoke the superclass's overridden method. This is by design; the subclass might add some sort of behavior that is necessary for correctness (such as maintaining some sort of cache or other data structure) or functional requirements (such as logging). Bypassing the subclass's functionality would put the correctness of the model at risk and breaks the encapsulation that assures it.
super keyword can use only with in the child class.
For ex you can try doing
public void t2() {
super.t1();
System.out.println("child11");
}
Casting to Parent also won't work still your underlying element is Child.
So you cannot access from outside of Child class in a clean way. Don't exactly know if they is any naive way to do that.
Your understanding is correct. Without changing one of classes Testabstract or Testconcrete there is no way to invoke the original method on an instance of Testconcrete.
I don't think it's even possible to do it with reflection.
Related
While refactoring I came across the following method in a subclass:
public void disposeResultsTable() {
super.disposeResultsTable();
}
What are the benefits to keeping this method rather than simply allowing the inherited superclass method to be called?
The only technical reason I can think of is what Michael proposed in the comments - making a restricted method become public.
However, I can think of a few human reasons.
For instance, this could be a convenient place to place a breakpoint for debugging invocations of disposeResultsTable of the child class. Or perhaps this was meant as a placeholder - "remember to implement this method for this class", or maybe someone wanted to explicitly point out to the reader of this code that this class uses the parent's implementation of disposeResultsTable. There are probably a bunch more options.
Have you tried looking up the history of this piece of code in the VCS? Maybe there's a helpful commit message from the original author.
The answer by Malt shows a common reason for overriding a method trivially by only calling the super implementation, namely to change the visibility from protected to public. Whether or not this might be the case in your example depends on the visibility of the respective method in the superclass...
However, there is another possible reason - although it might be a bit far-fetched and unusual - and this possible reason is reflection: The Class#getDeclaredMethods method only returns the methods that are... well, declared in this class.
For example, consider the following program:
import java.lang.reflect.Method;
public class TrivialOverride
{
static class BaseClass
{
void method0() {}
void method1() {}
}
static class ChildClass extends BaseClass
{
void method0() {}
}
public static void main(String[] args)
{
printDeclaredMethods(BaseClass.class);
printDeclaredMethods(ChildClass.class);
}
private static void printDeclaredMethods(Class<?> c)
{
System.out.println("Declared methods in " + c.getSimpleName());
for (Method m : c.getDeclaredMethods())
{
System.out.println(m.getName());
}
System.out.println();
}
}
The output is
Declared methods in BaseClass
method0
method1
Declared methods in ChildClass
method0
So method0 only appears in the list of declared methods of the child class because it was overridden from the base class.
Is it possible to enforce an overriden method to call the superclass method? Constructors always need to call their superclass constructor. But i want to enforce this on normal methods, without the position of when it is called mattering.
Example:
public class A {
public void doSth() {
System.out.println("I must appear on console!");
}
}
public class B extends A {
#Override
public void doSth() {
System.out.println("Bla!"); // IDE should mark an error, because supermethod is not called.
}
}
No, that is not possible. It is entirely up to the overriding method to call the superclass method, or not.
However, there is a way to do it, if you want to enforce control.
This is called the Template Method Pattern. Whether the template methods are abstract or stubs (like shown here), depends on whether they must do something, or simply allow something extra to be done.
public class A {
public final void doSth() { // final, preventing override by subclasses
beforeDoSth();
System.out.println("I must appear on console!");
afterDoSth();
}
protected void beforeDoSth() { // protected, since it should never be called directly
// Stub method, to be overridden by subclasses, if needed
}
protected void afterDoSth() {
// Stub method, to be overridden by subclasses, if needed
}
}
public class B extends A {
#Override
protected void afterDoSth() {
System.out.println("Bla!");
}
}
If you then execute new B().doSth(), you'll get:
I must appear on console!
Bla!
No, it is not possible. If you allow a method to be overridden at all (by not declaring it or its class final) then you cannot control much of anything about the implementation of methods that override it. You can, however, document that such methods should invoke the superclass's version. There's only so much you can do to protect your users from themselves.
You may also find that there are alternative designs that would suit you better. For example, if you want to allow subclasses to override particular details of a computation, but not to override the whole computation altogether, then you could employ the Template Method pattern. In that case, the computation is driven by one "template" method, which you can declare private or final if you wish, and the customizable details are implemented in a separate, non-final, public or protected, possibly abstract method that the driver method calls where appropriate.
Although not strictly Java related, I was looking for an answer to this issue as it relates to Android and found the annotation in the support annotations library called "#CallSuper". It does exactly what you think, and throws a lint error if the subclass does not call the super's implementation of methods annotated with #CallSuper.
That solved my usecase, but again, I know that the solution is strictly tied with Android. Please let me know if that is too far off base and I will remove the answer.
Here is some more documentation on #CallSuper.
https://developer.android.com/reference/android/support/annotation/CallSuper.html
https://developer.android.com/studio/write/annotations.html (just search for CallSuper and it'll show right up in that second link.
No, it is not possible. It is up to the overriding method to call or to not call the method that it overrides.
Yes, it's possible, given the following constraints:
The method has a non-void return type
Subclasses (or other classes accessible by the subclasses) cannot create instances of the return type
As #Andreas pointed out, the super call could still be avoided by returning null. In practice, this shouldn't be a problem, but it's reasonable to enforce non-nullness in the contract (super class documentation) and also by using a null-preventing annotation, e.g. #Nonnull, so that any modern IDE can give a compile error when the super class method is not called.
For example:
import javax.annotation.Nonnull;
public class A {
public static final class Result {
private Result() {
// declare constructor private so the class cannot be
// instantiated from outside
}
}
/**
* Does something.
*
* #return the result; never {#code null}
*/
public #Nonnull Result doSth() {
System.out.println("I must appear on console!");
return new Result();
}
}
//...
public class B extends A {
#Override
public #Nonnull Result doSth() {
System.out.println("Bla!");
// only way to get a Result instance is through super.doSth()
Result res = super.doSth();
/* manipulate the result as needed */
return res;
}
}
Given this class:
abstract class Foo{
public Foo(){...}
public abstract void checkable();
public void calledWhenCheckableIsCalled(){
System.out.println("checkable was called");
}
}
Is there any code I can put in Foo's constructor to make calledWhenCheckableIsCalled get called when checkable is called?
Note: This is a gross simplification of an actual project I am working on.
Edit: I have already implemented a template pattern workaround. I just wondered if there was another way to do this I am missing. (Perhaps using reflection.)
Looks like a template method pattern.
But then you must implement Foo.checkable() and introduce another abstract method to delegate to.
abstract class Foo{
public Foo(){}
public void checkable(){
calledWhenCheckableIsCalled();
doCheckable();
}
protected abstract void doCheckable();
public void calledWhenCheckableIsCalled(){
System.out.println("checkable was called");
}
}
I would also suggest to make checkable() final in this case so that you can be sure that checkable() can not implemented in another way as you expected.
In addition to Brian Roach's comment
The downside is that the protected can be expanded to public in the subclass, so you can't explicitly enforce it.
That's true, but you can prevent a Foo instance from being instantiated if a subclass increases the visibility of doCheckable. Therefore you have to introduce a verification whenever an object is instantiated. I would recommend to use an initializer code so that the verification is executed on every constructor that exists. Then it can not be forgotten to invoke and therefore be by-passed.
For example:
abstract class Foo {
{ // instance initializer code ensures that enforceDoCheckableVisibility
// is invoked for every constructor
enforceDoCheckableVisibility();
}
public Foo() {...}
public Foo(Object o) {...}
private void enforceDoCheckableVisibility() {
Class<?> currentClass = getClass();
while (currentClass != Foo.class) {
try {
Method doCheckableMethod = currentClass.getDeclaredMethod("doCheckable");
if (Modifier.isPublic(doCheckableMethod.getModifiers())) {
throw new RuntimeException("Visibility of "
+ currentClass.getSimpleName()
+ ".doCheckable() must not be public");
}
} catch (SecurityException | NoSuchMethodException e) {}
currentClass = currentClass.getSuperclass();
}
}
}
Since the check is implemented using reflection the downside is that it is only checked at runtime. So you will not have compiler support of course. But this approach let you enforce that an instance of a Foo can only exist if it fulfills your contract.
No, the constructor will get invoked once during the object initialisation. You can however get your subclass that provides the implementation to call the method in the super class:
class Bar extends Foo {
// implementation of abstract method
public void checkable(){
super.calledWhenCheckableIsCalled(); // call to parent's method
...
}
}
EDIT
You could achieve this with aspects. Using an aspect you can intercept each call to a method by referring to the abstract parent method. This leaves you free from interfering eith the child code. Your calledWhenCheckableIsCalled code would then become part of the intercepting code.
abstract class Foo {
// use pointcut to intercept here
public void checkable();
}
There is no way as you are forcing that method to implement in child.
An awkward suggestion will be know from child implementation. I mean there is no clean way AFAIK
abstract class foo {
public abstract void bar();
public void moo() {
System.out.println("some code");
this.bar();
System.out.println("more code");
}
}
now if moo is called, the underlying implementation of bar will be used, it is just a small paradigm shift from what you want.
so your end user would call moo instead of bar, but he still needs to implement bar
Nope, an abstract method doesn't have a body. You could, however, chain your method like this:
abstract class Foo {
void callMeInstead() {
// do common
callMeImplementation();
}
abstract void callMeImplementation();
}
It looks to me like you're looking for the template pattern:
public abstract class Template {
public final void checkable() {
calledWhenCheckableIsCalled();
doCheckable();
}
protected abstract void doCheckable();
private void calledWhenCheckableIsCalled() {
System.out.println("checkable was called");
}
}
Now, each time checkable() is called, calledWhenCheckableIsCalled() is also called. And the suclass must still provide the actual implementation of checkable(), by implementing the doCheckable() method.
Note that making checkable() final prevents a subclass from overriding it and thus bypassing the call to calledWhenCheckableIsCalled().
This problem just bit me, its pretty easy to forget to call super() when overriding a method.
In my case I was refactoring some existing stuff where there were already about ten classes overriding a method. Until yesterday the method had an empty default implementation, so it didn't matter if subclasses called super or not.
You can find the overriders just fine with any IDE worth its salt, but you know how it is, phone rings, colleagues have a smalltalk behind you back... its easy to forget to check a place or otherwise overlook it.
Ideally there would be a counterpart for the #Override annotation and the compiler would generate a warning for those places if the base class method is annotated but the override doesnt call super.
Whats the next best thing I can do?
Not quite elegant, but possible solution is to break that method into two:
public abstract class Foo {
public void doBar() {
// do your super logic
doBarInternal();
}
public abstract void doBarInternal();
}
If the superclass implementation MUST ALWAYS be called you could use the 'template method' pattern.
So what you have now is something like:
public static class Parent {
public void doSomething() {
System.out.println("Parent doing something");
}
}
public static class Child extends Parent {
public void doSomething() {
// MUST NOT FORGET SUPER CALL
super.doSomething();
System.out.println("Child doing something");
}
}
public static void main(String[] args) {
Child child = new Child();
child.doSomething();
}
And this would become:
public abstract static class Parent {
public final void doSomething() {
System.out.println("Parent doing something");
childDoSomething();
}
public abstract void childDoSomething();
}
public static class Child extends Parent {
public void childDoSomething() {
System.out.println("Child doing something");
}
}
public static void main(String[] args) {
Child child = new Child();
child.doSomething();
}
(classes are made static for easy testing within one class)
I made doSomething final to avoid it being overridden since in this solution childDoSomething should be implemented instead.
Of course this solution means Parent can no longer be used as a concrete class.
EDIT: after reading comments about Child implementing a third party interface; this does not need to be a problem:
public interface ThirdPartyInterface {
public void doSomething();
}
public abstract static class Parent {
public final void doSomething() {
System.out.println("Parent doing something");
childDoSomething();
}
public abstract void childDoSomething();
}
public static class Child extends Parent implements ThirdPartyInterface{
public void childDoSomething() {
System.out.println("Child doing something");
}
// public final void doSomething() {
// // cannot do this because Parent makes it final
// }
}
public static void main(String[] args) {
Child child = new Child();
child.doSomething();
}
Loooking for something else I found interesting OverrideMustInvoke annotation in FindBugs:
http://findbugs.sourceforge.net/api/edu/umd/cs/findbugs/annotations/OverrideMustInvoke.html
If you do not insist on compile time safety you could use a mechanism that throws an exception whenever a subclass does not behave as logically required: How do I force a polymorphic call to the super method?
I have 2 different suggestions:
1) Build a junit test that discovers all subclasses of your base class, and then selects all the methods decorated with the #Override annotations. I have some unit tests that do something similar (i.e. find all subclasses, check that they truly are Serializable for example).
Unfortunately, the verification of whether they call "super" is a little less straightforward. You would either need to have the test look up the source file, and search it, or better (but I don't know how to do this), read the byte code and see if you can detect the call to super.
2) Needing to guarantee a call to super is probably an indicator of a design/interface issue, rather than a coding/implementation issue. If you really want to guarantee that users call super, it would be better to make the super class abstract, clearly designate an abstract implementation method for them to override, and have the super control the flow of execution.
If you want to define a default implementation, so that not all users need to subclass provide implement that method, you could define a default implementation class for people to use. (And if you really want to control it, define that default class implementation method as final to force them to go back to subclassing the abstract parent.)
Code reuse inheritance is always harder to manage, and so it needs to be done carefully. Anyone doing code reuse inheritance has to have a good idea of the internals of the super class to do it right (which is a bit yucky). For example, do you have to call super.method() at the beginning of your overriding code, or at the end? (or could you do it in the middle...)
So in summary, the best solution is to try avoid a design where you have to enforce that.
What could work - creating some marker annotation (i.e. #MustCallParent) and then create some annotation processor to check that methods marked with it comply to the constraint.
First things first, please be aware I am trying to express my question as best I can with my current knowledge and vocabulary, so please excuse this...
I have an abstract class in which I want to make a method where it instantiates itself.... Of course this is impossible in an abstract class, however, what I really want is for the concrete children (those classes that "extends") to inherit this instantiation so that they then can instantiate themselves....
Basically what I want to do is this:
MyAbstract a = new this();
However this isn't allowed... Is there any way I can do what I want?
Here is some non-compiling dream-code (i.e. code I wish worked). Basically I am wanting the ConcreteChild to call a method in which it create an object of itself. The method is inherited from it's parent.
public class Abstract {
public void instantiateMyConcreteChild()
{
Abstract a = new this();
}
}
public class ConcreteChild extends Abstract{
public static void main(String[] args) {
ConcreteChild c = new ConcreteChild();
c.instantiateMyConcreteChild();
}
}
* Additional info **
Thanks for the replies but I think I missed something vital....
Basically I wanted to pass an object's self ( "this" ) into some methods of some other classes. However, creating instantiating another object within an object is a bit backwards, I can just pass "this", right...
You can do this using reflection, something like :
Abstract a = getClass().newInstance();
This is because getClass() always returns the concrete class, so this.getClass() will return the real subclass and not the current class.
However, beware that if the subclass defines a custom constructor, having more or less parameters than your abstract class, it could fail. Unless you specify in the documentation that subclasses must have a constructor with such given parameters ... but it's fragile anyway.
You can inspect it, using getClass().getConstructors() and see which constructors are there, and if there is the one you are expecting, or even search for a viable one, otherwise you can catch the exception thrown by newInstance(..), and wrap it in a more descriptive exception for the users, so that they understand better what they missed ... but it would still be a kind of a hack, cause there is no explicit language support for such a situation.
Another approach could be to implement Cloneable in your abstract class, and then use the clone method, but it could be overkill or even wrong if what you want is a new, clean instance.
You can't do this using an instance method. Because as the name implies an instance methods requires that the instance has already instantiated.
What you actually need to do here is to separate the non-changing internal functionality from the abstract class itself. So what I could do is to ,for e.g., have an inner class that really encapsulates the non-changing functionality like so:
public class Abstract {
public void instantiateMyConcreteChild()
{
Abstract a = new NonChangingOperations();
}
class NonChangingOperations
{
public void operationA() {}
}
}
Infact you really dont need to keep the class NonChangingOperations as an inner class, you could make it as an external utility class with its own class hierarchy.
Are you trying to define a constructor that the subclasses of Abstract can use? If so you could simply do it the same way you define any other constructor.
public class Abstract {
Abstract() {
//set fields, etc. whatever you need to do
}
}
public class ConcreteChild extends Abstract{
ConcreteChild() {
//call superclass's constructor
super();
}
}
Could you just have this ?
public abstract class AbstractClassWithConstructor {
public AbstractClassWithConstructor() {
init();
}
protected abstract void init();
}
FYI
In the objective-c you need to set this by calling method init. The the method init() would look like this:
protected AbstractClassWithConstructor init() {
return this;
}