I have a class A and write a subclass B. A has only one constructor which is parameterised. B has to call this super constructor of A.
Now I want to use an Object as a parameter. This object should call a method of B. So the parameter-object has to hold a reference of B or has to be an inner class.
public B(){
super.(new parameter(this))
}
Now when I want to invoke the constructor like... Eclipse says:
Cannot refer to 'this' nor 'super' while explicitly invoking a constructor
The only thing I see to get around this, is a set-method, to inject the "this"-instance into the parameter object. I would not like to edit the super-class.
Do you see any better way around this.
The compiler is really preventing you from shooting yourself in the foot here. B isn't fully constructed until after the call to the super constructor, so if you pass this (if the compiler allowed it) as a reference, and it calls a method on B, B would be in an invalid state and cause all kinds of nasty problems (in fact, A is still not initialized, nor any class up the chain, including Object).
The obvious solution is to provide the functionality outside of B and pass that to the constructor of the parameter. Specific solutions will depend on the specific problem, but a static nested class inside B (it needs to be static for the same reason - an inner class has an implicit reference to the outer class instance) could provide that functionality, perhaps. Maybe you need to rethink the relationship between the parameter, B and its super class. It all depends on the case.
Related
I know that this must have been asked before, but I'm not sure how to search for this.
If I have a Object of class B that extends class A, If I type cast this object to class A and then call a overriden method on this object, which method will be called? A's or B's?
The real class of an object determines with methods are called.
Those casts, and types that you are using in your source code are not really meaningful at runtime. You rather look at them as a way to enable human coders to do their job.
Let say I have:
class Superclass {
//fields...
methodA() {...}
methodB() {...}
...
}
class Subclass extends Superclass {
//fields...
methodA() {
// Here I need to call methods A and B from superclass:
// For this, I can use supper
super.methodA();
super.methodB();
// Or I have to instantiate the superclass and use the instance
Superclass superclass = new Superclass();
superclass.methodA();
superclass.methodB();
}
It works both ways, but I want to know which is better to use. Any of these ways is a bad programming technique? I hope you give me answer and arguments.
super.methodA();
Superclass superclass = new Superclass();
superclass.methodA();
These two calls of methodA work on different instances, so they are completely different. super.methodA() executes methodA on the current instance. superclass.methodA() executes methodA on a new instance of Superclass which is not related to the current instance.
You would almost always use the first option. As for the second option, It doesn't make sense to create a new instance, call a method on that instance and then never do anything with that instance again.
It works both ways, but I want to know which is better to use.
Well that entirely depends on what you're trying to achieve. If you want to create a new, entirely independent instance, do so. But it's more common that you want to use the superclass implementation of a method you're overriding on the same instance that the overridden method is currently executing on in which case you would use super.methodA().
In my experience, super is most commonly used when overriding a method to do some subclass-specific work, call the superclass implementation, then do some more superclass-specific work. For example:
#Override public void add(Foo foo) {
doSomeSubclassSpecificValidation(foo);
super.add(foo);
doSomeSubclassSpecificBookKeeping();
}
In other words, even though you're overriding the method, you still want the "normal" behaviour - you just want some extra code to run as well. Or sometimes you want to run the superclass code conditionally, e.g. only if the input meets a certain criterion.
It's totally different.
super.methodA() will call methodA() in the left circle, while creating a new superclass and calling that methodA() will first create the right circle, and then call methods from it.
With above answers, you must have understood that basically you are calling same method of same class but on two different objects so it all depends as what you are trying to achieve ( On which object you plan to call those methods ). As you know, call to same methods of same class but on different instances are not the same. "super" object is parent of "this" object and that super object was created implicitly when you instantiated Subclass so as per your example code, both are NOT SAME but for simple cases,output might be same. Go one more level up and see if it looks different to you from client code ( try writing calling code of Subclass ).
Lets think about Asynctask class.
It has overrideable methods such as onPreExecute,onProgressUpdate etc.
Compiler does not give error if i dont add super.'method-name' etc. So should i do it or not? What is the benefit of calling (or not calling) super methods when we dont have to call
When we think of extending EditText class, after your customization you need to call super constructor for sure.
NOTE: I am talking about optional super calls.
in general, and as a rule in object oriented programming: unless you have a good reason to break it, and you know exactly what's the super class method implementation all about, you should always call the super class methods.
in the specific case of AsyncTask - it is not required to call the super class method, simply because it does not doing any code.
opposite example: if you will not call the super methods of an Activity callbacks such as onCreate() and onDestroy() you will break entirely the activity, and probably nothing will work. that's because the super class implementation of this methods doing tons of stuff required from each activity.
so the conclusion is that if you are not the writer of the base class - look for documentation providing any hints about methods you which to override in order know how, and if at all you should call the super class methods.
As they are empty methods you do not have to call them. They are just there for you to use for overriding.
If you don't call the superclass's method, then...the superclass's method doesn't get called. Whether that's a problem depends entirely on what the superclass method does. If it's optional, as you say, then call it if you need to (e.g., your logic requires whatever it does) and don't call it if you don't.
If the superclass's method is empty, the only reason for coding the call to it would be if you rebased your class. E.g., suppose you had A as a base with an empty foo method, and B derived from it (class B extends A). Later, you want to be able to change it to class B extends SpecialA where SpecialA is a special version of A where foo does something. If you've left the supercall out of B's foo, you'll have to remember to add it. If you included it in the first place, you won't have to remember to add it.
(The only supercall that has to happen is a call to the superclass's constructor when constructing the object, but if you leave that out, the compiler will supply a call to the zero-args version [e.g., super()]. But that's a constructor, not a method.)
As I was preparing for an interview about OOP, I came across this question.
A inherits form B. B inherits from C.
Will initializing A invoke constructor of C?
What I know is that a constructed is not inherited. We have to use the super keyword to refer to the parent's constructor. Am I right?
The constructor of a subclass will first invoke the constructor of its super class. If a class has several ancestors, these calls will be stacked until the constructor of the top ancestor is called. Then, it will continue executing the constructor of the next ancestors until all the constructor of the ancestors were executed. You can infer from here that every time you create an object, the constructor of Object class is invoked, always.
Note that if you don't add the call to super() in the subclass constructor, the compiler will add it for you automatically. If there's no default constructor for the super class and you don't specify the call to the specific constructor of the super class in the constructor of the subclass, then you will get a compiler error.
All these rules are stated in JLS.
In the world of Java, when you are extending another class, you only see your direct super class' constructor. The super class is supposed to proper encapsulate the super-super class constructor.
There will always be an implicit call to the constructor of the base class. In your case, the constructor of C will be called first, then the constructor of B and finally the constructor of A.
Using super is useful when you have defined overloaded constructors, and you want to call a specific one.
I am trying to write an abstract class. In that class I have a method which is supposed to access the actual object for which the method is called.
"this" however will only return the "part of the object" that I write myself (the abstract one).
To specify some more:
If the method I was writing had a parameter of the type of my class, what i want looks like this:
public abstract class MyClass {
public void foo(MyClass invoker) {
...
}
}
The above code would allow me access to the object invoking the method, but it would be tedious to write it like this, since this is supposed to become part of a library I want to supply to others and I cannot know for certain, that the passed argument would in fact be the right object and not some other object of a class derived from MyClass.
Is there a way to invoke something along the lines of getNestingObject() or do I specifically have to give the method a parameter and constantly infer "this" to every call?
Finally, since I am no master in java, a perhaps less obvious question:
Is there a security reason, why the above described concept is flawed? Could someone
with malicious intent abuse that kind of keyword?
I am trying to write an abstract class. In that class I have a method
which is supposed to access the actual object for which the method is
called. "this" however will only return the "part of the object" that
I write myself (the abstract one).
this will return a reference to "the whole" object, not "a part". To proof this, if you cast this reference to a class that is lower in the hierarchy, you can access any property or method of this class using the instance referenced by this.
However, casting the instance referenced by this, would not be a good design practice. Speaking in general terms, you should write a foo method in MyClass with the general behaviour, and override it with the particular behaviour of each classs. If you want to use the foo method of the parent class, you can invoke it using super.