If you want classes B and C to have separate static variables, you’ll need to declare the variables in those classes. Basically, static members and polymorphism don’t go together.
Note that accessing static members through references is a really bad idea in terms of readability – it makes it look like it depends on the value of the reference, when it doesn’t really. So your current code won’t even compile when you’ve moved str down to B and C. Instead, you’ll need
System.out.println("b.str = " + B.str);
System.out.println("c.str = " + C.str);
If you really need to access the value polymorphically (i.e. through an instance of A) then one option is to make a polymorphic getter:
public class A {
public abstract String getStr();
}
public class B extends A {
private static String str = "b";
@Override public String getStr() {
return str;
}
}
(and the same for C).
That way you get the behaviour you want in terms of not having a separate variable per instance, but you can still use it polymorphically. It’s a little odd for an instance member to return a static value like this, but you’re using the value for polymorphism of type, basically…