Java Method Overriding - accessing methods in parent - is this possible? - java

Let's say I create an instance of a class and override one of its methods at the same time - like this
MyClass fred = new MyClass() {
#Override
public void mymethod() {
super.mymethod();
//call something here
}
};
Now let's imagine I want to call a local method which has the SAME name and SAME (lack of) parameters as my overridden method - e.g. I have
public void mymethod() {
//my stuff in here
}
How can I call that from within the overridden method (on the line //call something here)???
Is that even possible? Using
this.mymethod();
causes an endless loop (the overriden method is simply calling itself)
Is there a way of accessing this method (other than via a static reference perhaps?)
Sorry if this is a common question - it's a hard thing to search for and the one question I found had no replies and wasn't really that well-phrased so I'm trying myself!!

I don't have a complier handy so I'm not 100% sure here, but try this:
ParentClass.this.myMethod();

An ugly, but functioning solution:
final MyOtherClass parent = this;
MyClass fred = new MyClass() {
#Override
public void mymethod() {
super.mymethod();
parent.mymethod();
}
};
I'm struggling to see the scenario where you need to do this for naming purposes, but it's useful to know that this in the anonymous class will refer to the anonymous class, not the "parent"; so if you find the need to access the parent's method it's a useful technique.
FWIW, here's a working example.

I am not sure if I fully understood the question but my guess is that you want something like this:
public class ParentClass {
public void mymethod() {
....
}
public void someOtherMethod() {
MyClass fred = new MyClass() {
#Override
public void mymethod() {
super.mymethod();
//call something here
ParentClass.this.mymethod();
}
}
}
}
Note ParentClass.this.mymethod()

Related

Is there any best practice on java Super.call?

public boolean sendRequest(final Object... params) {
if (!super.sendRequest(params)) {
return false;
}
...
// Some Log code or tracing code here
...
}
Why not implement a new method to call sendRequest rather than overwrite?
public boolean Send(final Object... params){
if (!super.sendRequest(params)) {
return false;
}
...
// Some Log code or tracing code here
...
}
Do you want your class with the override to be able to be used in the same way as members of the original class? i.e.:
...
class MyClass extends TheirClass {
#Override
void doIt() {
super.doIt();
// also do my stuff
}
}
...
// the doSomething function is part of the library where TheirClass lives.
// I can pass instances of MyClass to it, and doIt will be called, because MyClass IS-A TheirClass
theirFunction.doSomething(new MyClass(...));
...
But perhaps you just want to use the functionality of doIt, but don't need to use and code which expects a TheirClass.
In that case it is probably better to use composition rather than inheritance:
class MyClass {
private final TheirClass theirClass;
public MyClass(TheirClass theirClass) {
this.theirClass = theirClass;
}
public void doMyStuff() {
theirClass.doIt();
// and do some other things
}
}
This is better than inheritance with a new method name, because then you would have two methods on the class which do about the same thing (except the original doIt doesn't do your stuff), and it may not be clear which should be called.
Even inheritance where you override the method may have problems. We don't know what code in TheirClass calls doIt, so perhaps the code we've added will be called when we don't expect it to be.
Overall, composition should be preferred to inheritance whenever possible.

Check is instance method is called from a constructor

I would like to check, from an instance method of a non-final class, whether the constructors and initializers of that class and its chain of subclasses for the specific instance have already completed.
In the following example, I have a class Abstract, which can be used to implement an interface which allows listeners to be added (which, for simplicity, are just Runnable instances here) and which provides a method signalEvent() which calls all attached listeners.
abstract class Abstract {
protected final void signalEvent() {
// Check that constructs have run and call listeners.
}
public final void addListener(Runnable runnable) {
...
}
}
class Concrete extends Abstract {
Concrete() {
// Should not call signalEvent() here.
}
void somethingHappened() {
// May call signalEvent() here.
}
}
Now it is possible to call signalEvent() from within the subclass constructor, but there is no way that a listener has already been added by that time and the event would just be lost. In our code-base, once in a while, someone adds such a call and I would like to be able to catch such calls as early as possible (using an assert statement or similar).
Is it possible to check whether an instance method is being called, directly or indirectly, from the subclass constructor or initializer of the current instance or, alternatively, is it possible to check whether all constructors for an instance have been completed?
In short, there is no elegant Java mechanism that allows you to do that, but you may consider using a factory pattern. Instead of creating instances directly using new keyword, you could create a factory class, that takes care of creating the actual instance and invokes an additional "post-create" method, that lets the instance know it's been completely created.
If you're using some dependency injection like spring, you get that out of the box, but if not, a solution could look something like this:
interface PostConstruct { // the classes need to implement that
void postConstruct();
}
public class InstanceFactory {
public <T extends PostConstruct> T create(Class<T> clazz, Object... params) {
T instance = //create using reflection
instance.postConstruct();
return instance;
}
}
A solution to the problem to see if a method or code is being called from a constructor. The code below will print true and false respectivly but would be slow and not pretty at all.
I still believe it is not the right solution for the problem above. As Codbender said, better to check if a listener has been added or set a status variable which would be faster
Edit - fixed the issue that Codebender mentioned and also made sure to check back in the stack trace incase of being called a couple of methods deep
public class TestClass extends TestAbstract {
public TestClass() throws Exception {
submethod();
}
public void submethod() throws Exception {
System.out.println(isInConstructor());
}
public static void main(String[] args) throws Exception {
System.out.println(new TestClass().isInConstructor());
}
}
public class TestAbstract {
public boolean isInConstructor() throws Exception {
StackTraceElement[] elements = Thread.currentThread().getStackTrace();
for (StackTraceElement element : elements) {
if (element.getMethodName().equals("<init>") &&
TestAbstract.class.isAssignableFrom(Class.forName(element.getClassName()))) {
return true;
}
}
return false;
}
}

Using different method depending on class in Java

I'm trying to reduce some code duplication. Currently i got two methods that are almost identical, the major difference being calling two separate methods within them.
Below is basically what i wanna do:
private void combinedMethod(StandardClass sc, MyClass mc)
{
Method m = null;
if(mc instanceof MySubClass1)
m = sc.RelevantFor1();
if(mc instanceof MySubClass2)
m = sc.RelevantFor2();
m(mc.getA(), mc.getB());
}
I've tested (and it works) this using reflection. But is there a better way of doing it? I read somewhere that reflection is slow and only to be used as a last resort. Is it in this case?
Also in this case the StandardClass is a standard class in the java api. The Class I send in is of my own making.
It isn't clear how exactly those methods look like, or what they are doing, but it seems like a perfect polymorphism case. You can create a method in super class - MyClass I suppose in this case. And override those methods in your subclasses.
Now, when you call that method on MyClass reference, appropriate subclass method will be called based on actual instance. Now invoke whatever method you want to invoke in respective overridden methods.
Somewhere along the lines of:
class MyClass {
public void method(StandardClass sc) { }
}
class MySubClass1 extends MyClass {
public void method(StandardClass sc) {
sc.method(getA(), getB());
}
}
class MySubClass2 extends MyClass {
public void method(StandardClass sc) {
sc.anotherMethod(getA(), getB());
}
}
And then your combinedMethod looks like:
private void combinedMethod(StandardClass sc, MyClass c) {
c.method(sc);
}

Remove/Deprecate a method in subclass

I want to remove a method from a class that is present in it's super class. I can deprecate the superclass method using the #Deprecated annotation, but it is still accessible in the subclass.
Eg:
public class Sample {
void one() {}
void two() {}
#Deprecated
void three() {}
}
class Sample2 extends Sample {
#Override
void one() {}
public static void main() {
Sample2 obj = new Sample2();
obj.one();
obj.two();
obj.three();// I do not want to access this method through the sample 2 object.
}
}
While using the Sample2 object I only want methods one and two to be available. Please advice on how to do this.
Thanks a lot.
Override three() in Sample2 and throw an exception if that method is accessed.
There is nothing you can do at compile-time. You cannot have a subclass with less methods than a superclass. Best you can do is make a runtime error like #Sudhanshu proposes, and maybe some tooling (like custom FindBugs rules) to flag it an error in your IDE.
Use the private access level modifier in front of methods that should only be accessed in their own classes.
public class Sample {
void one() {}
void two() {}
#Deprecated
private void three() {}
}
One idea for hiding the interface of another class while still using it is to wrap it with your own object (i.e. don't subclass).
class MySample {
private Sample sample;
//maybe other stuff
public MySample(){
sample = new Sample();
}
void one(){
return sample.one();
}
}
This is potentially unsatisfactory: not wanting to use Sample in the entire way it was intended while simultaneously wanting to hijack and extend its behavior. It solves the problem of ever calling three() on your backing Sample.

Define the methods of anonimous class created inside a method from the method caller

in a class i have
A a = new A(){
stuffhere
};
now i found that i need to create the new A inside a method and return it, but i have to define the stuffhere from the class caller. Is there a way in java to do so? Something like
A a = createAClass(){
stuffhere
};
public A createAClass()[T]{
return new A(){T};
}
or something similar. I would prefer not to use an interface to pass to the create method, since my anonymous classes not only override methods, but also adds attributes and new functions, and i don't think i can pass them with an interface..
Any thought?
EDIT for the -1ers (a simple comment would suffice)
with the syntax [T], obviously wrong, i meant something that can pass a generic code, let's say a copy-paste of code.
createAClass()[int a; String b; #override public void mymethod(){dosomethigb;} public void dosomethingelse(){dosomethingelse;}];
would work like
public A createAClass(){
return new A()
{
int a;
String b;
#override public void mymethod()
{dosomethigb;}
public void dosomethingelse()
{dosomethingelse;}};
};}
but if i write in another part of the program
createAClass()[float c; List d; public void yourmethod(){dosomething2;} #override public void dosomethingelse(){dosomethingelse2;}];
it would instead work like
public A createAClass(){
return new A()
{
float c;
List d;
public void yourmethod()
{dosomething2;}
#override public void dosomethingelse()
{dosomethingelse2;}
};}
My bad, i choose a bad may of making an example, but i thought it was the clearest way. Maybe i should have used X instead of T?..
Long story short:
i want create an anonymous class inside a method, but define what the anonymous class does in the method caller, and not inside the method(like the title says)
EDIT2:
i know i can't access the new methods from the class, what i do now is create an anonymous class, add a few attributes and method, and then use them in an overridden method. The added methods are not a problem, since i can make the method caller to pass an interface that is called by the overridden method in the anonymous class created, the problems are the attributes. I don't know how to add them in the anonymous class passing them from the method caller.
Something like the following usually works:
public A createAClass(final String value){
return new A(){
// some code here that can access value
};
}
If you are looking for something else, please clarify the question.
Edit
Answer is no you can't do that. You are trying to create an A with no defined API for A. Even if you could do what you propose, how would any user of A know what methods / fields are available if A is not defined somewhere? For A to be useful, you need to have an API that A implements.
Not sure whether fully understood by me. But the pattern is like this:
public class Here {
private int stuff;
public class A {
private A() { ... }
... ++stuff; ...
}
public A createA() { ... }
}
...
Here here = ...
A a = here.createA();
AFTER QUESTION EDITED:
The simplest way is to override a method:
final Object stuff = ...;
A a = new A() {
#Override
protected void onSomeEvent() {
... stuff.toString();
}
}
Then A can call onSomeEvent.

Categories