1

I'm having trouble understanding some basic concepts about inheritance and polymorphism in Java.

I'm trying to call on child only methods for child classes that implement a given parent interface. However, I can not call on these child class only methods when I instantiate the child class object and put it in the parent class interface. How I can I do so without compromising polymorphism.

Contract.java

package test;

public interface Contract {

    void getLog();
}

myContract.java

package test;

public class myContract implements Contract {

    public void getLog()
    {
        System.out.println("logging in myContract");
    }

    public void anotherMethod()
    {
        System.out.println("another method");
    }
}

app.java:

package test;

public class app {

    public static void main(String[] args) {
        // TODO Auto-generated method stub
        Contract myContract = new myContract();

        //I can't call below method in child class
        myContract.anotherMethod();
    }

}
jerryh91
  • 1,777
  • 10
  • 46
  • 77
  • 1
    This is code smell. If you need to interact with an instance of`MyContract`, then the static type should be `MyContract`. Alternatively you could add `anotherMethod()` to the interface ***IF IT REALLY BELONGS THERE***, or downcast where you use it, but downcasting indicates a design problem. You haven't provided enough information or context for anyone to suggest the "correct" alternative. – Jim Garrison Mar 17 '16 at 21:12
  • what you want to do is defeating the purpose of polymorphism. see this related question: [What is so important about polymorphism](http://stackoverflow.com/q/25898730/217324) – Nathan Hughes Mar 17 '16 at 21:20

4 Answers4

0

Use instanceof operator to check whether your object is an instance of a specified type. If it is, you can cast the object and invoke the method.

    Contract myContract = new myContract();

    if(myContract instanceof MyContract){
        ((MyContract)myContract).anotherMethod();
    }
Haifeng Zhang
  • 30,077
  • 19
  • 81
  • 125
0

As mentioned by other, you can cast it to MyContract. However, if you want to do this on multiple instances which can have multiple different implementations, a better solution than casting them to their implementation after an instanceof, would be to use a visitor pattern.

Jonathan Schoreels
  • 1,660
  • 1
  • 12
  • 20
0

In your main method you have this:

// TODO Auto-generated method stub
Contract myContract = new myContract();

//I can't call below method in child class
myContract.anotherMethod();

The reason why the last line of this code snippet doesn't compile is because the compiler can't "see" the ".anotherMethod()." You've declared the myContract variable as an object of type Contract. So even though you've instantiated it with "new myContract()", you won't be able to invoke ".anotherMethod()" because ".anotherMethod()" doesn't exist in the Contract interface.

There are two ways to make this work:

  1. Add the ".anotherMethod()" signature to the Contract interface. If you do this, then the compiler will be able to "see" it in the last line of the above code snippet.

  2. Declare your "myContract" variable to be of type myContract (instead of type "Contract", which is the way you've declared above.

Aside from this, I strongly recommend that you follow the convention of naming your classes and interfaces in camel-case. That way, you can clear up some confusion by having the class name be "MyContract", but the instance variable be named as "myContract".

W. Lee
  • 105
  • 5
-1

You have a conflict with your naming. You are creating a class called "myContract", as well as an object "myContract". Due to scoping (the object is in scope), you'll be accessing the object as the object. Use Uppercase first letter for all class names, and don't use the same name for an object as already exists for a class. (Maybe rename class myContract to ControlImpl).

dr.java
  • 46
  • 5