6

In the following code, I pass to the method "testmethod() an instantiation of a subclass of A, named B

Unfortunately, the signature for the method accepts the superclass A not the subclass B and I can't change that signature since it's referred by many classes.

Is there a way (without changing the signature of testmethod()) that I can access the var2 variable from within testmethod() that is part of the object that was passed to testmethod?

    public class test5  {

        public static void main(String args[]){
            B b = new B();
            testmethod(b);
        }

        public static void testmethod(A a2 ) {
            System.out.println("in testmeth->" + a2.getVar1() );   // WORKS
            System.out.println("in testmeth->" + a2.getVar2() );   // DOESNT WORK
        }
    }

    class A  {
        int var1 = 2;

        public int getVar1() {
            return var1;
        }
    }

    class B extends A {
        int var2 = 8;

        public int getVar2() {
            return var2;
        }
Sarta
  • 139
  • 2
  • 9
  • 4
    You really shouldn't *need* to do this. If `testmethod()` requests an instance of `A` then it should use the operations on `A`. If it needs a `B`, then the method signature should require a `B`. – David Jan 19 '16 at 17:37
  • Or you could overload the method... – user1675642 Jan 19 '16 at 17:39

4 Answers4

3

You can downcast but this is generally not a good practice.

So it would be

System.out.println("in testmeth->" + ((B) a2).getVar2() );

Note: if a2 is not an instanceof the class B then this line would result in a ClassCastException

RamV13
  • 547
  • 4
  • 8
3

You can cast like this:

if(a2 instanceof B)
  System.out.println("in testmeth->" + ((B) a2).getVar2() );
else
  System.out.println("in testmeth->" + a2.getVar1() );
CMPS
  • 7,733
  • 4
  • 28
  • 53
  • 1
    In the code sample in question, the instance of adds no value as its explicitly a B type already. – tgkprog Jan 19 '16 at 17:33
  • 2
    That's true, but the OP mentioned that it's used by many classes, therefore it might have been used while passing an instance of A instead. @tgkprog – CMPS Jan 19 '16 at 17:36
  • Worked perfectly, requiring no method signature change! – Sarta Jan 19 '16 at 22:52
  • 1
    @user3302169 Glad that was helpful. And for the -1 ... haters gonna hate :) – CMPS Jan 20 '16 at 22:39
2

You could overload the method, and then the most specific one will be chosen when called. ie:

public class test5  {

    public static void main(String args[]){
        A a = new A();
        B b = new B();
        testmethod(a);
        testmethod(b);
    }

    public static void testmethod(A a2 ) {
        System.out.println("in testmeth_a->" + a2.getVar1() );
    }

    public static void testmethod(B b2 ) {
        System.out.println("in testmeth_b->" + b2.getVar2() );
    }
}

NB. The method called depends on the declared type and not the type of the object passed in. See here.

Community
  • 1
  • 1
user1675642
  • 747
  • 2
  • 5
  • 15
0

It's hard to tell from the minimal example, but it looks like you might want to make A an abstract class, which requires B (and any other subclasses) to implement getVar2(). When you do this, getVar2 is accessible through any instance of A:

abstract class A {
   int var1 = 2;

    public int getVar1() {
        return var1;
    }
    public abstract int getVar2();
}
ach
  • 6,164
  • 1
  • 25
  • 28