Why does Java base class constructor call derived class' methods? [duplicate] - java

This question already has answers here:
Polymorphism and Constructors
(2 answers)
Closed 3 years ago.
I have a derived Java class override a base class' method. When the base class calls the method, it executes the derived class' function, rather than its own. Why?
public class HelloWorld{
public static void main(String []args){
Derived d = new Derived();
System.out.println("Main");
}
}
class Base {
void f() {
System.out.println("Base::f()");
}
public Base() {
f();
}
}
class Derived extends Base {
void f() {
System.out.println("Derived::f()");
}
public Derived() {
f();
}
}
The code prints Derived::f() twice, I expect it to print Base::f() followed by Derived::f(), as would happen in C++

In Java, unlike in C++, instance methods are virtual by default. It means that a method call is dispatched at the run time according to the actual run-time class of an object (not at the compile time). In C++, you achieve this behaviour with keyword virtual.

Your Derived f() method is overriding the Base f() method. If you want to see the Base method try putting super.f(); in the start of the Derived f() method, this will call the super class' f() method.

Related

Method binding when passing control to superclass [duplicate]

This question already has answers here:
Confusing "override a private method"
(3 answers)
Can I override a private method in Java?
(10 answers)
Java private method override
(4 answers)
Override "private" method in java
(5 answers)
Closed 4 years ago.
class Base {
private void func(){ // method overridden if public
System.out.println("In base func method");
};
public void func2() {
System.out.println("func2");
func(); // alternatively, this could be: ((Derived) this).func();
}
}
class Derived extends Base {
public void func(){
System.out.println("In Derived Class func method");
}
}
class Test {
public static void main(String [] args) {
Derived d = new Derived();
d.func2();
}
}
As written, this code will call the func() of the Base class because this method is private and there is no method overriding going on.
However, if the func() line of func2() is changed to ((Derived) this).func(), the func() of the Derived class will be called.
From what I can tell, it seems as if the Derived object is being treated like a Base object once the control enters the func2() of the Base class.
Is my understanding correct? How can my understanding be reconciled, if at all, with method overriding in the case where the func() of the Base class is instead public rather than private and runtime binding occurs? Does the call to func() in func2() first find the Base class func() and then decide to use func() in the subclass due to method overriding? Exactly what happens at runtime here?
According to what I have understood from your question, you are confused about what happens during the runtime when the method func() is called from func2() of the Base class.
When Java finds a method inside the superclass's method that is overridden in the subclass, it finds that the method is in the subclass.
So, in your case, the method func() is executed, not of the Base class but of the Derived class due to late binding. Because the Derived Object is calling the method func2(), the method func() comes back to the subclass (Derived). If, however, the call were made to the Base class, the func of the Base class would be called.
So the overall takeaway is this: Late binding is purely based off of the object calling the function. Java checks for overridden methods of the subclass during the late binding (run-time).

Explain the output of below java code [duplicate]

This question already has answers here:
“overriding” private methods with upcasting call in java
(1 answer)
Overriding private methods in Java
(10 answers)
Closed 5 years ago.
Can anybody explain why output to below question is "A.test" ?
class A {
private void test(){
System.out.println("A.test");
}
public void mytest(){
this.test();
}
}
class B extends A{
protected void test(){
System.out.println("B.test");
}
}
public class Test{
public static void main(String[] args) {
A a = new B();
a.mytest();
}
}
The test() method of class A cannot be overridden by class B, since it is private. Therefore this.test(); invokes A's test() method even though it is executed on an instance of class B.
Super class can invoke the methods of the sub class without using typecasting, without using reflection and without using a reference other than this only if they are overridden.
In your case A a = new B(); , object of B is created which has both the behaviours private void test() as inherited by super class A as well as protected void test() as added by B. The reason for both the methods being there and not just one is that due to the acess modifier being private the method is not visible in subclass scope. Hence it can not overriden and adding the method with same name just simply adds another method.
As there is no run time polymorphism in this case hence compile time target method is resolved and method defined in A is invoked.
If in case you would have overriden the mytest in B and from the overriden mytest you would have made a call to test then method in B would have been invoked. This is easy to understand as any method of B can not see any private method of its super class.

Java: Call a base super class method while skipping intermediate inherited super classes [duplicate]

This question already has answers here:
Calling super super class method
(12 answers)
Closed 8 years ago.
Let say I have three classes:
class A
{
public void method()
{ /* Code specific to A */ }
}
class B extends A
{
#Override
public void method()
{
/*Code specific to B*/
super.method();
}
}
class C extends B
{
#Override
public void method()
{ /* I want to use the code specific to A without using B */ }
}
The goal in this case is to use the code from A without using the code from B. I thought there was a way to do it by calling the super method, but this brings in the code from B as well.
Is there a way to do this?
The short answer is no. What you're seeing is that your design is flawed. It indicates that you need too move the code in class A out into a helper class. B and C would then use it via composition. You could try using partials to get the behavior you want. See this link for more details. Partial function application in Java 8
You could instantiate an object of class A in C and call the method method
class C extends B
{
#Override
public void method()
{ /* I want to use the code specific to A without using B */
A test = new A();
test.method();
}
}
Not sure if this is what you meant. Also asumed you forget the method name method in class A.
No there is no way to do it. You can simply create another method in class B that executes the code of A's method, and call that method in subclass C.

Can a method in sub class overloading a method in super class?

Java code:
class P {
public void hello() {}
}
class C extends P {
public void hello(String s) {}
}
My question is: Is the hello in class C overloading the one with same name in super class P?
My friend says they are not because the are not in the same class.
Taking a more formal approach, the Java Language Specification for Java 7 states:
If two methods of a class (whether both declared in the same class, or both inherited by a class, or one declared and one inherited) have the same name but signatures that are not override-equivalent, then the method name is said to be overloaded.
http://docs.oracle.com/javase/specs/jls/se7/html/jls-8.html#jls-8.4.9
I would point your friend to this link.
So, in short, in your example, the hello method is indeed overloaded.
Simple Explanation:
I think this question arises because at times we hear the following,
"Method overloading is performed within class.
Method overriding occurs in two classes that have inheritance relationship."
The above statement is correct. But your friend is wrong. why?
Because when you extend a class, the subclass have all the methods defined by superclass. It is as if all the methods of superclass have been implemented by the subclass. That means the hello() method has been implemented by the class C as well. Now, you added a method in class C with different parameter (hello(String s)). That means, class C has two methods in all with same name but different parameters and that is "overloading".
Hope it is crystal clear.
Overloading can happen in same class as well as parent-child class relationship whereas overriding happens only in an inheritance relationship.
Yes, your friend is wrong because he thinks only of the concept of overriding.
But here hello(), and hello(String s) are different by there parameters so it's overloading not overriding.
Source of confusion: Your friend would be right if speaking about C++ not Java. In C++, function overloading can only occur between members of the same class. Whereas in Java, overloading can occur, in addition to that, across two classes with inheritance relationship.
Yes it is overloading, This overloading is happening in case of the class 'C' which is extending P and hence having two methods with the same name but different parameters leading to overloading of method hello() in Class C. However Class P is only able to access one of the methods which is present in its own definition.
Long story short, an instance of C will have both the hello() and the hello(String s) methods available. An instance of P will only have the hello method available.
This is indeed overloading, as you have two methods of the same name taking different parameters.
However, it is not overriding, because overriding is having a method declared in a subclass with the same name and same parameters as a method in a superclass.
E.g. if you had
class C extends P {
public void hello() {}
}
it would be overriding the hello() method declared in P. When invoking new C().hello() in that case, you would invoke the implementation of the hello() method declared in class C.
It is a valid question since usually, overloading is explained using two methods with the same name (but different parameters) in the same class.
I would argue that yes, the method hello in C is overloading P's hello method because of the "is a" relation.
The "is a" relation states that since C subclasses P, it is also an instance of P ("C is a P"). Hence C has 2 overloaded hello-methods.
Good question!!!In sub class if method name | parameter type | list is changed then sub class method will not be considered as overriding it is considered as overloading method
Example :
class A{
void m1(int a){}
}
class B extends A{
void m1(float f)
{}
}
In above program m1 method is a overloaded method.
Yes we can overload the super class method in sub class like as bellow:
public class OverLoading {
public static void main(String[] args) {
B b = new B();
b.display();
b.display(4);
}
}
class A {
public void display() {
System.out.println("A class display method");
}
}
class B extends A {
public void display() {
System.out.println("class B subclass");
}
public void display(int a) { //Overloading in subclass
System.out.println("class B subclass with overloading");
}
}
Output:
class B subclass
class B subclass with overloading
Depends on the class. From class P's perspective (if the reference is P, the object can be of C) it is not. If you write something like: P p = new C(); there is no overloading because you cannot call p.hello("foo").
From class C's perspective it is overloaded because if you write C c = new C(); it has two methods with same name and different signatures.
This is a good question and the answer is a bit tricky.
Well, it's true that you can overload an inherited method from a parent class into a subclass. However, and here's the interesting part, the actual behavior depends on the reference variable type.
Let's consider the following example:
public class OverLoadingTest {
public static void main(String[] args) {
ChildClass cc = new ChildClass();
SuperClass sc = cc;
sc.method("lol");
cc.method("lol");
}
static class SuperClass {
public void method(Object o) {
System.out.println("SuperClass called.");
}
}
static class ChildClass extends SuperClass {
public void method(String s) {
System.out.println("ChildClass called.");
}
}
}
So, we have a class extending another and with a method that overloads a method from the parent.
It's easy to guess that if you have an instance of ChildClass, the two methods are overloaded, and overloading resolution takes place as it normally does.
However, let's consider creating an instance of ChildClass and assigning it to a reference variable of type SuperClass. Is the overloading thing still standing?
If you execute this program you will get this outptut:
SuperClass called.
ChildClass called.
The output clearly indicates that there's no overloading here in this case. This however can be altered by overriding the original method.
static class ChildClass extends SuperClass {
public void method(String s) {
System.out.println("ChildClass called.");
}
public void method(Object o) {
System.out.println("ChildClass called.");
}
}
Now, if you run the program again, you get this output:
ChildClass called.
ChildClass called.
Explanation
Now, why is JVM behaving that way? Why can't it see the overloading method as we're using an instance of the child class?
This takes us to how does JVM call a method. The JVM sees that you're referring to the object with a reference of type SuperClass, so, it can only use the methods that are related to that type, with the only exception is overriden methods. And since method(String) isn't overriding, we have method(Object) of the parent, hence, it's the one chosen for execution.
We then override the method to break this rule, and this is how the JVM called ChildClass.method(Object) even if the reference variable is of a parent class.
Overloading is when you have two methods that have the same name but different signatures (Your case).
Side note: Overriding is when you have two methods that have exactly the same signature and name and the parent class.

Java Vs C#: Java and C# subclasses with method overrides output different results in same scenario

Ok! I have same code written in Java and C# but the output is different!
class A
{
public void print()
{
Console.WriteLine("Class A");
}
}
class B : A
{
public void print()
{
Console.WriteLine("Class B");
}
}
class Program
{
static void Main(string[] args)
{
A a = new B();
a.print();
Console.Read();
}
}
Output: Class A. It is in C#.
But when same code was ran in Java, the output was Class B. Here is the Java Code:
class A
{
public void print()
{
System.out.println("Class A");
}
}
class B extends A
{
public void print()
{
System.out.println("Class B");
}
}
public class Program{
public static void main(String []args){
A a = new B();
a.print();
}
}
So, why this is showing different results? I do know that, in Java, all methods are virtual by default that's why Java outputs Class B.
Another thing is that, both languages claim that they are emerged or inspired by C++ then why they are showing different results while both have same base language(Say).
And what does this line A a = new B(); actually doing? Isn't a holding object of class B? If it is so, then why C# displays Class A and Java shows Class B?
NOTE This question was asked in interview with the same code provided above. And I answered with output Class B (with respect to Java) but he said Class A will be right output.
Thank you!
This is because in C# methods of derived classes hide, not override, methods of their base class. The methods that you would like to override need to be explicitly marked with the keyword virtual in the base, and with the keyword override in the derived classes.
In contrast, in Java all methods are virtual by default: simply specifying the same signature is sufficient for an override.
Here is how to make your C# program an equivalent of Java program:
class A
{
public virtual void print() // Add "virtual"
{
Console.WriteLine("Class A");
}
}
class B : A
{
public override void print()// Add "override"
{
Console.WriteLine("Class B");
}
}
After A a = new B(), variable a is holding object of B but the output is "Class A"! Shouldn't it call method of class B?
When you hide a method, rather than overriding it, your derived class keeps both methods - the one in the base class, and the one in the derived class. Both these methods remain accessible to the outside callers. They can decide which of the two methods to call by using an object of an appropriate static type. Here is an example:
B b = new B();
b.print(); // Prints "Class B"
((A)b).print(); // Prints "Class A"
Demo on ideone.
When you use virtual/override, you can access only one method from the outside - namely, the one in the derived class. The method in the base class can be accessed by methods of the derived class, but not by the outside users of the derived class.
In Java, non-static methods are virtual, whereas in C#, they are not. You will need to use the virtual and override keywords on your print method to get the same behaviour in c#.
Polymorphic behaviour in C#:
class A
{
public virtual void print()
{
Console.WriteLine("Class A");
}
}
class B : A
{
public override void print()
{
Console.WriteLine("Class B");
}
}
Edit
Getting back to your original C# code, you will get a compile time warning on B.print when you use the same method signature in both a subclass and its superclass, viz:
The keyword 'new' is required on 'print' because it hides method
'MyNamespace.A.print()'
This is a good indication that the method won't be called polymorphically / virtually. To avoid the warning (and retain your original C# behaviour), in B you would need to add new:
public new void print()

Categories

Resources