Override a function without extending the class - java

Suppose I have a class A:
public class A {
public A(){....}
public void method1() {...}
};
And an instance of that class:
A anA = new A();
Is there any way to override the method1() only for anA?
This question arises when I write a small painting program in which I have to extend the JPanel class several times just to make minor changes to the different panels that have slightly different characteristics.

You can do the following:
A anA = new A() {
public void method1() {
...
}
};
This is the same as:
private static class myA extends A {
public void method1() {
...
}
}
A anA = new myA();
Only with the exception that in this case myA can be reused. That's not possible with anonymous classes.

You can create a an new anonymous class on the fly, as long as you are using the no-arg constructor of your class A:
A anA = new A() {
#Override
public void method1() {
...
}
};
Note that what you want to do is very close to what is known as a lambda, which should come along the next release 8 of Java SE.

I like to do this kind of thing with a delegate, or "strategy pattern".
public interface ADelegate {
public void method1();
}
public class A {
public A(){....}
public ADelegate delegate;
public final void method1() { delegate.method1(); }
};
A anA = new A();
anA.delegate = new ADelegate() {
public void method1() { ... }
};

Related

How to force derived class to call super class method at multiple layers?

I am trying to find the most elegant way to allow a child and parent to react to an event initiated by the grandparent. Here's a naive solution to this:
abstract class A {
final public void foo() {
// Some stuff here
onFoo();
}
protected abstract void onFoo();
}
abstract class B extends A {
#Override
final protected void onFoo() {
// More stuff here
onOnFoo();
}
protected abstract void onOnFoo();
}
class C extends B {
#Override
protected void onOnFoo() {
// Even more stuff here
}
}
So basically, I'm trying to find the best way to allow all related classes to perform some logic when foo() is called. For stability and simplicity purposes I prefer if it is all done in order, although it's not a requirement.
One other solution I found involves storing all the event handlers as some form of Runnable:
abstract class A {
private ArrayList<Runnable> fooHandlers = new ArrayList<>();
final public void foo() {
// Some stuff here
for(Runnable handler : fooHandlers) handler.run();
}
final protected void addFooHandler(Runnable handler) {
fooHandlers.add(handler);
}
}
abstract class B extends A {
public B() {
addFooHandler(this::onFoo);
}
private void onFoo() {
// Stuff
}
}
class C extends B {
public C() {
addFooHandler(this::onFoo);
}
private void onFoo() {
// More stuff
}
}
This method is certainly preferable to the first. However I am still curious if there is a better option.
Have you considered the Template Method pattern? It works well to define a high level method that delegates to derived types to fill-in the gaps.
What about this by calling the super method?
class A {
void foo() {
System.out.println("Some stuff here");
}
}
class B extends A {
#Override
void foo() {
super.foo();
System.out.println("More stuff here");
}
}
class C extends B {
#Override
void foo() {
super.foo();
System.out.println("Even more stuff here");
}
}

Invoking method of anonymous class

Java 7
First of all, I'm going to simplify the example to avoid posting unnecesary code. My specific concrete example a little bit complicated, but I' try to preserve the point.
public class Test {
public static void main(String[] args){
Test t = new Test(){ //<---------------------------------------------------------
public void m(){ // |
Test t = new Test(){// |
public void m(){// |
//Here I need to invoke the most inclosing class's m() method
}
//other actions
};
}
public void someMethod(){
//action
}
};
}
public void m(){
}
}
Is it possible to do in Java? I mean, to invoke the method of anonymous class that way?
No it's impossible because there is no reference to the anonymous classes.
This is the only possible way to call the instance m() method :
new Test(){
public void m(){
}
}.m();
By definition according to the oracle documentation here :
Anonymous classes enable you to make your code more concise. They
enable you to declare and instantiate a class at the same time. They
are like local classes except that they do not have a name. Use them
if you need to use a local class only once
So if you have to use one of the methods of your class you have to create a local one.
You cannot access the methods of the anonymous class using normal java, but you are able using reflection:
Test t = new Test{
public void m() {
System.out.println("Welcome to my class");
}
};
Class<?> c = t.getClass();
Method m = c.getDeclaredMethod("m");
// m.setaccessible(true); // if private
m.invoke(t);
Here is a way to do it:
public class Test
{
public static void main(String[] args)
{
Test t = new Test()
{
public void m() // this one will be called
{
Runnable r = new Runnable()
{
#Override
public void run()
{
m();
}
};
Test t = new Test()
{
public void m()
{
r.run();
}
};
}
};
}
public void m()
{
}
}
If the method returns a value, use Callable<V> instead.

Call super.super.method, skipping super.method

I have the following (third-party) class structure. We'll call the third-party project ProjectSeriously, and note that I'm using System.out.println in place of other complicated functionality (100s of lines of code).
class A {
public void hi() {
// Do an important thing
System.out.println("Important thing A");
}
}
class B extends A {
public void hi() {
// Do some terrible, terrible things
System.out.println("TERRIBLE THING B");
// Do that important thing
super.hi();
}
}
Now I want to write this (this isn't valid java):
class C extends B {
public void hi() {
// Do some not-so-terrible things
System.out.println("Ok thing C");
// Do that important thing
super.super.hi();
}
}
I have to pass an instanceof B to some other piece of this wonderful project, ProjectSeriously. Seeing as these are public methods, I feel like this should be possible.
You could use javassist to modify the class before any use of it.
But this is a really ugly hack, please try to refactor the code in A and/or B the expose the important parts.
package test;
import javassist.ClassPool;
import javassist.CtClass;
import javassist.CtMethod;
import javassist.CtNewMethod;
class A {
public void hi() {
// Do an important thing
System.out.println("Important thing A");
}
}
class B extends A {
public void hi() {
// Do some terrible, terrible things
System.out.println("TERRIBLE THING B");
// Do that important thing
super.hi();
}
}
class C extends B {
public void hi() {
// Do some not-so-terrible things
System.out.println("Ok thing C");
// Do that important thing
super.hi();
}
}
public class Main {
public static void main(String[] args) throws Exception {
CtClass cc = ClassPool.getDefault().get("test.B"); // don't use test.B.class.getName() as this force the class loader to load the class
CtMethod m1 = cc.getDeclaredMethod("hi");
cc.removeMethod(m1);
CtMethod m2 = CtNewMethod.copy(m1, cc, null);
m2.setBody("{ /* override method B.hi() body */ return super.hi();}", "this", m1.getName());
cc.addMethod(m2);
cc.toClass();
C obj = new C();
obj.hi();
}
}
Result:
Ok thing C
Important thing A
Unless you explicitly expose the method(s), which sort-of goes against the design pattern, there aren't many other options:
public class GrandParent {
public void hi() {
hiGrandParent();
}
protected final void hiGrandParent() {
System.out.println("Hi from grandparent.");
}
public static class Parent extends GrandParent {
#Override
public void hi() {
hiParent();
}
protected final void hiParent() {
System.out.println("Hi from parent.");
}
}
public static class Child extends Parent {
#Override
public void hi() {
hiChild();
super.hi();
hiParent();
hiGrandParent();
}
protected final void hiChild() {
System.out.println("Hi from child.");
}
}
}
Run with:
public final class RunIt {
public static void main(final String[] args) {
new GrandParent.Child().hi();
}
}
Expected output:
Hi from child.
Hi from parent.
Hi from parent.
Hi from grandparent.
This would break encapsulation in a terrible way (you'd essentially be disabling some part of class B's logic), and it shouldn't be possible in Java. I'm pretty sure it isn't possible.
Yeah its not really possible in a "standard" java way, also its a bad design decision but OP might not have access to the original class. I've faced this problem several times earlier with different jars.
If you want to skip for example a private method call in one of the super classes, but still need the other parts of the constructor code or the functionality of the superclasses, the only "easy" way to do this is to basically copy-paste that part of the code into your own class. For example if you have these classes:
public class Foo {
public Foo() {
importantFunctionality();
}
private void importantFunctionality() {
System.out.println("DOING IMPORTANT STUFF");
}
}
public class Bar extends Foo {
public Bar() {
super(); //constructor gets called
killAllBabies(); //I dont want this to get called, but its a private method meaning no overriding
solveWorldHunger(); //I want to call this, but this is a private method, so no calling this from child classes
}
private void killAllBabies() {
System.out.println("KILLING ALL BABIES");
}
private void solveWorldHunger() {
System.out.println("SOLVING WORLD HUNGER");
}
}
public class MyClass extends Bar {
public MyClass() {
super(); //Not good, because stuff I dont want gets called here
}
}
Only way to solve this is to "skip" the previous class and extend the original class and implement the functionality of the skipped class. Unfortunately this was an issue for us with a certain framework because of bad extendibility:
public class MyClass extends Foo {
public MyClass() {
super();
solveWorldHunger();
}
private void solveWorldHunger() {
System.out.println("SOLVING WORLD HUNGER");
}
}

How to substitute an abstract class with an interface in Java?

I have an abstract class Work with two abstract methods (init and work) and one concrete method (run) working with the abstract methods.
class work
{
abstract static class Work<T> implements Runnable
{
T data;
abstract protected void init ();
abstract protected void work ();
public void run ()
{
init();
work();
System.out.println (data);
}
}
public static void main (String[] args)
{
Runnable hello = new Work<String>() {
protected void init () { data = "Hello $1!"; }
protected void work () { data = data.replace ("$1", "World"); }
};
(new Thread(hello)).start();
}
}
In order to get rid of the multiple inheritance problem I would like to convert the abstract class into an interface. But in Java interfaces can not contain a body. So where do I have to put the generic data and method after converting the abstract class into an interface?
I fear that it is not possible to get rid of the multiple inheritance problem as long as I want to share anything concrete. Is this right?
You can do something like:
Create the Work interface
Create the AbstractWork class which is the abtract class implementing Work and containing the generic code
Create your implementation classes extending AbstractWork
That is exactly what is used in the JDK with List (the interface), AbtractList (the abstract class implementing List) and LinkedList and ArrayList (the implementation classes extending AbstractList).
You might have to separate the interface from the functionality; something like this:
public interface Work<T> {
void init();
T work();
}
public class Worker<T> implements Runnable {
private final Work<T> work;
Worker(Work<T> work) {
this.work = work;
}
public void run () {
work.init();
T data = work.work();
System.out.println(data);
}
}
public static void main (String[] args)
{
Runnable hello = new Worker<String>(new Work<String>() {
private String data;
public void init () { data = "Hello $1!"; }
public String work () { return data.replace ("$1", "World"); }
});
(new Thread(hello)).start();
}

Inheriting from two classes with Java?

I have made a class to include a custom title bar with my apps logo on it. This works well except that for the majority of my classes I need to be able to inherit that functionality as well as that of say a ListActivity. What to do?
Any help appreciated.
you should favor composition (and delegation) over inheritance :
public interface FirstClassInterface {
void method1();
}
public interface SecondClassInterface {
void method2();
}
public class FirstClass implements FirstClassInterface {
// ...
}
public class SecondClass implements SecondClassInterface {
// ...
}
public class FirstAndSecondClass implements FirstClassInterface , SecondClassInterface
{
private FirstClassInterface firstclass;
private SecondClassInterface secondclass;
public FirstAndSecondClass(FirstClassInterface firstclassinterface, SecondClassInterface secondclassinterface) {
this.firstclass= firstclassinterface;
this.secondclass= secondclassinterface;
}
public void method1() {
this.firstclass.method1();
}
public void method2() {
this.secondclass.method2();
}
public static void main(String[] args) {
FirstAndSecondClass t = new FirstAndSecondClass(new FirstClass(), new SecondClass());
t.method1();
t.method2();
}
}
In Java, you cannot have:
class MyClass extends ClassA, ClassB { ... }
Depending on what you are doing, it might be possible to use:
class ClassB extends ClassA { ... }
class MyClass extends ClassB { ... }

Categories

Resources