How to call base class method? - java

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

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.

Java condition at constructor in order to invoke a parent constructor

I have a following Java class:
public class CharacteristicResponse extends VotableResponse {
public CharacteristicResponse() {
}
public CharacteristicResponse(Characteristic characteristic) {
super(characteristic);
this.characteristicId = characteristic.getId();
this.name = characteristic.getName();
this.nameSlug = characteristic.getNameSlug();
this.description = characteristic.getDescription();
this.valueType = characteristic.getValueType();
this.visualMode = characteristic.getVisualMode();
...
}
}
I want to add additional argument to constructor in order to be able to control super constructor invocation.. for example something like this:
public CharacteristicResponse(Characteristic characteristic, Boolean detailed) {
if(detailed) {
super(characteristic);
}
...
}
The example above is not possible from Java point of view so I'm looking for a solution how it can be done at some other way.
In a comment you've said:
Currently I have a pretty deep chain of a nested super calls.. so I was wondering there is an elegant way how it can be done with no needs to rewrite a lot of code..
In terms of not shaking that up too much, I see basically three options:
You could pass null in the case detailed is false and have VotableResponse(Characteristic) handle getting null:
super(detailed ? characteristic : null);
You could always call super() and then then set characteristic via a setter immediately afterward if detailed is true.
super();
if (detailed) {
super.setCharacteristic(characteristic);
}
You could pass the flag up the chain and let each class along the way handle it appropriately.
The example above is not possible from Java point of view so I'm
looking for a solution how it can be done at some other way.
Indeed, in Java the super constructor invocation is mandatory.
If you have only a constructor with some args you are forced to invoke it from the child class to compile fine
If the super constructor of the class doesn't suit for all cases, it means probably that what you perform in the super constructor should not be done here.
You could move the processing that is actually in the parent constructor directly to the child class constructor that needs it or in a common abstract class if multiple child classes need it.
You can just have a setter method.
Or try moving the logic to the factory.
Factory Design Pattern
But if you dont have access to the data structure of the backend, just you need to pass some parametters to the back end just use the .setCharacteristics(Characteristic characteristic, Boolean detailed)
If you really want to pass in a flag, create a factory that handles construction of new objects in this hierarchy:
class ResponseFactory {
public Response buildCharacteristicResponse(Characteristic characteristic, Boolean detailed) {
if (detailed) {
return new DetailedCharacteristicResponse(characteristic);
} else {
return new SimpleCharacteristicResponse(characteristic);
}
}
}
class Characteristic {}
class Response {
public Response(final Characteristic characteristic) {
}
}
class DetailedCharacteristicResponse extends Response {
public DetailedCharacteristicResponse(final Characteristic characteristic) {
super(characteristic);
}
}
class SimpleCharacteristicResponse extends Response {
public SimpleCharacteristicResponse(final Characteristic characteristic) {
super(characteristic);
}
}
I am assuming VotableResponse has an empty constructor? Your first example is implicitly calling super() in the empty constructor for CharacteristicResponse. You will have to invoke a super constructor one way or the other and it has to be the very first line of your constructor.
You may also try using static instantiators
public class CharacteristicResponse extends VotableResponse {
public CharacteristicResponse() {
}
public CharacteristicResponse(Characteristic characteristic) {
super(characteristic);
}
public static CharacteristicResponse instanceFrom(Characteristic c, boolean detailed)
if (detailed) {
return new CharacteristicResponse(c);
} else {
return new CharacteristicResponse();
}
}

How to prevent sublasses from default implementing a method of super class?

I have a method which adds Objects to an static list like this:
#PostConstruct
protected void registerToTransactionList() {
TransactionValidator.registerTransactionList(this);
}
registerTransactionList method just adds "this" to the static list, this method is in BalanceTransactionValidator class which extends TransactionValidator (owner of static list),the problem is all subclasses of BalanceTransactionValidator class are added to static list either,and if I override registerToTransactionList method in them like this:
#Override
#PostConstruct
protected void registerToTransactionList() {
}
It doesn't add subclasses but doesn't add BalanceTransactionValidator either. Can anybody help me on this? Please notice sublasses are overriding this method by default.
make the method private to block the visibility
private void registerToTransactionList() {
}
or make the method final to block it from been override
protected final void registerToTransactionList() {
}
There are two ways of achieving that:
Keep your method as it is; but then you have to actively check for the type of your objects before externally calling that method
Change your whole logic and make that method private
It won't help to make the method final as suggested in one of the comments - your problem is not that subclasses are overwriting that method; in essence, you have a design problem: you wish that subclasses should not invoke that method at all.
So, the only real option that makes sense here is "2.". You see, by having public method on a class that you want to be extended you are implicitly saying: it is perfectly fine to call that method; on any object that is instance of the base class (or child class!).
And in your case, that is not true: you actually do not want that the code behind this method runs for child classes. Then you shouldn't put that method in the list of public/protected methods of your base class!
Finally: you might want to step back and do some reading about good OO design. Class hierarchies do not fall from the sky: you willfully design them for a certain purpose. In other words: there is more to inheritance than just putting some "A extends B" on your class declaration. You have to understand each and every method on your B class; and how your child classes should deal with them!
EDIT: after some more thinking, I guess you are doing things "the wrong way", like:
class BaseClass {
public final void doRegistration() {
BaseClass toRegister = getObjectForRegistration();
if (toRegister != null) { ... register toRegister ...
}
protected BaseClass getObjectForRegistration() {
return null;
}
With that code, you could then put
protected BaseClass getObjectForRegistration() {
if (this instanceof ClassThatShouldBeRegistered) {
return this;
}
return null;
}
into that one class that wants to be registered. Probably there could be even nicer ways of doing so; but after some thinking I don't see how we could avoid the instanceof. But the above code should work; and it only requires specific code only in your base class and in that one class that wants to register something.

Method call in constructor does not work, made method final and still does not work

I am tring to set my objects state in my constructor. I call the setState method.
This keeps giving me null. I read that you can't call methods that can be overridden in a constructor, so I figured that was why. I made the setState method final and still see the issue.
Is it ok to just do myState = x; in the constructor instead of calling setState(x)?
Also any thoughts why the call to setState in the constructor does not work even if the method is final?
One more point is that the class that all this is done in is abstract, not sure if that makes any difference.
Language is Java.
I am not sure about posting code, my company is sensitive to that. Don't want to get in trouble with my employer.
I will post some generic code
public abstract class Abc
public Abc()
{
setState(uninit);
}
public final void setState(state s)
{
myState = s;
}
This does not work, if I change the line
setState(uninit);
to
myState = uninit;
it works, but I am not sure this is a good idea, because I have a setter for the state.
I suppose that you forgot to call the super constructor in the sub-class constructor.
super();
It is something like
public class sub_abc extends abc}
public sub_abc(){
super();
...
}
}
Not sure what your actual code is but I don't find the parameter name in the formal parameter list of the setState() method.
public abstract class abc
{
public abc()
{
setState(uninit);
}
public final void setState(state s) //Seems to be something like this.
{
myState = s;
}
}
Additionally, you must follow the Java naming-conventions. Accordingly your class name abc should be replaced as Abc and so on.
Executing myState = x; in the constructor has the exact same effect as calling setState(uninit);; at least as far as I can imagine your original code to be. In that case then, the error must be somewhere else. Perhaps you are calling setState again? Or something else that is different between the two tests. I would put a breakpoint in the constructor and step through the code.
There is nothing here that your company can object to as being sensitive. If it makes you more comfortable, use an online compiler such as ideone
I usually initialize my class variables in the constructor like that. The getters and setters are usually only for other classes to use, so I see no reason why you cannot just use myState = uninit;
public abstract class abc {
private State uninit;
public abc()
{
myState = uninit;
}
public final void setState(State newState)
{
myState = newState;
}
}

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