1

I made a small toy program to replicate a problem I am having in a larger project. In the following code, class A is a parent class from which class B inherits. Class B adds a new method called PrintStuff. In my main method I am declaring class B by providing its superclass. I need to do this for reasons related to the real use case:

package com.company;
import java.lang.String;

class A {
    String x;

    A(String value) {
        x = value;
    }
}

class B extends A {
    B(String value) {
        super(value);
    }

    void printStuff() {
        System.out.println(x);
    }
}

public class test {
    public static void main(String[] args) {
        A Binstance = new B("B instance");

        Binstance.printStuff();
    }
}

However the program does not compile due to the following:

C:\Users\me\Desktop\Library\src\com\company\test.java:28:18
java: cannot find symbol
  symbol:   method printStuff()
  location: variable Binstance of type com.company.

Why is Java not able to recognize that in reality I am instantiating an object of class B? How can I get the compiler to recognize that a method printStuff in fact exists?

user32882
  • 5,094
  • 5
  • 43
  • 82
  • 2
    `Binstance` is an `A`, not a `B`. What `Binstance` actually is, is decided at runtime, so the compiler can't guarantee it's a `B`. You'll have to cast it to assure the compiler you know what you're doing. – Federico klez Culloca Dec 16 '20 at 13:08

3 Answers3

1

During compilation time we know only that the Binstance object is of type A, which means it doesn't know anything about the printStuff() method (which you declared in class B) and that's why you get that error.

Now, you have two options:

  1. You can use a cast

     public static void main(String[] args) {
         A Binstance = new B("B instance");
    
         ((B)Binstance).printStuff(); //casting Binstance to B
     }
    
  2. You can make class A abstract and create an abstract method - printStuff()

     abstract class A {
    
         abstract void printStuff();
     }
    
cristagp
  • 26
  • 3
0

Binstance is declared as having type A and printStuff() is not declared in A, but in B. Only methods of A are visible in this case. The method is there, but not visible. To make it visible, declare Binstance as B.

B Binstance = new B("B instance");
Binstance.printStuff();
EricSchaefer
  • 25,272
  • 21
  • 67
  • 103
  • As I indicated in the question, I need to maintain the declaration using type `A` for reasons related to the actual use case. – user32882 Dec 16 '20 at 13:45
  • Then you need to declare printStuff() in A or cast Binstance to B when calling printStuff(). There is no other way. This is how Java's type system works. – EricSchaefer Dec 16 '20 at 15:09
0

Note this carefully: when B extends A, all B is an A, but not the other way around.

So in your case, Binstance is an A and then can't access the printStuff method of B.

To make your code work, you need to coerce Binstance to be of type of B; this is called a cast in java.

So this should work : (A(Binstance).printStuff();

Happy Coding !

bashizip
  • 562
  • 5
  • 14