Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Polymorphism: Deriving from a protected member in a base class?

I'm working on programming a basic media player, and I'm having some trouble writing polymorphic code, which is something I've studied, but never actually implemented before.

There are four relevant classes: MediaInfo, MovieInfo, Media, and Movie.

MediaInfo is an abstract base class that holds information relevant to all media files. MovieInfo inherits from MediaInfo and adds some information that is specific to video files.

Media is an abstract base class that represents all media files. Movie inherits from Media.

Now, Media contains the following line of code:

protected MediaInfo info;

Inside Media, I have Accessors that extract information from MediaInfo. However, inside Movie, I'd like to have Accessors that also extract information from MovieInfo.

So what I did inside Movie was:

protected MovieInfo info;

And inside the constructor:

this.info = new MovieInfo(path);

However, now I have an Accessor:

/// <summary>
/// Gets the frame height of the movie file.
/// </summary>
public string FrameHeight
{
    get
    {
        return this.info.FrameHeight;
    }
}

The problem is, FrameHeight is an accessor only available inside MovieInfo. this.info is treated as a MediaInfo, despite the fact that I declared it as a MovieInfo, and so the code generates an error.

So to sum up my problem into a more generic question: In a derived class, how do I derive from a protected base variable in the base class?

Sorry if this was a bit confusing, I'd be happy to clarify any unclear details.

like image 590
Daniel Avatar asked May 13 '12 19:05

Daniel


2 Answers

You could make the base class generic in the type of MediaInfo it contains:

public abstract class Media<T> where T : MediaInfo
{
    protected T info;
}

Then you can specify that Movie handles MovieInfo types:

public class Movie : Media<MovieInfo>
{
    public string FrameHeight
    {
        get { return this.info.FrameHeight; }
    }
}
like image 65
Lee Avatar answered Oct 02 '22 15:10

Lee


Here's a non-generic alternative:

protected MovieInfo info { get { return (MovieInfo)base.info; } }

Depending on the situation, this may or may not be better than Lee's solution. I personally like his better, just thinking generally.

like image 23
Tim S. Avatar answered Oct 02 '22 17:10

Tim S.