Sometimes,deriving classes should always call through to the base implementation. where should I put the calling statement, before or after the subclass-specific code. For example:
boolean foo(T x) {
super.foo(x);
....blabla...; //< derived calss-specific code
return true;
}
OR
boolean foo(T x)
{
....blabla...; //< derived calss-specific code
return super.foo(x);
}
How to make a correct decision on different situation?
Thanks in advance.
The answer depends on what the superclass method does, and what the subclass method does.
If the work done by the superclass must be done before, put the super call before. If the work done by the superclass must be done after, put the super call after. If some work must be done before the superclass method and some after, then put it in between.
If the order doesn't matter, the usual way is to call the superclass method at the beginning.
Related
As stated in the title, pertaining specifically to Java. In pseudocode an example of this might be:
class SubClass extends SuperClass {
protected void update() {
super.update()
// do other functionality
}
}
class SuperClass {
protected void update() {
if (something) return;
}
}
If the update method is called and the superclass then returns, does the other functionality in the subclass then execute or does it return fully to where the original subclass method is called?
As a follow up question, if this is not the case, is there a way to effectively prevent any further code from running in the superclass or subclass methods?
There's nothing special about the method call from the subclass to the superclass (other than which method gets called, which the super keyword influences, obviously). The answers to your questions flow from that fact:
Does the return keyword in a superclass method return to the subclass that called the superclass method?
Yes, just like any other method call. Sometimes, the subclass needs to do work after the superclass work is done, and/or with the return value from the superclass before returning to the caller.
...is there a way to effectively prevent any further code from running in the superclass or subclass methods?
Not from the superclass method, no. You can throw an exception, but (of course) the subclass method could catch it. Which is, again, just like any other method call.
Because the type of the method is protected, access from subclasses is
possible. Also void methods do not return.
I understand that this keyword is for calling a current constructor in the specific class. But I had another situation that I need to understand it more. The next code shows the use of this and super keywords:
public class Stack {
public void push()
{
/* do something */
}
public boolean full()
{
/* do something */
}
}
and the other class is:
public class ProtectedStack extends Stack {
public void push()
{
if (this.full()){----}
else
{
super.push();
}
}
}
I want to know what will happen in this case.
this.full() is exactly the same as full(). It calls the method full() on a ProtectedStack instance. This method might be declared directly in the ProtectedStack class or it might be inherited. In your code, it looks like the method full() is inherited from the parent class Stack, because ProtectedStack does not override it.
Concerning super.push(), this will always call the method push() implemented in the nearest parent class. Even if this method is overriden in ProtectedStack, the parent method will be called.
Basically:
this.method(): the method method() is called on this object, so the method is searched in this class, then on the parent class, etc. If this class overrides it, then this one will be called. If not, the one from the parent will be called, etc.
super.method(): the method method() of the parent class is always called, even if this class overrides it.
It is pretty much explicit this calls the method of on the current object and super calls the method on the current object's parent (Note during the call the method is searched in recursive fashion till it is found.).
from the comments, in your case as you did not implement full() method on the subclass this.full() and full() and super.full() are identical.
Also as this.full() and full() are always same dont use this.full() pattern to minimize the confusion.
I have derived a class in java.
I noticed that the superclass constructor gets called before code in my derived class constructor is executed.
Is there a way to invert that order?
Example:
class Animal
{
public Animal()
{
//do stuff
}
}
class Cat extends Animal
{
int var;
public Cat(int v)
{
var = v;
super();
}
}
This is what I would like to do, but calling super() like that gives an error...
No, there is no way to invert that order. If you explicitly call a parent class constructor you are required to do it at the top of your constructor. Calling it later would allow a child class to access the parent class's data before it's been constructed.
No, you can't invert the order of constructor calls this way. A call to super() must be the first statement in a constructor. And if there is no such call, Java inserts an implicit call to super() as the first statement.
The JLS, Section 8.8.7, states:
The first statement of a constructor body may be an explicit invocation of another constructor of the same class or of the direct superclass (§8.8.7.1).
ConstructorBody:
{ [ExplicitConstructorInvocation] [BlockStatements] }
There isn't a way to call run the sub class constructor before superclass constructor. That's basically like trying to create the subclass even before the superclass gets created, which is impossible since the subclass relies on superclass attributes to get created.
Are there any reason to call method from super class?
I have met lots of places where super method called instead of this method, e.g.:
public String getCustomValue() {
String value = (String) super.getValue(someArgHere);
return value;
}
Any benefits? I just see one major problem with inheritance: if I override getValue in this class or in one of its descendants getCustomValue will neglect that override and call super method.
super.getValue(someArgHere) calls the getValue method of the super class. In contrast, this.getValue(someArgHere) calls the getValue method of the current class, if defined. If the current class does not override getValue, the super class method is called.
Unless you overwrote the method getValue(...) and you are really sure (your sureness deserves a comment in the code) you want to bypass it you should not use super like you are doing. Later on if you or someone else decide to overwrite getValue(...) they probably wanted the effect to apply to getCustomValue() as well.
Although you definitely can call super.myMethodOne() from myMethodTwo(), the usual scenario is when you want to call super.myMethodOne() from myMethodOne() when you override it. Some languages like Ruby even pass up the method arguments automatically for you so that you don't have to retype them.
Here is one example:
public class A {
public void close() {
// do a bunch of things...
}
}
public class B extends A {
#Override
public void close() {
// close things related to the subclass B
// and then make sure A is closed as usual...
super.close();
}
}
There are no technical advantages of using super over this in the case where the method is not overridden.
However, one might say that it's clearer to use super instead of this for the reason you've just mentioned. If you override the function in your subclass, then you will need to use super; if you don't you can use this. Instead of playing guessing games (or forcing people to check whether the method has been overridden), you can just always use super when you mean super.
I just see one major problem with inheritance: if I override getValue in this class or in one of its descendants getCustomValue will neglect that override and call super method.
Then don't call the super method explicitly, just call getValue. If the method has not been overriden it will default to the super-method. If it has, it will use the overriden method.
I don't know if it's appropriate to ask about "benefits" in this case - it really just depends on what exactly you are trying to accomplish.
The thing is the design. When we code, we do it as per what it is!
So even if getValue is extended, its perfect, because that is what your class is suppose to do.
Normally, super is used, to obtain any information or data or side effect from the super type and modify or improve it as per your current class functionality
The only benefit is if your class overrides the method of the superclass you still can call the method of the superclass using super.
If I had a method signature
public void myMethod(SuperClass s){
}
and SuperClass has three subclasses, is there any way within myMethod I can get the class name of the subclass which was passed in?
Not sure if it's important, but SuperClass is abstract.
is there any way within myMethod I can get the class name of the subclass which was passed in?
Yes, by using the getClass method:
public void myMethod(SuperClass s){
System.out.println(s.getClass());
}
Remark 1:
This does however sound to me like a Bad Design™.
Whatever you want to do in myMethod consider having a method for it in SuperClass (provide a meaningful default implementation, or make it abstract to force subclasses to implement the method) and call this method on s in your method:
public void myMethod(SuperClass s){
s.abstractMethod();
}
Remark 2:
If myMethods logic is seemingly unrelated to the purpose of the SuperClass and you don't want to put the myMethod code inside this class, consider implementing the visitor pattern instead.