I have a class A that extends a class B.
A is defined like this, it also overrides a method of B:
class A extends B
{
public A() {
super();
}
#Override
public void doSomething(){
//does something
}
}
B is defined like this:
public class B
{
public B(){
doSomething();
}
public void doSomething(){
//does something
}
}
So if I initialize an object of A, the constructor calls the one of the superclass that calls the method doSomething(). But which one will be executed? B's implementation or the overriden one in A?
That is a common bug, only call final methods in constructor, the method from A will be called.
Btw Sonar(if you have it) will trigger a rule here saying that you should not call polymorphic methods inside a constructor.
If the class Overrides a method, then the overriden method will be called. Try the example below:
public class A {
void doSomething() {
System.out.println("a");
}
}
public class B extends A {
#Override
void doSomething() {
System.out.println("b");
}
}
A a = new B();
a.doSomething(); // will print "b"
Related
Here's something I quite understand:
abstract class A {
public void foo() {
System.out.println("a");
}
}
abstract class B extends A {
#Override
public abstract void foo();
public void bar() {
super.foo();
foo();
}
}
class C extends B {
#Override
public void foo() {
System.out.println("c");
}
}
public static void main(String[] args) {
new C().foo();
new C().bar();
}
new C().foo() prints c to the console, while new C().bar() prints a then c.
Calling super.foo() is illegal in the #foo() implementation of the C class.
I don't have a clear question, but if anyone could give a complete explanation of what is going on with the foo method, it may be interesting I think.
A is super class for B, so calling super.foo() inside B calls method defined in A, and calling foo() inside the same class will invoke its own implementation that should be delivered by any subclass.
You cannot use super.foo() within C class because it is defined as abstract in B and cannot be invoked directly.
My code looks like this:
class A {
void myMethod() {
...
}
class B implements class C {
// ... how can I call myMethod here?
}
}
I am sorry if I'm not explicit enough or if there is any error in my question.
You should be able to call the method directly:
class A {
void myMethod() {
...
}
class B implements class C {
public void init() {
myMethod(); // calls myMethod() from A
}
}
}
In that case that class B also has a method named "myMethod", then see this question: Calling outer class function from inner class
class A {
void myMethod() {
...
}
class B implements class C {
public void init() {
// calls myMethod from A even tho myMethod is also defined on B
A.this.myMethod();
}
void myMethod() {
}
}
}
I can only guess that this answers your question, but it's hard to tell since you didn't provide the actual code that you had the problem with.
Use this to run a method in a different class:
class.method();
This will run method method in class class.
If the method you wanted to call was in the same class you were calling it from you could just write the method name:
method();
What is the difference between these two calls? How should this be done properly?
//package test;
public class SomeClass {
public SomeClass() {
doSomething();//Warning - Overridable method call in constructor
SomeClass.this.doSomething();//Seems OK
}
public void doSomething() {
//...
}
}
I want to use doSomething() just for convenience in the same class. I have no intentions to override it later. One idea is to declare it final. But still it is not clear if SomeClass.this.doSomething(); is safe to use in this situation.
The compiler warning notification somewhat says what can happen. If a subclass overrides the doSomething method, it can change the behavior when creating the class instance, which may be dangerous or not, depending on your design. Note that it's a warning, not a compiler exception.
To prove this, just extended your code to test it:
class SomeClass {
public SomeClass() {
doSomething();//Warning - Overridable method call in constructor
SomeClass.this.doSomething();//Seems OK, but is not
}
public void doSomething() {
System.out.println("parent");
}
}
public class SomeOtherClass extends SomeClass {
#Override
public void doSomething() {
System.out.println("child");
}
public static void main(String[] args) {
SomeClass a = new SomeClass();
SomeOtherClass b = new SomeOtherClass();
}
}
Prints:
parent
parent
child
child
If you just want that no other class can override doSomething method, mark it as final:
class SomeClass {
public SomeClass() {
doSomething();//Warning - Overridable method call in constructor
SomeClass.this.doSomething();//Seems OK
}
public final void doSomething() {
System.out.println("parent");
}
}
Then if any subclass tries to override it, the compiler will throw an error:
public class SomeOtherClass extends SomeClass {
#Override
public void doSomething() { //compiler error
System.out.println("child");
}
//...
}
what will be the flow of execution in case of override? What i believe is , when we call a constructor/object of any class, during execution first it call parent constructor and than child. but what will happen in case of over ridding?
lets suppose:
class A {
public A(){
printStatus();
}
public void printStatus(){
System.out.println("In Class A");
}
}
class B extends A{
public B(){
printStatus();
}
#Override
public void printStatus(){
System.out.println("In Class b");
}
}
public class Test2 {
public static void main(String[] args){
B b = new B();
}
}
Out put of this code is:
In Class b
In Class b
what i don't understand is, why it's printing "In Class be" only, it should be "In class A and, In Class b",
when i remove override method from class b. it give me desired output.
All java methods are virtual. It means the method is called with using actual type of this. So inside of constructor A() {} this is the instance of B, so that is why you've got its method call.
Calling like this printStatus() will call the method from the same class. If you call with super.printStatus() it will envoke method from the super class (class which you have extended).
When you over-ride a method you over-ride it completely. The existence of the original implementation is completely invisible to other classes (except via reflection but that's a big topic of its own and not really relevant). Only your own class can access the original method and that is by calling super.methodName().
Note that your class can call super.methodName() anywhere, not just in the overriding function, although the most usual use for it is in the overriding function if you want the super implementation to run as well as your own.
Constructors are a slightly special case as there are rules about how and why constructors are called in order to make sure that your super-class is fully initialized when you try and use it in the inheriting class.
super is always called whether you write super(); or not.
In the example printStatus() method of Class A will never be called. Since you are creating an instance of class B and there will be method overriding. You can use the following to call the Class A printStatus() method.
public B()
{
super.printStatus();
}
When you override a method, it will override the one that you expect from class A.
Should use super keyword for calling super class method.
class A {
public A(){
printStatus();
}
public void printStatus(){
System.out.println("In Class A");
}
}
class B extends A{
public B(){
super.printStatus();
}
#Override
public void printStatus(){
System.out.println("In Class b");
}
}
Constructor public B(){ super.printStatus(); } calls Class A print method and constructor public A(){ printStatus(); } calls Class B print method since you've overridden.
But its wrong with overridable method calls in constructors.
Try with like this :
class A {
public A(){
printStatus();
}
public void printStatus(){
System.out.println("In Class A");
}
}
class B extends A{
public B(){
super.printStatus();
printStatus();
}
#Override
public void printStatus(){
System.out.println("In Class b");
}
}
public class Test2 {
public static void main(String[] args){
B b = new B();
}
}
For better understanding the concepts of Overloading and Overriding just go through this links:
http://en.wikibooks.org/wiki/Java_Programming/Overloading_Methods_and_Constructors
I have
public class D extends B
{
public void method() {}
}
public class B
{
public void method() {}
public void anotherMethod() { method(); }
}
In the above, if you hold an instance of D, say d, d.anotherMethod() results in calling D.method.
Is there a syntax in Java to call B.method() from inside anotherMethod()?
No, there isn't. The derived class would have to contain a call to super.method().
If B wants to prevent subclasses from overriding method(), it should declare method() as final.
You still can call the super method by explicitly using super like this this:
public class D extends B{
public void method() {}
public void anotherMethod() { super.method(); }
}
The only thing that is required is for you to override anotherMethod().
Another way is thinking like this. You want anotherMethod to call B method() so:
public class D extends B{
public void methodInternal() {}
}
public class B{
public final void method() {
//...
methodInternal();
}
public void methodInternal() {}
public void anotherMethod() { method(); }
}
Here the user can create his own version of method() by overriding methodInternal(), but still the behavior of the original method() is intact.
You can make method() static in B and then call it as B.method() from the instance methods where it is needed (you may need to rename the static method if you want to use the name for the instance method).
At least that's what I do in similar situations.
Maybe you should also reconsider your design.