-2

I have an interface and three classes. In class B, I define a method called printHello. Then, in class Test, I declare a new IHello object and assign it to a new B.

The problem is, the code does not compile, because I get an error indicating "The method printHello() is undefined for type IHello". This is confusing to me, because I am able to assign an object of type IHello to a new B, so shouldn't that object be able to use B's methods even if the interface does not have them?

To solve this problem, I understand I could either declare a method called printHello in the IHello interface, or I could declare the object of type B instead. Is there anything else I could do to solve the problem?

Interface IHello

public interface IHello {

    void hello();

}

Class A

public class A implements IHello{

    public void hello(){
        System.out.println("hello");
    }
}

Class B

public class B extends A  {

        public void printHello(){
            this.hello();
        }
}

Class Test

public class Test {

    public static IHello b;

    public static void main(String[] args) {

        b = new B();
        b.printHello(); //The method printHello() is undefined for type IHello
    }
}
Omar N
  • 1,720
  • 2
  • 21
  • 33
  • 3
    What is the *type* of the ***variable*** (not the *object*)? This is what the compiler sees. This has been asked here a gazillion times by the way. – Hovercraft Full Of Eels May 31 '17 at 21:26
  • The type of the variable is IHello, but since its assigned to a `B`, I am trying to understand why I can't use the methods of `B`. – Omar N May 31 '17 at 21:30
  • 3
    The compiler is not looking at the actual object type. It's looking at the type you declared - IHello. In some cases, the compiler might not *know* the actual object type, because that might be available only at run time. – Andy Thomas May 31 '17 at 21:32

1 Answers1

2

Class B extends Class A, and none of your Class A or B has relationship with Interface IHello, therefore you cannot instantiate B and assign it to b because the type of b is IHello

If your Class A is an implementation of Interface IHello, you should make it as

public class A implements IHello{
    ...
}

Be aware that if you declare instance variable x as type XXX, only the methods in class XXX is visible to instance x. In your case, you declare b as IHello, only method hello() is accessible by instance b, it cannot access printHello(), only instance declared as B can invoke printHello(), if you are 100% sure b is an instance of B, you can cast instance b to type B.

Haifeng Zhang
  • 30,077
  • 19
  • 81
  • 125