0

I have a class called MilitaryReport that implements the Reportable interface:

public class MilitaryReporter implements Reportable {

    public String reportable_type(){
        return "MilitaryReport";
    }

    public String reportable_db_name() { return "military_reports"; }

    public void setUniqueAttribute(int attr) { this.uniqueAttribute = attr; }

    public int uniqueAttribute(){
       return some_unique_attribute_to_military;
    }
}

I have another class called OilReport that implements the Reportable interface:

public class OilReport implements Reportable {

    public String reportable_type(){
        return "OilReport";
    }

    public String reportable_db_name() { return "oil_reports"; }

    public int anotherUniqueAttribute(){
       return some_unique_attribute_to_oil;
    }
}

This is the Reportable interface:

public interface Reportable {

    public String reportable_type();

    public String reportable_db_name();
}

Here's the problem. The reportable is a strategy that belongs to an instance of Report. A report can have any type of reportable e.g. Military, Oil, Driver, etc. These types all implement the same interface but have unique elements.

I am able to assign a reportable to a Report as so:

public class Report {

    private Reportable reportable;

    public void setReportable(Reportable reportable){ this.reportable = reportable; }

    public Reportable reportable(){
        return reportable;
    }
}

Then in client code, I am able to assign a reportable to this instance:

MilitaryReporter reportable = new MilitaryReporter();
reportable.setUniqueAttribute(some_val);
report.setReportable(reportable);

But when I later access the reportable, I cannot access any of the unique methods. I can only access methods implemented in the interface. This will not compile:

report.reportable.uniqueAttribute();

The problem is I don't want to set reportable's data type to be MilitaryReport. I want the data type to be Reportable, so I can assign any type of reportable to it. At the same time, I want to access the unique methods of the reportables.

How can I get around this limitation? Another design pattern?

Balkrishna Rawool
  • 1,865
  • 3
  • 21
  • 35
Donato
  • 2,727
  • 6
  • 29
  • 59
  • If you need to access methods not defined by the interface then either your interface is wrong or what you want to do with it is wrong. It's difficult to tell which one is the case here, but if you're sure about your interface, maybe a [Visitor pattern](https://en.wikipedia.org/?title=Visitor_pattern) is what you need. – biziclop Jun 14 '15 at 19:40
  • This is not limitation. It is bad design from you and any design pattern in this scenario would be anti-pattern. You should read this to get basic understanding of interfaces: https://docs.oracle.com/javase/tutorial/java/IandI/createinterface.html and then please continue with this to get understanding of programming to interface concept: http://stackoverflow.com/questions/383947/what-does-it-mean-to-program-to-an-interface – John Jun 14 '15 at 20:38

1 Answers1

3

The whole idea of an interface is that you don't care what type of reportable it is. When you declare it at the interface level, Reportable instead of MilitaryReportable, you only see the methods declared on Reportable. If you don't want to declare it as MilitaryReportable, but you know that's what it is, you can cast it:

((MilitaryReportable)report.reportable).someUniqueMethod()

Jeff Storey
  • 56,312
  • 72
  • 233
  • 406