Home > front end >  Object evaluating in java
Object evaluating in java

Time:02-08

I don't understand, why Java acts the way it does.

I have two classes,

Class A:

public class A {
  public String s = null;

  public A(int s) {
    this.s = "a";
  }

  public A(String s) {
    this.s = "b";
  }

  public int f(A p) {
    return 2;
  }
}

Class B:

public class B extends A {
  public String s = "c";
  public B() {
    super(null);
  }
  public B (String s) {
    this (0);
    this . s = s ;
  }
  public B (int x) {
    super ("d");
  this . s = this . s   x ;
  }
  public int f (A p) {
    return 3;
  }
  public int f(B p) {
    return 4;
}

If I know have my main class, in which I run the following code:

public class Test {
  Public static main(String[] args) {
    B b1 = new B("g");
    A ab = new B(6);
    System.out.println(ab.f(b1));
  }
}

Why am I getting 3 as an result, and not 2 or 4, like I would expect? Normally I would assume, if I run the method f of the object ab, and give f the object b1 as a parameter, it would either return 2, not compile (since the only method f in Class A uses an Object A and not an Object B) or it would look for another method f in Class B, that uses an Object B as a parameter and would execute that, in which case the program should return 4.

CodePudding user response:

This is the relevant statement

ab.f(b1)

The fact that you are passing the object reference b1 to the method is irrelevant because none of these methods are doing anything with the parameters being passed. The question here is should calling f() return 3 or 2? It will return 3 because are creating an instance of B (A ab = new B(6);) and this class B overrode the f() method.

What is the impact of A ab = new B(6);?

When you instantiate objects using the superclass to the right of the assignment symbol =, you are actually widening the type of the object created (Making an object of a subclass into an object of a superclass). If the subclass have new methods, those methods will be inaccessible to this object. Only methods declared in the superclass are accessible and, through polymorphism, overridden methods are accessible as well (as was already demonstrated by the example above). However, if we were to add a new method to class B

public void newMethod() {
    System.out.println("new method");
}

and modified the Test class

public class Test {
    public static void main(String[] args) {
        B b1 = new B("g");
        A ab = new B(6);
        System.out.println(ab.f(b1));
        ab.newMethod(); // compile error
        b1.newMethod();
    }
}

newMethod will be inaccessible to instance ab but not to b1. For this reason, the method f(B p) is inaccessible for ab, as you can see in the image below.

enter image description here

CodePudding user response:

I think it calls your f method in class B that returns 3 because, even though b1 is of class B, class B is a subclass of A. Since :

public int f (A p) {
   return 3;
}  

comes before the other f method, it checks that first. It says is b1 of type A? And the answer is yes, because all Bs are As. So it uses that function, returns 3 and completes the method call.

CodePudding user response:

Your example has a lot of code that isn't relevant to the operation at hand. It might get a little easier to see if we strip back to something simpler.

public class Person {

    public String greetPerson(Person otherPerson) {
        return "Hi other person!";
    }
}

public class Doctor extends Person {

    public String greetPerson(Doctor otherDoctor) {
       return "Doctor.";
    }
}

public class Test {
   public static void main(String[] args) {
       Doctor doctorOne = new Doctor();
       Person doctorTwo = new Doctor();
       
       System.out.println(doctorTwo.greetPerson(doctorOne));

       //Output is "Doctor."
   }
}

Perhaps this already makes things more clear, but the reasoning is that at runtime, Java will execute the method based on the ACTUAL type of the object, rather than the type of the reference.

Doctor two here is ACTUALLY a doctor, so Java will attempt to find a Doctor method for him to use before looking into the parent class for a matching method. Our greet person method signature in the doctor class matches both the name and the parameter that was matched, so that is the method that will be executed.

In the same way, "ab" in your code is ACTUALLY a B, so it will find the method in B that matches and execute it

  •  Tags:  
  • Related