How to resolve issue between Interface and Inheritance - java

I am facing a confusion. please look into the below java code.
public interface Interface {
public void draw();
}
public class A {
public void draw()
{
System.out.println("Draw in A");
}
}
public class B extends A implements Interface {
#Override
public void draw()
{
System.out.println("Draw in B");
}
}
public class Main {
public static void main(String [] args)
{
Interface i = new B();
i.draw();
A a = new B();
a.draw();
B b = new B();
b.draw();
}
}
For all I am getting the same output ("Draw in B"). Could you please tell me which draw() is getting invoked (Interface / Parent class)?

Java performs late binding, meaning it is the method of the instance that gets invoked, not the method corresponding to the type.
A a = new B();
^ ^
type instance
In this case, you create only B instances (new B()), so the method of B gets invoked each time, irrespective of your assigning this instance to a variable of type A.
See also: dynamic dispatch

As you might have guessed, it is the draw() method in class B that is getting invoked. This is because even though you have declared the varialbles i, a, and b as being able to reference different type, you choose to assign instances of type B to all of them. In other words, when draw is invoked what matters is the runtime type of the object (the one created by new B()), and not how the variable is declared.

The method which is invoked depends on the Object created. So, the method of the RHS (B) is invoked always.

every time you create instance of B class, and its method is being invoked

In a simple words it is because of new B(). it doesnt matter what type it is, when you instantiating from B, all methods from B(and it's parents if B not implementing them.) will be invoked.

Related

"The type of a class variable determines which method names can be used with the variable". What does that mean?

I'm currently studying polymorphism but I don't understand the following statements:
"The type of a class variable determines which method names can be used with the variable.
However, the object named by the variable determines which definition with the same method name is used."
I'm confused.
It means that the methods you can call from an object are limited by the type of that object. For example, let's say you have these classes:
public class Animal {
public void sayName() {
System.out.println('animal');
}
}
public class Cow extends Animal {
#Override
public void sayName() {
System.out.println('cow');
}
public void sayMoo() {
System.out.println('mooo');
}
}
Now, you can declare your cows like this:
Animal cow = new Cow();
You can do that because Cow is a subclass of Animal. However, if you do that you'll be unable to say moo with your Cow, because you have created the variable as a simple Animal. Therefore, the method sayMoo is unaccessible from your variable.
The type of a class variable determines which method names can be used with the variable.
This means that if you have a class Base and a variable of type Base:
Base base = ...
You can call a method
base.method()
only if method() is defined in class Base (or a super-class of Base).
However, the object named by the variable determines which definition with the same method name is used.
This means calling base.method() doesn't always execute method() of class Base.
If, for example, Derived is a class that extends class Base and overrides method() method, then if the actual type of the instance referenced by base is Derived:
Base base = new Derived();
then calling
base.method();
will execute Derived's class implementation of method().
The "type of a class variable" means the static (compile-time) type of a reference variable.
The "object named by the variable" means the dynamic (run-time) type of the instance (object) referenced by the variable.
Consider the following code (and explanations inside):
class A {
public void methodA() {
System.out.println("A -> A");
}
public void methodB() {
System.out.println("A -> B");
}
}
class B extends A {
#Override
public void methodB() {
System.out.println("B -> B");
}
public void methodC() {
System.out.println("B -> C");
}
}
A a = new B();
// here, the type of variable a determines which methods can be called on that var.
// A declares two methods, methodA and methodB and only those can be called.
// Even a is actually referring to an instance of B which declares methodC
// as well, the call a.methodC() is not valid because a has type A.
a.methodA(); // prints A -> A
// Here, the actual implementation (the object that a refers to) determines
// which implementation is being called and because the actual object
// is an instance of B, we get B -> B printed.
a.methodB(); // prints B -> B
// a.methodC(); cannot be called
To put it simple, you will be able to execute methods specific to your class variable and not of the class instance.
In this way you are able to use interfaces as declared class variable and instantiate a new object.
Display display = new TV();
You will be able to execute whatever method Display has, but not the specific method that TV has.

How the Given Data type effect Overriding member variables

I have studied some of the related posts about this topic and I have learned that when we make a variable of the same name in a subclass, that's called hiding.
class A {
int i = 10;
public void printValue() {
System.out.print("Value-A");
System.out.println(i);
}
}
class B extends A {
int i = 12;
public void printValue() {
System.out.print("Value-B");
System.out.println(i);
}
}
public class Test {
public static void main(String args[]) {
A a = new B();
a.printValue();
System.out.print(a.i);
}
}
When I instantiate class B with type A and print member data
A a=new B();
System.out.println(a.i)//The output is `10`.(The value of parent class member data).
But when I instantiate class B as type B,
B a=new B();
System.out.println(a.i)//The output is 12. (The value of parent class member data)
I would like to know how they are different.
Variables bind to the reference, not to the object created. In your example, A a = new B(); Here a is a reference to which variable binds of type A. And, created object is of type B, to which methods are bind. That's why it is picking values for variables of references. This is called data hiding. Because when we create same variable in sub-class, value of variable of sub-class is hidden under super class variable. Hope it helps.
Polymorphism applies only on methods. Variables still binds to the type. You can't ovveride variables. That is the reason you are seeing different output when you changing the type.
In simple words, when you write
A a=new B();
Just to remember, variables bind to left side and methods gets execute from right side.

Polymorphism inside constructors in Java

Code:
class A{
A() {
test();
}
void test(){
System.out.println("from A");
}
}
class B extends A {
void test() {
System.out.println("from B");
}
}
class C {
public static void main(String args []){
A a = new B();
a.test();
}
}
Output:
from B
from B
Why is it getting printed that way ?
This is extremely bad code. What's happening is that void test() is being overridden in the child class B.
new B(); creates an instance of class B. The fact that you reference cast it to A is not relevant here. But even though the child class has not yet been constructed, the Java runtime calls a method in that child class from the constructor of the parent class A.
Use this (anti)pattern with extreme caution! (Note that in C++ you get undefined behaviour).
When you call a polymorphic method at runtime, Java uses a special data structure to decide a method of which class needs to be called. This structure is set up at the time the object is constructed, before any of the user-supplied constructor and initializer code get executed.
When you create A a = new B(), the data structure that says "when test() is called, you need to call A.test() or B.test()" is prepared before the constructor of A is entered. Since this structure is prepared for the B class, it points to B.test(), even though the calling code is inside A's constructor. That is why you see "from B" printed twice.
Note, however, that although technically your code will do what you want, logically it is a very poor decision. The reason why this code is bad has to do with the initialization sequence: imagine a test() method that relies on private fields of B being initialized in the constructor, like this:
class B extends A {
private final String greeting;
public B() {
greeting = "Hello";
}
void test() {
System.out.println(greeting + " from B");
}
}
One would expect to see "Hello from B" being printed. However, you would see it only in the second call: at the time the first call is made, greeting is still null.
That is why you should avoid calling method overrides from inside a constructor: it breaks method's assumption that the object has been fully initialized, sometimes with rather unfortunate consequences.
During runtime, the method is invoked from actual instance object. i.e B.
A a = new B();
a.test();
In the above code, You have instantiated Object B, not A. You have just assigned the reference variable of type A. Internally, it is referring only an instance of B. During compilation, it just checks whether the method is actually present in A reference and allow it to compile. During Runtime, the method is actually invoked on the real object i.e. B referred by the reference A
This is one of the most important concepts of Object Oriented polymorphism.
By extending A with class B you are creating a more specific implementation of it, overriding some of its methods with new ones (such as your test() method) and potentially adding things to it (members and methods).
Whenever you override a class, the methods of the subclass will be invoked, irrespective of which class they are 'acting' to be.
When you cast an object to another class (like in your case B to A) you are just saying I want to see it as a reference of type A. This is useful for methods that accept objects of type A as parameter.
Consider this example:
Employee (super class) which has method float computeSalary()
Technician extends Employee which overrides method float computeSalary()
Manager extends Employee which overrides method float computeSalary()
The SalaryGenerator class has a method generateMonthlyPay(Employee e) that calls the computeSalary() of the Employee superclass, but the specific sub-class method will be invoked, because each have a different way of calculating their monthly salary.
Although the reference type is A, it's object type is B which means that it is pointing to the implementation in B. Hence, from B gets printed.
When the object a is created using,
A a = new B()
the constructor gets invoked from base class to derived class.. here the base class constructor calls test(), but this calls test() in derived class because of the over riding concept.
So you get " from B" initially.
Again a.test() calls the over rided derived class test(). So again from B is printed

Confusion in Java polymorphism

I am having confusion in java polymorphism. In dynamic method binding jvm decides at run time which class method has to call. Suppose I am having three classes A, B and C.
class A{
int get(){
return 10;
}
int getParent(){
return 10;
}
}
class B extends A
{
int get(){
return 20;
}
}
public class C
{
public static void main(String args[])
{
A a = new A();
A a1 = new B();
System.out.println(a.get());/////////////////////////LINE1
System.out.println(a1.get ());////////////////////////LINE2
System.out.println(a.getParent());////////////////////////LINE3
}
}
I am having confusion in line 1 and line3 at compile time and runtime binding.
In line 3 it a.getParent() and this method is in parent class only so what it has to decide at runtime.
In line 1 both reference and object are from same class so again what it has to decide .
Please send me any good link for runtime and compile time binding how works.
class A
{
public doIt( )
{
//this does something
}
}
class B extends A
{
public doIt( )
{
//this does something
}
}
class C extends B
{
public doIt( )
{
//this does something
}
}
public static void main(String[] args) {
A x = new B( );
x.doIt( );
}
The statement that causes a lot of confusion is the “A x = new B();” statement. Although the variable x is an object of type A, it is instantiated as an object of class B – because of the “= new B( );” part of the statement. The Java runtime will basically look at this statement and say “even though x is clearly declared as type A, it is instantiated as an object of class B, so I will run the version of the doIt() method that is defined in class B.”
The version of the doIt() method that’s executed by the object x is the one in class B because of what is known as dynamic binding in Java – the code above can be considered to be an example of dynamic binding. Dynamic binding basically means that the method implementation that is actually called is determined at run-time, and not at compile-time. And that’s why it’s called dynamic binding – because the method that will be run is chosen at run time. Dynamic binding is also known as late binding.
In early binding the data and method are binds at the complie time where as in
late binding the data and method will bind at the runtime.
Class B overrides the get() method. So whenever you call get() on an object that is of type B it will use the overridden method.
Because B doesnt override getparent(), then the parent getParent() will be called when you call it on class B
Class A provides the Object instance a with a virtual method table, containing A.get and A.getParent.
Class B provides the Object instance a1 with a virtual method table, being first taken from class A, and expanded (here nothing to expand with). The get method is overwritten with B.get.
a1.get, even being a A, will call B.get.
polymorphism here applies only in the case of line2. There is no concept of polymorphism applied to line1 and line3.

How to call base class method with derived class Object when that method overridden in derived class?

class A
{
public void m1()
{
System.out.println("hi-base class");
}
}
class B extends A
{
public void m1()
{
System.out.println("hi-derived ");
}
public static void main(String args[])
{
B b1=new B();
}
}
In this i want to invoke base class m1 method by using Derived class object without using the super
You would need to construct an object of type A. You have overridden method m1 in the derived class, and so any calls to m1 on an object that was created as a B will have the B version of m1 invoked. Without using super, there's no way to instruct the compiler to make the non-virtual call to the base-class version.
Are you just looking for super.m1();? This will invoke the immediate parent's method.
However, you cannot instantiate an object of type B from outside of B and use this.
You cannot do:
B value = new B();
value.super.m1(); // call A's implementation
However, you could do this within B:
#Override
public void m1()
{
System.out.println("hi from B");
super.m1();
}
public void useAM1()
{
super.m1();
}
Of course, when you start to provide workarounds to get at functionality from A, then it sounds like you are abusing inheritance, or at least should have used an instance of A to begin with.
Interestingly, in C++ you could do this: value->A::m1();. Fortunately, there is no equivalent in Java.
In short you cannot do it -- virtual dispatching would delegate the call to the referred.

Categories