5

I have a class called "Module"

public abstract class Module {

    protected Map<String, Port> ports;

    ...

    public Map<String, Port> getPorts() {
        return ports;
    }
}

and a class called Design that is a subclass of Module

public class Design extends Module{
    ...

    //want to do this but doesn't compile
    @override
    public Map<String, Port> getPorts() {
        return (Map<String, TopPort>) ports;  //TopPort is a subclass of Port
    }
}

Basically what I want to do is only add TopPorts to Design and have the type already cast upon return from the getPorts() function.

What I am doing right now is casting Ports to TopPorts after the getPorts function returns in main, but this is very finneky and someone who is building on my code would not be able to immediately understand when a TopPort is returned.

I also tried creating another function instead of overriding getPorts()

    //want to do this as well but doesn't compile
    public Map<String, TopPort> getTopPorts() {
        return (Map<String, TopPort>) ports;  //TopPort is a subclass of Port
    }

What is the correct way to do this?


More specific problem

I have been playing around with the code and I am able to add this in my "Design" class:

public TopPort getTopPortByName(String porName) {
    return (TopPort) ports.get(porName);
}

public void addPort(TopPort port) {
    this.ports.put(port.getName(), port);
}

However whenever I try to do this casting, it doesn't work:

return (Map<String, TopPort>) this.ports;

Why does the type-cast not work on the whole map even though it works on each of its members?

4
  • Why don't you add another Map of "TopPorts" in "Design"? Commented Dec 12, 2014 at 3:58
  • That's a viable solution, but I want to keep the abstraction and meaning of the "Module" and "Design" classes. Design also contains Ports, but they are a special kind of Ports called TopPorts Commented Dec 12, 2014 at 4:01
  • 1
    To follow up on the idea from @mohsaied, is there an viable conversion from a Port instance into a TopPort instance that never fails? Commented Dec 12, 2014 at 4:02
  • whenever I add a "Port" to an instance of "Design", it is always a "TopPort". So the true type (don't know if that's a real term) of Ports inside Design are always TopPorts. That's why I can cast them after the method returns in main and I do not get a runtime error. I am just at a loss as to how I can do this inside the class to abstract away this type-casting. Commented Dec 12, 2014 at 4:11

1 Answer 1

3

You'd need to make your class generic.

public abstract class Module<P extends Port> {

   protected Map<String, P> ports;

   public Map<String, P> getPorts() {
      return ports;
   }
}


class Design extends Module<TopPort> { }

I'm not sure if this isn't overkill here, though.

Sign up to request clarification or add additional context in comments.

6 Comments

Thanks, I haven't thought of that at all! It is kind-of overkill though. There are many other subclasses of Module, and a lot of code that depends on it. Changing it to a generic might force me to do a lot of refactoring. It's only in the "Design" class do I want to do this.@Thilo
Re: Refactoring: Minimum change would be to change all the extends clauses in your subclasses to include <Port>. That won't break code that uses them.
Oh I see, this might be worth doing then.. Can you review my more specific question though? It seems that the main problem is with the typecast of a Map. Do you know why that doesn't work? @Thilo thanks
That's a different question. And it has been asked before, I'll try to find a link for you.
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.