What's the default behaviour of subclass method without using super? - java

Is there a possibility to have some default behaviour defined for a method in a subclass, without having to call super?
E.g: Suppose we want to set a boolean value in the superclass and you want to hide this from the subclass, is there a way to hide the modification of the boolean value? Suppose that we have the following base class BaseTest
public class BaseTest {
private boolean mIsInitialized = false;
public BaseTest() {
}
public void initialize() {
mIsInitialized = true;
}
}
and its subclass Test:
public class Test extends BaseTest {
public Test() {
}
public void initialize() {
}
}
I would like for the call to Test.initialize() to set the mIsInitialized value to true without having to call super.initialize(). I would equally like to avoid to define an abstract function in the superclass.
Is this even possible?

It is possible to do this, but not by overriding initialize. In the BaseTest class, mark initialize as final so it cannot be overridden. In initialize, call another method to do any subclass initialization.
public final void initialize() {
mIsInitialized = true;
initializeFurther();
}
You said no abstract methods. But, initializeFurther can just be made empty.
protected void initializeFurther() {}
Then, the subclass Test just needs to override initializeFurther.
public class Test extends BaseTest {
#Override
protected void initializeFurther() {
// Initialize Test here.
}
}
The base class's initialize method is guaranteed to set mIsInitialized to true, and Test can implement initializeFurther however it wants, without calling super.initialize(). Test can't stop the superclass BaseTest from doing its initialization.
When initialize is called on any BaseTest instance, the initialize logic will always run.

#rgettman et al. are calling for using the Template pattern. Therein you make explicit the fact that subclasses may "hook in" to the superclass's action through specific overridable methods that are not initialize, which seems to go against the spirit of your question.
You can also use an aspect-oriented framework like AspectJ to have all kinds of invisible behaviors attached to method calls.

If you prevent Test from overriding BaseTest's initialize(), you can call BaseTest's initialize() directly. Here's some test code:
public class BaseTest {
private boolean mIsInitialized = false;
public BaseTest() {
}
public void initialize() {
mIsInitialized = true;
System.out.println(mIsInitialized);
}
public static void main(String[] args){
Test test = new Test();
test.initialize();
}
}
class Test extends BaseTest {
public Test() {
}
}

Related

Call of super.method automatically [duplicate]

Consider the following class
class A{
public void init(){
//do this first;
}
public void atEnd(){
//do this after init of base class ends
}
}
class B1 extends A{
#Override
public void init()
{
super.init();
//do new stuff.
//I do not want to call atEnd() method here...
}
}
I have several B1, B2,... Bn child classes which are already developed. All of them extend class A. If I want to add a new functionality in all of them, the best place to do so is define that in a method within class A. But the condition is that the method should always get called automatically just before the init() method of child class ends.
One basic way to do so is to again add atEnd() method call at end of init() method of child classes. But is there any other way to do this smartly ??
One way to do this is by making init() final and delegating its operation to a second, overridable, method:
abstract class A {
public final void init() {
// insert prologue here
initImpl();
// insert epilogue here
}
protected abstract void initImpl();
}
class B extends A {
protected void initImpl() {
// ...
}
}
Whenever anyone calls init(), the prologue and epilogue are executed automatically, and the derived classes don't have to do a thing.
Another thought would be to weave in an aspect. Add before and after advice to a pointcut.
Make init() final, and provide a separate method for people to override that init() calls in the middle:
class A{
public final void init(){
//do this first;
}
protected void initCore() { }
public void atEnd(){
//do this after init of base class ends
}
}
class B1 extends A{
#Override
protected void initCore()
{
//do new stuff.
}
}
The other answers are reasonable workarounds but to address the exact question: no, there is no way to do this automatically. You must explicitly call super.method().

Java method that can't be callable but can be overridden

If I don't want that a method on my class can be called, I just make it private.
But if I want to allow that method to be overridden, I have to make it protected
Is it possible to have a method on an abstract class that can't be called but can be overridden? (I guess not, but is there any workaround?)
Use case:
abstract class Super {
protected void finalize() {
}
public final void doThings() {
// do stuff
finalize();
}
}
and whoever wanted to extend the class:
class Sub extends Super {
#Override
protected void finalize() {
closeSockets();
alertSomeone();
}
}
But I don't want other classes calling mySub.finalize();
Instead of overwriting a method, the sub-class may provide the super-class with a Runnable which contains the code to be executed. You could do something like this:
public class Super {
private final Runnable subClassCode;
public Super(Runnable finalizeCode) {
subClassCode = finalizeCode;
}
public final void doThings() {
// do stuff
subClassCode.run();
}
}
public class Sub extends Super {
public Sub() {
super(() -> {
// code to be executed in doThings()
});
}
}
You dont need to set the Runnable instance in the constructor. You may also give access to a protected setFinalizeCode(Runnable) method but that method could also be called by other classes within the same package as Super.

how to mock private static inner class?

I have a class like
public class Enclosing {
public String methodA() {
Inner.getContext();
......
}
private static class Inner{
// some context init
public static Context getContext() {
.....
}
}
}
Now I want to test methodA without invoking the real Inner.getContext(). I have been searching all over but cannot find a working solution. I am using Java 8. Can I have some help please? Many thanks
You can apply the extend and override technique, here's how it works.
Given this code:
public class Enclosing {
public String methodA() {
Inner.getContext();
......
}
You can move the Inner.getContext() call to a protected method:
public class Enclosing {
public String methodA() {
getContext();
......
}
protected void getContext() {
Inner.getContext();
......
}
And then in your test case, you can extend the enclosing class, and override the protected method to do whatever you want with it:
#Test
public void test_something() {
Enclosing enclosing = new Enclosing() {
#Override
protected void getContext() {
// do what you need here
}
};
// your test code on enclosing where you control getContext
}
As an alternative to #janos' answer, you can inject a strategy (basically, the "prefer composition over inheritance" approach):
interface ContextStrategy {
void getContext();
}
and then inject an instance of this into the constructor of Enclosing:
class Enclosing {
private final ContextStrategy ctxStrategy;
Enclosing(ContextStrategy ctxStrategy) {
this.ctxStrategy = ctxStrategy;
}
String methodA() {
ctxStrategy.getContext();
// ...
}
}
and then implement this interface for the production case, as a nested class in Enclosing:
static class ContextStrategyImpl implements ContextStrategy {
#Override public void getContext() {
Inner.getContext();
}
}
and implement an alternative version for your mock case.
You should not mock a private class (whether it is a nested class like the one here or an actual inner class).
Instead, mock only the Context type if it's really needed (otherwise, use a real Context object). For example, such a test is shown below, using the JMockit library:
#Test
public void mockingTheContext(#Mocked Context anyContext) {
new Expectations() {{
// record any method call results expected from "anyContext"
}};
new Enclosing().methodA();
new Verifications() {{
// verify calls to "anyContext", if applicable
}};
}
In the test above, the fact that Context is created inside a nested class is irrelevant. In general, mocking private methods or classes should always be avoided, since they are only implementation details.

Warn developer to call `super.foo()` in java

Lets say I have these two classes, one extending the other
public class Bar{
public void foo(){
}
}
public class FooBar extends Bar {
#Override
public void foo(){
super.foo(); //<-- Line in question
}
}
What I want to do is warn the user to call the super-class's method foo if they haven't in the override method, is this possible?
Or is there a way to know, using reflection that a method that overrides a method of its super-class calls the original method if I pass on the class type to the super?
for example:
public abstract class Bar{
public Bar(Class<? extends Bar> cls){
Object instance = getInstance();
if (!instance.getClass().equals(cls)) {
throw new EntityException("The instance given does not match the class given.");
}
//Find the method here if it has been overriden then throw an exception
//If the super method isn't being called in that method
}
public abstract Object getInstance();
public void foo(){
}
}
public class FooBar extends Bar {
public FooBar(){
super(FooBar.class);
}
#Override
public Object getInstance(){
return this;
}
#Override
public void foo(){
super.foo();
}
}
Maybe even an annotation I can put on the super method so it shows that it needs to be called?
EDIT
Note, its not the super class that needs to call the foo method, it would be someone calling the sub class's foo method, for example a database close method
I would even be happy with making the method "un-overrideable" if it came down to it, but would still like to give it a custom message.
Edit 2
This here is what I wanted in a way:
But it would still be nice to have the above, or even give them a custom message to do something else like, Cannot override the final method from Bar, please call it from your implementation of the method instead
EDIT: To answer the edited, question, which includes:
I would even be happy with making the method "un-overrideable"
... just make the method final. That will prevent subclasses from overriding it. From section 8.4.3.3 of the JLS:
A method can be declared final to prevent subclasses from overriding or hiding it.
It is a compile-time error to attempt to override or hide a final method.
To answer the original question, consider using the template method pattern instead:
public abstract class Bar {
public foo() {
// Do unconditional things...
...
// Now subclass-specific things
fooImpl();
}
protected void fooImpl();
}
public class FooBar extends Bar {
#Override protected void fooImpl() {
// ...
}
}
That doesn't force subclasses of FooBar to override fooImpl and call super.fooImpl() of course - but FooBar could do this by applying the same pattern again - making its own fooImpl implementation final, and introducing a new protected abstract method.
what you could do is something like following
public class Bar{
public final void foo(){
//do mandatory stuff
customizeFoo();
}
public void customizeFoo(){
}
}
public class FooBar extends Bar {
#Override
public void customizeFoo(){
//do custom suff
}
}
foo method made 'final' in superclass so that subclasses can't override and avoid doing mandatory stuff

Using abstract init() function in abstract class's constructor

I have something like this:
public abstract class Menu {
public Menu() {
init();
}
protected abstract void init();
protected void addMenuItem(MenuItem menuItem) {
// some code...
}
}
public class ConcreteMenu extends Menu {
protected void init() {
addMenuItem(new MenuItem("ITEM1"));
addMenuItem(new MenuItem("ITEM2"));
// ....
}
}
//Somewhere in code
Menu menu1 = new ConcreteMenu();
As you can see superclass's init method is abstract and is called by constructor automatically after object is created.
I'm curious if i can run into some sort of problems with code like this, when i need to create some object of this kind whose structure wont't be changed in time.
Would be any approach better? It works in Java, but will it work in C++ and possibly ActionScript?
Thank you for answer.
DO NOT INVOKE OVERRIDEABLE METHODS FROM THE CONSTRUCTOR.
A quote from Effective Java 2nd Edition, Item 17: Design and document for inheritance, or else prohibit it:
There are a few more restrictions that a class must obey to allow inheritance. Constructors must not invoke overridable methods, directly or indirectly. If you violate this rule, program failure will result. The superclass constructor runs before the subclass constructor, so the overriding method in the subclass will be invoked before the subclass constructor has run. If the overriding method depends on any initialization performed by the subclass constructor, the method will not behave as expected.
Here's an example to illustrate:
public class ConstructorCallsOverride {
public static void main(String[] args) {
abstract class Base {
Base() { overrideMe(); }
abstract void overrideMe();
}
class Child extends Base {
final int x;
Child(int x) { this.x = x; }
#Override void overrideMe() {
System.out.println(x);
}
}
new Child(42); // prints "0"
}
}
Here, when Base constructor calls overrideMe, Child has not finished initializing the final int x, and the method gets the wrong value. This will almost certainly lead to bugs and errors.
Related questions
Calling an Overridden Method from a Parent-Class Constructor
State of Derived class object when Base class constructor calls overridden method in Java
See also
FindBugs - Uninitialized read of field method called from constructor of superclass
You are right in that it might cause problems with a derived class whose instance variables are initialised in the constructor or when the instance is created.
If you had this:
public class ConcreteMenu extends Menu {
String firstItem = "Item1";
protected void init() {
addMenuItem(new MenuItem(firstItem));
// ....
}
}
Then the MenuItem would have null as it's constructor argument!
Calling non-final methods in constructors is a risky practise.
A simple solution could be to separate the construction and the initialisation, like so:
Menu menu = new ConcreteMenu();
menu.init();
As others mentioned, calling an overridable method from the constructor is entering a world of pain ...
Have you considered doing the initialization in the constructor itself?
public abstract class Menu {
public Menu() {
....
}
protected void addMenuItem(MenuItem menuItem) {
// some code...
}
}
public class ConcreteMenu extends Menu {
public ConcreteMenu() {
super();
addMenuItem(new MenuItem("ITEM1"));
addMenuItem(new MenuItem("ITEM2"));
// ....
}
}

Categories