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.
Related
I want to create a wrapper class over another class so that it hides the functionality of wrapped class and also the wrapper provides certain methods of its own.
For example, lets say we have class A as
public class A{
void method1(){ ... do something ... }
void method2(){ ... do something ... }
void method3(){ ... do something ... }
}
Now I want another class B which wraps class A, so that it has its own methods, and also if someone asks method of class A, it should delegate it to class A.
public class B{
// if someone asks method1() or method2() or method3() ... it should delegate it to A
// and also it has own methods
void method4(){ ... do something ... }
void method5(){ ... do something ... }
}
I can't use inheritance (i.e B extends A) because its not easy with my use case (where A has concrete constructor with some parameters which we can't get ... but we can get the object of A).
I can't simply delegate each function in A using object of A (because there are several functions in A)
Is there any other way to obtain class B with said restrictions?
Important Note: Class A is handled by someone else. We can't change any part of it.
What you have described is a Decorator pattern coined by GOF. There is plenty of sources on the Internet about it. It is similar to the Proxy pattern (as in the answer of Pavel Polivka) but the intent is different. You need the Decorator pattern:
Attach additional responsibilities to an object dynamically. Decorators provide a flexible alternative to subclassing for extending functionality. sourcemaking.com
As you have written in a comment
class A inherits from single interface containing several methods
I assume A implements AIntf and contains all the methods you want.
public class BDecorator implements AIntf {
private A delegate;
private BDecorator(A delegate) {
this.delegate = delegate;
}
void method1(){ delegate.method1(); }
// ...
void method4(){ /* something new */ }
There are several functions in A, and I don't want to do tedious work of writing each method explicitly in B.
Java is a verbose language. However, you don't need to do this by hand, every decent IDE provides automatic generation of delegate methods. So it will take you 5 seconds for any amount of methods.
The class A is not in my control, I mean someone might update its method signatures, In that case I need to watch over class A and made changes to my class B.
If you create B you are responsible for it. You at least notice if anything changed. And once again, you can re-generate the changed method with the help of an IDE in an instant.
This can be easily done with CGLIB but will require few modifications. Consider if those modifications may not be harder to do that the actual delegation of the methods.
You need to extend the classes, this can be done by adding the no arg constructor to class A, we will still delegate all the methods so do not worry about unreachable params, we are not worried about missing data, we just want the methods
You need to have CGLIB on you classpath cglib maven, maybe you already have it
Than
A would look like
public class A {
private String arg = "test";
public A() {
// noop just for extension
}
public A(String arg) {
this.arg = arg;
}
public void method1() {
System.out.println(arg);
}
}
B would look like
public class B extends A implements MethodInterceptor {
private A delegate;
private B(A delegate) {
this.delegate = delegate;
}
public static B createProxy(A obj) {
Enhancer e = new Enhancer();
e.setSuperclass(obj.getClass());
e.setCallback(new B(obj));
B proxifiedObj = (B) e.create();
return proxifiedObj;
}
void method2() {
System.out.println("a");
}
#Override
public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
Method m = findMethod(this.getClass(), method);
if (m != null) { return m.invoke(this, objects); }
Object res = method.invoke(delegate, objects);
return res;
}
private Method findMethod(Class<?> clazz, Method method) throws Throwable {
try {
return clazz.getDeclaredMethod(method.getName(), method.getParameterTypes());
} catch (NoSuchMethodException e) {
return null;
}
}
}
That you can do
MyInterface b = B.createProxy(new A("delegated"));
b.method1(); // will print delegated
This is not very nice solution and you probably do not need it, please consider refactoring your code before doing this. This should be used only in very specific cases.
I was wondering if it's frowned upon that when designing an framework to be used by others, a class has some function as default behavior and expects its customers to override it if necessary. An example would be something like the following:
public class RecordProcessor<T extends Record> {
// ...
public void process() {
// process record logic
}
}
Consumers of this library creates their concrete classes to process their own records of type T.
Now I want to add a function called preProcess() to offer the ability for the consumers to preprocess their records. It would then look something like this:
public class RecordProcessor<T extends Record> {
// ...
public void process() {
preprocess();
// process record logic
}
public void preProcess() {
// By default no preprocessing
}
}
I know I can make preProcess an abstract function, but I dont want to due to a couple reasons:
Not all customers need to preprocess their records
We have a pipeline structure that autodeploys pushed code, so making RecordProcessor an abstract class would immediately break our customers' applications.
Is making preProcess do nothing in the parent class and let child classes override it considered bad practice? If not, what should the best way be to let customers know that they now have the power to preprocess the records? Through java docs?
One approach is to mark the public method as final (but this might also break existing apps) and allow protected hook methods to be overridden. For example:
public class RecordProcessor<T extends Record> {
// ...
public final void process() {
doPreProcess();
doProcess();
doPostProcess();
}
protected void doPreProcess() {
// By default no preprocessing
return;
}
protected void doProcess() {
// some default implementation
}
protected void doPostProcess() {
// By default no postprocessing
return;
}
}
Having some documentation should make it natural for other developers to recognize the optional extension methods.
I don't see anything wrong with having a hook method which does nothing. However, it should contain a return statement so static analysis tools won't complain.
UPDATE: in order to avoid breaking existing apps, if possible mark the existing method as deprecated and introduce a new method. For example:
public class RecordProcessor<T extends Record> {
// ...
public final void execute() {
doPreProcess();
doProcess();
doPostProcess();
}
#Deprecated - use execute() method instead.
public void process() {
doProcess();
}
protected void doPreProcess() {
// By default no preprocessing
return;
}
protected void doProcess() {
// some default implementation
}
protected void doPostProcess() {
// By default no postprocessing
return;
}
}
Prefer composition over inheritance. If you want your clients to add custom pre processing then do it by delegating to a separate objects.
public interface RecordPreProcessor<T extends Record>{
public void process(T record);
}
public class RecordProcessor<T extends Record> {
private RecordPreProcessor<T> recordPreProcessor = null;
public void setRecordPreProcessor(RecordPreProcessor<T> recordPreProcessor) {
this.recordPreProcessor = recordPreProcessor;
}
public void process() {
if (recordPreProcessor != null) recordPreProcessor.process(record);
// process record logic
}
}
No, overriding is not discouraged in Java.
The language allows overriding.
The language makes all methods overridable by default.
The Java class library includes examples of the same pattern.
Your approach is one reasonable way to allow subclasses to extend the behavior of their parent class. There are alternatives, such as passing a behavior as an object. However, there is no one true way.
One way you could improve your code is to mark preProcess() as protected. It's an implementation detail of the class. You don't want just anyone holding a RecordProcessor to decide they can call preProcess() by itself, right?
public class RecordProcessor<T extends Record> {
...
protected void preProcess() {
^^^^^^^^^
// By default no preprocessing
}
}
Another way to improve this is to consider whether you intend anyone to create an instance of the superclass RecordProcessor. If you don't, make the class abstract, to prevent that. The class name can express that, if you like, or your coding guidelines call for it.
public abstract class AbstractRecordProcessor<T extends Record> {
^^^^^^^^ ^^^^^^^^
...
protected void preProcess() {
// By default no preprocessing
}
}
One common way to document such methods is with the phrase "The default implementation does nothing. Subclasses may override this method ...". For example, below is the documentation for java.util.concurrent.FutureTask.done(). You can find more examples by searching for the first sentence of that phrase online.
public class FutureTask<V> implements RunnableFuture<V> {
...
/**
* Protected method invoked when this task transitions to state
* {#code isDone} (whether normally or via cancellation). The
* default implementation does nothing. Subclasses may override
* this method to invoke completion callbacks or perform
* bookkeeping. Note that you can query status inside the
* implementation of this method to determine whether this task
* has been cancelled.
*/
protected void done() { }
}
What I ended up doing- which I also thought was pretty good, inspired by #tsolakp, was simply creating a child class to RecordProcessor, called something like PreprocessRecordProcessor. This has no way of interfering existing code because nothing existing was touched. The class would something like this:
public class PreprocessRecordProcessor<T extends Record> extends RecordProcessor<T> {
// ...
public void process() {
preProcess();
super.process();
}
protected abstract void preProcess();
}
And if customers of this library would like to add their own logic they can simply extend this class and they'd be forced to provide pre-processing logic (as supposed to having the option to provide, which may result in unexpected results if they forgot to.)
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);
}
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.
Say I have classes declared like this:
public abstract class IdentifiableEntity {
public boolean validate() {
return true;
}
}
public class PreferenceCategory extends IdentifiableEntity {
public boolean validate() {
return true;
}
}
Now, let's say I have PreferenceCategory variable created, and I want to call the IdentifiableEntity.validate() method, not the PreferenceCategory.validate() method.
I would have thought I could do this with a cast (see below), but it still calls the overridden method:
PreferenceCategory cat = new PreferenceCategory();
// this calls PreferenceCategory.validate(), not what I want
((IdentifiableEntity)cat).validate();
Is there any way to do it?
You can't. Your best bet is to add another method to PreferenceCategory which calls super's validate() method.
public boolean validateSuper() {
return super.validate();
}
But why would you like to do that? This is a bit a design smell. You may find the chain of responsibilty pattern interesting.
You can, but only in the subclass:
public boolean simpleValidate() {
return super.validate();
}
If you don't want overriding, why not name the method differently? If callers must be able to choose the method they invoke, the methods do different things, which should be reflected in the method name.
If you cast, it will still use the override method. So you should do something like that...
public class PreferenceCategory extends IdentifiableEntity {
public boolean validate() {
return true;
}
public boolean validateSuper(){
return super.validate();
}
}
Then you call validatesSuper, it should work, bot is far from good OO programming, and I really do not recommend you to do that;
If you need to call a different validate so you should just give a different name for that method and call it when you need, or call validate to invoke the superclass method now, not overrided, like this...
public class PreferenceCategory extends IdentifiableEntity {
public boolean validatePreferenceCategory() {
return true;
}
}
you will still can call validade from superclass
There is no way to do that in Java, except from within the subclass with super.methodName(). Not even with reflection. Other languages such as Ruby can do it with reflection.
http://blogs.oracle.com/sundararajan/entry/calling_overriden_superclass_method_on