I have a little confusion in Java overriding. Suppose we have the following inheritance:
class A{
public A(){
}
void show(){
System.out.println("SuperClass");
}
}
class B extends A{
#Override
void show(){
System.out.println("SubClass");
}
}
public class Test {
public static void main(String[] args) {
B b = new B();
b.show();
}
}
Clearly, class B overrides the method show() that is inherited by the class A. Why is not b.show(); printing the message System.out.println("SuperClass"); as well since class B has now the method show() from class A?
Thank you.
The show method of class B overrides the show method of class A and doesn't call it, so there's no reason for System.out.println("SuperClass"); to be executed when you call show on an instance of B.
If you change class B to :
class B extends A
{
#Override
void show(){
super.show ();
System.out.println("SubClass");
}
}
calling show on an instance of B will also execute the logic of A's show method.
In class B you are overriding, in other words replacing the original implementation of the show() method. Every time you invoke show() on an object that is instanceof B that version of the method will be called.
The only way to refer to the original show() method is to refer to it using the super.show() syntax inside B or any other class that extends A.
And as an additional note, that #Override annotation is just to add additional compiler checks but it's not required to actually override a method, you just need to re-implement it as you have done in B.
its the matter of polymorphism which acts , i.e., method call to method body happens at run time i.e when JVM invokes B b=new B(); so B object is of type class B ,so the method it displays B's method which is overridden one, if you put super() in B()'s constructor you can get parents one.
This is the effect of overriding in inheritance. You just replace the method from the superclass (but you can still reach the old one!) Here I also added a little bit with polymorphism too. Hope that this will help you.
class A{
public A(){
}
void show(){
System.out.println("SuperClass");
}
}
class B extends A{
void superclass() {
super.show();
}
#Override
void show(){
System.out.println("SubClass");
}
}
public class Test {
public static void main(String[] args) {
B b = new B();
b.show(); //SubClass
b.superclass(); //SuperClass
A a = new A();
a.show(); //SuperClass
A c = new B();
c.show(); //SubClass
//c.superclass(); //error! the program won't compile
}
}
Related
If class A creates an instance of class B, then in class B can I run a method from class A? sorry if the question is poorly worded, I don't know how else I could say it.
In the below code, Class A creates an instance of Class B and you can call Class A's method from Class B's method.
class A {
public void getA() {
System.out.println("In A");
}
public static void main(String[] args) {
B b = new B();
b.getB();
}
}
class B {
public void getB() {
System.out.println("In B");
A a = new A();
a.getA();
}
}
Output:
In B
In A
In class B you can call methods of class A only if A's methods are visible to B. It doesn't matter who created an instance of B.
This tutorial might help: http://www.tutorialspoint.com/java/java_access_modifiers.htm
So you can call it if the method is one of the following:
public
protected (and B is a subclass of A or B is in the same package as A)
no modifier (and B is in the same package as A)
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
My code looks sort of like this, but this is a simplified version:
class A:
public class A{
public void testArgs(A a){
System.out.println("A");
}
public void test(){
System.out.println("A");
}
}
class B:
public class B extends A{
public void testArgs(B a){
System.out.println("B");
}
public void test(){
System.out.println("B");
}
}
class Main:
public class Main{
public static void main(String[] args){
a(new B()).testArgs(new B()); // prints A
(new B()).testArgs(new B()); // prints B
a(new B()).test(); // prints B
}
public static A a(B b){
return b;
}
}
Why does a(new B()).testArgs(new B()) print A not B?
Is there some sort of way to workaround/fix this?
edit:
Clarification:
What I really want is the superclass method to be run when it is called with an A, and the subclass method to be run when testArgs is called with a B.
Casting also isn't an option because in the actual code, unlike here, I don't know whether the result of the method call is actually B or not.
edit:
Solution:
Thanks everyone for your answers. Thanks for the clarification on overriding. I used this to implement the desired behavior.
For anyone who has a similar problem in the future:
Change class B to
public class B extends A{
public void testArgs(A a){ // Corrected overriding, thanks
if(a instanceof B) // Check if it is an instance of B
System.out.println("B"); // Do whatever
else // Otherwise
super.testArgs(a); // Call superclass method
}
public void test(){
System.out.println("B");
}
}
The two testArgs functions are different. One takes an A and the other takes a B. Thus, the B version doesnt override the A version. Since a(new B()) is of type A and B extends A, it is the A version that will run.
There is a "workaround":
public class B extends A{
public void testArgs(A a){ // <-- note how this is A a, not B a
System.out.println("B");
}
public void test(){
System.out.println("B");
}
}
Then you will see B for all 3 cases (because B's testArgs will override A's testArgs)
The call a(new B()) returns a new B instance of type A, when invoking testArgs() it gets called in class A and prints "A". Correct.
Should the method testArgs() override the one in super class, then the sub class version will get invoked, by means of polymorphism (but its not your case).
So to get your expected result, class B needs to properly override the method in super:
public class B extends A{
public void testArgs(A a){ // polymorphism would work
System.out.println("B");
}
...
Debugging the problem at run-time is rather difficult. There's a very simple way to let the compiler warn you by using the anotation #Overrides
public class B extends A{
#Overrides
public void testArgs(B a){
System.out.println("B");
}
#Overrides
public void test(){
System.out.println("B");
}
}
If I have inadvertently left out a parameter or used a wrong one then #Overrides will catch my error at compile time itself.
In your first statement, that prints "A", you could workaround the issue by casting the result of the static a() call to a B:
((B) a(new B())).testArgs(new B());
public class XXX {
#Test
public void test() {
B b = new B();
b.doY();
}
}
class A {
public void doY() {
XProcedure.doX(this);
}
}
class B extends A {
public void doY() {
super.doY();
XProcedure.doX(this);
}
}
class XProcedure {
public static void doX(A a) {
System.out.println("AAAA!");
}
public static void doX(B b) {
System.out.println("BBBB!");
}
}
The output is
AAAA!
BBBB!
And I wonder why?
Although XProcedure has two methods with the same name - doX, the two signatures are different. The first method gets an instance of class A as a parameter, and the second one gets an instance of class B.
When you call XProcedure.doX(this), the correct method is called according to the class of the passed parameter.
"AAAA!" is printed because of the super.doY() call.
"BBBB!" is printed because of the XProcedure.doX(this); call.
this differs in A's constructor from this in B's constructor for the reasons in Che's answer. Although A's contructor is called from within a B's constructor, in A's scope, the instance is of class A.
You called super.doY which is a method on B's superclass A.
All animals can talk.
A cat is an animal.
A cat talks and drinks milk.
In Python, class methods can be inherited. e.g.
>>> class A:
... #classmethod
... def main(cls):
... return cls()
...
>>> class B(A): pass
...
>>> b=B.main()
>>> b
<__main__.B instance at 0x00A6FA58>
How would you do the equivalent in Java? I currently have:
public class A{
public void show(){
System.out.println("A");
}
public void run(){
show();
}
public static void main( String[] arg ) {
new A().run();
}
}
public class B extends A{
#Override
public void show(){
System.out.println("B");
}
}
I'd like to call B.main() and have it print "B", but clearly it will print "A" instead, since "new A()" is hardcoded.
How would you change "new A()" so that it's parameterized to use the class it's in when called, and not the hard-coded class A?
Static methods in java are not classmethods they are staticmethods. In general it is not possible to know which class reference the static method was called from.
Your class B does not have a main method and static methods are not inherited.
The only way I can see this happening is to find whatever is calling A.main( String[] arg ) and change it to call B.main instead.
B.main:
public static void main( String[] arg ) {
new B().run();
}
How is your program started? Is there a batch file, shortcut, etc? Something you can change? Where does A.main get called?
I think this isn't possible. Here's why:
In Java, the implementation of a method is determined by the instance's run-time type. So, to execute B.show(), you need to have an instance of B. The only way I could see to do this, if the method that constructs the instance is supposed to be inherited, is to use Class.newInstance() to construct an instance of a type that's not known at runtime.
The problem with that is that within a static method, you have no reference to the containing class, so you don't know whose newInstance method to call.
Why do you want to do this, though? There may be some better way to achieve whatever it is you want to achieve.
In your example I wouldn't put your main method inside of A. This is setup as the entry point into the system (you can't be in B if you are specifically entering into A).
In the example below I created class A, B, and C. Class C instantiates A and B and runs them. Notice that in C I created an A, a B, and another A that I instantiate as a B. My output is:
A
B
B
Hopefully this makes sense.
public class A {
public void show(){
System.out.println("A");
}
public void run(){
show();
}
}
public class B extends A {
#Override
public void show(){
System.out.println("B");
}
}
public class C {
public static void main(String[] args) {
A a = new A();
B b = new B();
A anothera = new B();
a.show();
b.show();
anothera.show();
}
}