i am newbie in java and i usually used c++ i just wondering this code works
public class ParentClass {
public void methodA() {
System.out.println("This is Parent A Method");
whoAmI();
}
public void methodB() {
System.out.println("This is Parent B Method and I am Calling Method A");
whoAmI();
methodA();
}
}
public class ChildClass extends ParentClass{
#Override
public void methodA() {
System.out.println("This is Child A Method and I am Calling Parents Method A");
whoAmI();
super.methodA();
}
#Override
public void methodB() {
System.out.println("This is Child B Method and I am Calling Parents Method B");
whoAmI();
super.methodB();
}
}
ChildClass c = new ChildClass();
c.methodB();
and I expected output like this
This is Child B Method and I am Calling Parents Method B
This is Parent B Method and I am Calling Method A
This is Parent A Method
but was
This is Child B Method and I am Calling Parents Method B
This is Parent B Method and I am Calling Method A
This is Child A Method and I am Calling Parents Method A
This is Parent A Method
so i realized that in java all non-static methods are by default virtual functions like virtual keyword in c++.
is there any way to make output like this?
This is Child B Method and I am Calling Parents Method B
This is Parent B Method and I am Calling Method A
This is Parent A Method
You can wrap the methodA's impl of ParentClass in a seperate private method:
public class ParentClass {
public void methodA() {
interMethodA();
}
private void interMethodA() {
System.out.println("This is Parent A Method");
whoAmI();
}
public void methodB() {
System.out.println("This is Parent B Method and I am Calling Method A");
whoAmI();
interMethodA();
}
}
And the ChildClass remains the same.
The code - as is - does not compile since method whoAmI() is undefined. By removing the calls to this method, I was able to reproduce the output.
From what I understand, you want to ensure that methodA in Parent is called from methodB in Parent. Since dynamic dispatching is used in Jjava to determine which actual implementation is called, we have to enforce that methodA cannot be overridden. As #MarquisofLorne pointed out, C++ uses dynamic dispatch aswell, if methodA is defined as virtual in Parent.
To enforce that dynamic dispatch always results in a call to Parent's methodA, there are two general approaches that come to my mind: declaring methodA as final and declaring methodA as private.
Approach one: declare methodA in Parent as final
When going down this route, Child cannot re-define methodA, i.e. the code would result in a compile-time error if methodA is not removed from Child.
Ideone demo
Approach two: declare methodA in Parent as private
This approach is similar to the first approach, but allows you to retain methodA in Child, albeit the #Override-annotation must be removed since private methods cannot be overridden.
Ideone demo
You got:
This is Child B Method and I am Calling Parents Method B
This is Parent B Method and I am Calling Method A
This is Child A Method and I am Calling Parents Method A
This is Parent A Method
Instead of
This is Child B Method and I am Calling Parents Method B
This is Parent B Method and I am Calling Method A
This is Parent A Method
Simply Bacause, In Java calling methodA() or this.methodA() in your methodB() of ParentClass calls the method off of the calling object or instance, Yet the instance is an instanceof ChildClass. Java treats methodA() and this.methodA() as same. The this keyword in Java actually refers to the "currently running instance of the object you're using". Meaning, the overridding methodA() of ChildClass will be called instead of methodA() of ParentClass.
Here is a suggestion, to get the expected output, simply apply modifications on the overridding methodA() of ChildClass by commenting out the printing line.
Otherwise reference this for more details.
Related
Given the code from Parent class and Child class:
class Parent{
public static void classMethod(){
System.out.println("ClassMethod in Parent");
}
public void hello(){
System.out.println("Hello from parent, call classMethod");
classMethod();
}
}
class Child extends Parent{
public static void classMethod(){
System.out.println("ClassMethod in Child");
}
}
If I have this in main method:
public static void main(String[] arg) {
Parent D = new Child();
D.hello();
}
Why is this the result? ->
Hello from parent, call classMethod
ClassMethod in Parent
So there's a child object of parent class calling an instance method which calls a static method.
I would understand why it calls the static method from the parent class if hello() was static as well, since the object type would be defined at compile time and it would be Parent. However, since hello() here is an instance method, it has to be resolved at runtime, and at runtime, isn't the type of the object the actual type, AKA Child type? So in that case, wouldn't it call the static method from the child object since the object is of child type at run time?
Note: this answer assumes the Child class extends Parent. Otherwise, the code in the main method just throws an error.
This is an example of up-casting and polymorphism. Because it's of the type Parent, its access is limited to the Parent class. When you call the hello() method, it is being called in the Parent class. Then, this method calls classMethod() but, because hello() is a method in the parent class, it calls it in the Parent class as well, which is why you are getting that as a result. The fact that it is static makes no difference: static methods can always be called by instance methods, but not always the other way around.
One thing I should point out is that, because of the line Parent D = new Child();, the object D does not actually have access to any of the static methods in Child even though it is that type. If you wish for D to have access to methods in both Parent and Child, you can use Child D = new Child();
With Parent D = new Child();, if you are calling a method, it must be in the Parent class and will run the method in the parent class - except for if there is an overriding instance method of the same name in the Child class, in which case it will run this method instead. It should also be noted that an overridden method cannot be static
I am looking for a way to explain how the following Java program should be traced (which method is called, etc), esp how the access modifier & inheritance affects the method invocation.
I have two classes A and B, where B extends A.
Class A has private method process()
Class B has public method process()
Class A has public method callProcess() which calls process().
In the main program, I create an object B and call method callProcess().
class A {
private void process(){
System.out.println("Process A.");
}
public void callProcess(){
process();
}
}
class B extends A {
public void process(){
System.out.println("Process B.");
}
}
class MethodTest{
public static void main(String[] args){
B b1 = new B();
b1.callProcess();
}
}
I expect that the process() from B is invoked since the object that calls process() is of type B, but what happens is process() from A is invoked.
What's weirder is if I change the modifier of process() in A to public then the process() in B is invoked.
Since process from A is a private method, B is completely unaware of its existence and it cannot be overridden.
Similarly, when you call callProcess on an instance of B, it calls A.callProcess (since it was not overridden in B). A only knows of its own process method (which cannot be overridden) and calls that.
If you were to change the visibility of the process method in A to be either public or protected, then it can be overridden in B, as long as the signature matches i.e. they must have the same visibility.
Yes, for the override to be implicit, the overrided method cannot have a more restrictive access level than the overriding one.
abstract class A {
public void methodA() {
System.out.println("methodA");
methodB();
showName();
}
public abstract void methodB();
public void showName() {
System.out.println("in showname base");
}
}
class B extends A {
public void methodB() {
System.out.println("methodB");
}
public void showName() {
System.out.println("in showname child");
}
}
public class SampleClass {
public static void main(String[] args) {
A a = new B();
a.methodA();
}
}
Output is :
methodA
methodB
in showname child
Question :-
Since in overriding, the object type is considered. Is it the reason behind that class B's showName() method called not of class A's? If not then whats the cause of this output order?
You created an object of type B, so all methods called on that object will be on class B. If class B does not implement some methods (like methodA), then Java tries to find a method in the parent class (A). You should read about polymorphism in object oriented languages:
http://en.wikipedia.org/wiki/Polymorphism_in_object-oriented_programming
It's easy:
A a = new B();
a.methodA();
here is known that a is object of B class, so every method that can be overriden in class B is used from class B if there is no overriding, then method from class A must be used.
Considering order:
you invoke methodA that is declared as:
public void methodA() {
System.out.println("methodA");
methodB();
showName();
}
from inside of methodA() you invoke both methodB() and showName(). They are overriden in class B, and object a is instanceof B, so that's why they (from B class) are used.
EDIT as mentioned in comment:
#Jaikrat Singh, class B is still class A (child of it, but inheritance is relation of type: IS-A ). Class B has inherited methods from A class. So it has methodA as well. So it's better to say, that methodA is also called from class B but with is default code - the same as provided in class A
While the object 'a' is declared as type A, it is instantiated as type B. Polymorphism causes the methods of the instance type to be called rather than those of the declaration type, so because it is internally of type B, the showName() method of class B is called.
When you call a.methodA(), since your object type is B, it will look for methodA first in B. Since there is no such method in B, it will look for this method in its super class, which is A. Finding methodA in class A, it will start to execute.
Executing, it will print methodA and start looking for the next called method (methodB), which is implemented in the B class, then it will print methodB.
The next called method is showName, which is implemented in both classes. Since Java will start looking for the implementation in the same class as the object type, it will find in its first attempt, which is class B.
The main rule is simple: Java will first try to find the method in the object type class (the name that goes after the new operator). If the method is not implemented there, it will start to go up through the super classes.
You have the abstract class A, and it is extended by B. Extends is equivalent to B "is a" A. For example if apple extended fruit, apple 'is a' fruit. It acts like a fruit but also does apple things that a banana wouldn't do. So B acts the same way as A, but then also can do other stuff. So in your example, your B overwrites two methods. They will be called by every B object by default. In order to access A's methods from a B, you need to use the keyword super .
It is part of polymorphism (a key point in java programming) that an object will find any methods in itself first (even if they are overwritten from a parent) and then it will climb the tree of inheritance to find a method that isn't directly in that class.
For your example:
public void methodA() {
System.out.println("methodA"); //This prints no problem.
methodB(); //This searches the "B" class for a method called "methodB" If it can't find it, it checks its parent for a "methodB"
showName();//This searches the "B" class for a method called "showName" If it can't find it, it checks its parent for a "showName"
}
The above code gets called. You know this much (from other comments you made, I'm assuming this.) Once the line methodB() gets called, your object of type B checks the entire B file for the method. It would only jump up to A for the method if it didn't exist. Then it would do the same for showName().
I have a super class:
public class SuperClass {
public void dosomething() {
firstMethod();
secondMethod();
}
public void firstMethod() {
System.out.println("Super first method");
}
public void secondMethod() {
System.out.println("Super second method");
}
}
A sub class:
public class SubClass extends SuperClass {
public void dosomething() {
super.dosomething();
}
public void firstMethod() {
System.out.println("Sub first method");
}
public void secondMethod() {
System.out.println("Sub second method");
}
}
A test class:
public static void main(String[] args) {
SubClass sub = new SubClass();
sub.dosomething();
SuperClass sup = new SuperClass();
sup.dosomething()
}
when I run the test method, I got this:
Sub first method
Sub second method
Can you tell me how this happened? In the sub class dosomething method, I called super.dosomething() and I think the super method will be called, but the override method in sub class was called.
if I do this:
SuperClass superClass = new SuperClass();
superClass.dosomething();
the result is:
Super first method
Super second method
The difference is method invocation place. I think there must be something I don`t know ):
oops!the super reference pointed to subclass in the first example...
like this:
SuperClass sub = new SubClass();
sub.firstMethod();
sub.secondMethod();
In java, the methods binding is always dynamic [ignoring static and private methods here]. Thus, when you override firstMethod() and secondMethod(), any time an object of type SubClass will try to invoke one of them - the overriden method will be invoked - even if it [the invokation] is from the parent's method.
So, as expected - when you invoke super.doSomething(), it calls firstMethod() and secondMethod(), and the overriden methods are being called.
Your object on which the methods are invoked is of type SubClass, not SuperClass. Even if you call a method that is only defined in SuperClass, your execution context remains SubClass. So any method that is invoked that is overridden will in fact execute the overridden method.
The thing to take away from this is that by declaring firstMethod and secondMethod as public, SuperClass is in fact allowing subclasses to override their behaviour. If this is not appropriate, the methods should be private, or final.
Indeed the super doSomething gets called. Do something calls firstMethod and secondMethod, which are virtual methods (any method in Java is by default virtual, which means it can be overriden). So their overriden versions gets called.
You can prevent them from being overriden if you mark them final.
Super.dosomething() does in fact call the method dosomething() in Super class. But inside this method, you call 2 functions which are firstMethod and secondMethod. These methods are overwritten in the Sub class and they are being called from the Sub Class.
As Petar Ivanov suggested:
You can prevent them from being overriden if you mark them final
Why does is print last "I'm a Child Class." ?
public class Parent
{
String parentString;
public Parent()
{
System.out.println("Parent Constructor.");
}
public Parent(String myString)
{
parentString = myString;
System.out.println(parentString);
}
public void print()
{
System.out.println("I'm a Parent Class.");
}
}
public class Child extends Parent
{
public Child() {
super("From Derived");
System.out.println("Child Constructor.");
}
public void print()
{
super.print();
System.out.println("I'm a Child Class.");
}
public static void main(String[] args)
{
Child child = new Child();
child.print();
((Parent)child).print();
}
}
Output:
From Derived
Child Constructor.
I'm a Parent Class.
I'm a Child Class.
I'm a Parent Class.
I'm a Child Class.
Because this is an example of polymorphism (late binding). At compile time you specify that the object is of type Parent and therefore can call only methods defined in Parent. But at runtime, when the "binding" happens, the method is called on the object, which is of type Child no matter how it is referenced in the code.
The part that surprises you is why the overriding method should be called at runtime. In Java (unlike C# and C++) all methods are virtual and hence the overriding method is called. See this example to understand the difference.
Both:
child.print();
and
((Parent)child).print();
Should return:
I'm a Parent Class.
I'm a Child Class.
In that order.
Casting an object to its base class doesn't change which method call gets made.
In this case, even after the cast, the child print method gets called and not the parent.
Even though you cast child to Parent this does not change its implementation of the method. This does not actually make it a parent. This is why you can do something like:
Image img = new BufferedImage(...);
Even though Image is abstract img is still a bufferedImage underneath.
Even though you are casting it as the Parent class, that does not mean it will use its parent's functions-- it will only treat the object as a Parent.
By saying ((Parent)child).print(); you are saying "Treat this object as a Parent Object, Not a Child Object". Not "Use the parent method implementations"
Thus if the child object had other methods you wouldn't be able to call them. But since print() is a method of the parent you can still call it, but it uses the actual object's (not the class its casted to) implementation.
in java if we call any method on one object then its calls the method by using sub most object ...............
here:
Object
|
|
Parent
|
|
Child <- sub most object
Case 1::
Child child = new Child();
child.print();
this calling child class method print by using child object... child is sub most
so it prints
output::
I'm a Parent Class.
I'm a Child Class.
Explanation: From child method it is calling parent method because of super.print(); method
so first line is I'm a Parent Class. after completion of parent method execution controls comes back to child method and prints I'm a Child Class.
Case 2::
((Parent)child).print();
if we call like this jvm calls print () method by using sub most object here sub most object is child object so it prints
output::
I'm a Parent Class.
I'm a Child Class.
Explanation: From child method it is calling parent method because of super.print(); method
so first line is I'm a Parent Class. after completion of parent method execution controls comes back to child method and prints I'm a Child Class.