I'm sure most of us endeaver to keep the tightest scope possible for the members of classes we write. But I have a situation where I just can't seem to be able to keep the scope of members of my inherited class as tight as I would like.
What I am intending to create is a Job object that will inherit from a BaseJob object that will implement the IJob interface. While doing this I want to ensure the JobFactory member of the Job object is kept private and the Id member is public. Both of these members belong in the BaseJob object.
So I'll start with new assembly that will contain three interfaces; IJob, IIdentifyable and IJobFactory.
public interface IJob : IIdentifyable { /// <summary> /// Gets or sets a reference to the factory that created the IJob object. /// </summary> IJobFactory JobFactory { get; set; } }
/// <summary> /// Represents the signature for an object that is identifyable/// </summary> public interface IIdentifyable { /// <summary> /// Gets or sets a reference to the identity of the IJob object. /// </summary> int Id { get; set; } }
/// <summary> /// Represents the signature required for a job factory. /// </summary> public interface IJobFactory { /// <summary> /// Creates an object that implements the IJob interface. /// </summary> /// <returns>Returns an object that implements the IJob interface</returns> IJob Create(); /// <summary> /// Saves the current job /// </summary> void Save(IJob job); }
IJob has a member which will be used to hold a reference to an object (that implements the IJobFactory inteface) that created it. It will also have a Id member implemented through the IIdentifyable interface. IJobFactory has a method for returning a newly created object that implements the IJob interface and a method to save an object that implements the IJob interface. Both interfaces must be public as they need to be seen from outside the assembly. As far as I am aware you canot declare the scope of the methods in an interface so each will be of the same scope as the interface.
I now need to another new assembly which will contain a base class (BaseJob) for my Job object to inherit from. I create a reference to the interfaces assembly, and allow the BaseJob class will implement the IJob interface from it.
/// <summary> /// The base class that all Job objects should inherit from. /// </summary> public abstract class BaseJob : IJob { private int _id; private IJobFactory _jobFactory; #region IIdentifyable Members /// <summary> /// Represents the identity of an Job /// </summary> public int Id { get { return _id ; } set { _id = value; } } #endregion #region IJob Members /// <summary> /// Gets or sets a reference to the factory that created the IJob object. /// </summary> public IJobFactory JobFactory { get { return _jobFactory; } set { _jobFactory = value; } } #endregion }
Now, I would like to set the scope of the BaseJob's Id and Jobfactory members as protected, do they can only be seen by objects that inherit from the BaseJob object. However if I try and make the scope any tighter then VS advises me of an error when I try to build.
Error 1 'BaseJob' does not implement interface member 'IJob.JobFactory'. 'BaseJob.JobFactory' is either static, not public, or has the wrong return type.
So as far as I can see it has to stay public. Any way on to my Job object now. In a third assembly, which has a reference to both the base class assembly and the interfaces assembly, I create the Job class.
public class Job : BaseJob { public Job(int id, IJobFactory jobFactory) : base() { base.Id = id; base.JobFactory = jobFactory; } }
The Job class has a contructor which allows me to pass in the identity and the JobFactory which is used to create it ( I hope to write an post / question on dependency injection next!). My problem is I don't intend the JobFactory property of the Job object to be visiable outside the class code, so ideally I would like to scope it as private. However it is an inherited member that already has a scope of public. I can quite clearly see the member like so...
class TestClass { Job _job; public TestClass() { _job = new Job(); _job.JobFactory = ...; } }
The only way I can see to hide the member is by overriding the JobFactory member to the Job object with the new modifier like so.
private new IJobFactory JobFactory { get { return base.JobFactory; } }
Is this really the best way to go about this, or am I doing something fundementally wrong? Your comments appreciated!
Remember Me
a@href@title, b, blockquote@cite, em, i, strike, strong, sub, sup, u
Disclaimer The opinions expressed herein are my own personal opinions and do not represent my employer's view in any way.