So i was browsing some code and i came across:
public class Person
{
private string message;
public override string ToString()
{
return message;
}
public static Person CreateEmployee()
{
return new Employee();
}
class Employee : Person
{
public Employee()
{
this.message = "I inherit private members!";
}
}
}
Can someone please explain how the private variable "message" is being used/accessed even though its private??
Private members are accessible to all code within the class, including nested classes.
If you move the Employee class outside the Person class, it will fail until you make the field protected.
The simple fact is, this works because compilers allow it to - the designers thought it was a good thing. Once code is compiled, private/public variables are stored in memory in exactly the same way. (The CLR is simply aware of different metadata attributes for them.)
The justification is: nested classes and their members are still considered to lie conceptually/hierarchically within the parent class. Hence, private members of the parent class are always accessible by these semantics. Besides, it just makes life easy for programmers in many cases without breaking the object-oriented encapsulation rule!
In fact, if you want to think about this in terms of code, any code that falls within the open and close braces of a given class can access its private members, regardless of whether it immediately lies within a nested class/struct/etc.
Because Employee is an inner class of Person.
See this question: can-inner-classes-access-private-variables
Person={private message, private Employee}
Private Employee and private message are siblings, Employee can use the message. If you allocate Private Message into another class and mark it as protected/private outside the Person class, then Employee will not be able to see or use it anymore even with an instance of that class.
Related
I have a question regarding simple inheritance in C#.
Here is the code:
class Mammal
{
int age { get; set; }
public Mammal(int age)
{
this.age = age;
}
}
class Dog : Mammal
{
string breed { get; set; }
public Dog(int age, string breed)
: base(age)
{
this.breed = breed;
}
}
class Program
{
static void Main(string[] args)
{
Dog joe = new Dog(8, "Labrador");
Console.WriteLine("Joe is {0} years old dog of breed {1}", joe.age, joe.breed); // gives error
}
}
This gives error since it cannot access the age and breed parameters. So I make age and breed public in Mammal and Dog class respectively. This makes the program to run fine.
But my question is shouldn't ideally the parameters be made private or non-public and only accessed through public methods? If that's the case, then how can I access the non-public parameters in Program class?
Thanks
Automatic properties are essentially methods (they are compiled to get_ and set_ methods). By marking them public, they will be as you have described, which is fine.
You only need hide the information that an outsider shouldn't have access to. Your use case shows that an outside caller must have access to these properties, so marking them public is fine.
If you don't want an outside caller to set the value, then you can mark that particular accessor as private or protected.. whilst leaving the get accessor public:
public int Age { get; private set; }
Also, uppercase the first letter in properties.
In your code, age and breed are properties. You can control access to the get and set methods separately by writing public get; private set;. That would achieve what you want!
Additionally, consider whether it makes sense in your program to change the age and the breed of an object after it's constructed. If not, you can make them public readonly fields.
Having not provided an access modifier it uses it's default access. However, you're correct in most cases with your logic. You should hide as much as possible. So in reality I, depending on the situation, might provide public getters and private setters - or not. The point to get would be that you're free to do what you like as long as it delivers the correct results.
What you have here, in C#, is the creation of a variable that will always only be accessed via its getters and setters (implicitly of course) because that really is the best, although not so often implemented, practice.
So here:
[access] [type] [name] { [access]get; [access]set; }
we're able to control the access to the parameter but the parameter itself is seen. You could also, obviously because you've done it, make certain fields private that need not be seen, which is the not so implemented way. Often, variables take on some form of validation, no matter the access, so having private parameters like above is advantageous for you to use because the verification can be housed in the setters and allows for simpler syntax with MyClass.Something = somethingElse; or System.Console.Write(MyClass.Something);.
The answer to how can I access the non-public parameters in Program class is that you it can't (without doing reflection), because you can control what member variables, properties and methods are exposed to your derived classes and instantiated classes.
Data encapsulation is a good thing and you should use it to reduce the risk of calling code being able to modify data in your class that they should not have access to.
private will never be available outside the class, you need to make it public when you want to be accessible by all or protected when you want your property/variable/method to be accessible only in inheriting classes.
If we inherit a class do the private variables also get inherited?
I know that "Yes, the variables are inherited but cannot be accessed directly by the class interface."
What I want to know is how can we access the private variables/methods from the child class
What I am trying to say is that private members are also inherited.But how to access the same without making them protected.
I know that "Yes, the variables are inherited but cannot be accessed directly by the class interface."
So you know the answer then.
What I want to know is how can we access the private variables/methods from the child class
You can’t, that’s why they are private (rather than, say, protected). The whole intention of making them private is so that you cannot access them from anywhere, notably including child classes.
Explicitly breaking this encapsulation is almost always a sign of a broken design and shouldn’t ever be part of a normal code flow. However, there are situations in which you want to reason about some code, and in these situations it may be necessary to examine even private values. Reflection libraries allow this. Here’s a simple example using the System.Reflection capabilities:
class Widget {
private readonly string identifier;
public Widget(string identifier) {
this.identifier = identifier;
}
}
class MainClass {
public static void Main(string[] args) {
var widget = new Widget("my_test_widget");
var type = widget.GetType();
var field = type.GetField("identifier",
System.Reflection.BindingFlags.Instance |
System.Reflection.BindingFlags.NonPublic);
Console.WriteLine($"{field} = {field.GetValue(widget)}");
}
}
Make them protected. For variables, make a protected property that the child classes then use.
You can only access private variables/methods from a derived class using reflection. You cannot access them in a "natural" way, since the whole point of making them private is to hide them from other classes (including derived classes).
Make it protected property instead of private member.
What I want to know is how can we access the private variables/methods from the child class
.........
But how to access the same without making them protected.
You might want to try using reflection:
Here is a similar question / answer that explains how this can be done.
I have a class that upon construction, loads it's info from a database. The info is all modifiable, and then the developer can call Save() on it to make it Save that information back to the database.
I am also creating a class that will load from the database, but won't allow any updates to it. (a read only version.) My question is, should I make a separate class and inherit, or should I just update the existing object to take a readonly parameter in the constructor, or should I make a separate class entirely?
The existing class is already used in many places in the code.
Thanks.
Update:
Firstly, there's a lot of great answers here. It would be hard to accept just one. Thanks everyone.
The main problems it seems are:
Meeting expectations based on class names and inheritance structures.
Preventing unnecessary duplicate code
There seems to be a big difference between Readable and ReadOnly. A Readonly class should probably not be inherited. But a Readable class suggests that it might also gain writeability at some point.
So after much thought, here's what I'm thinking:
public class PersonTestClass
{
public static void Test()
{
ModifiablePerson mp = new ModifiablePerson();
mp.SetName("value");
ReadOnlyPerson rop = new ReadOnlyPerson();
rop.GetName();
//ReadOnlyPerson ropFmp = (ReadOnlyPerson)mp; // not allowed.
ReadOnlyPerson ropFmp = (ReadOnlyPerson)(ReadablePerson)mp;
// above is allowed at compile time (bad), not at runtime (good).
ReadablePerson rp = mp;
}
}
public class ReadablePerson
{
protected string name;
public string GetName()
{
return name;
}
}
public sealed class ReadOnlyPerson : ReadablePerson
{
}
public class ModifiablePerson : ReadablePerson
{
public void SetName(string value)
{
name = value;
}
}
Unfortunately, I don't yet know how to do this with properties (see StriplingWarrior's answer for this done with properties), but I have a feeling it will involve the protected keyword and asymmetric property access modifiers.
Also, fortunately for me, the data that is loaded from the database does not have to be turned into reference objects, rather they are simple types. This means I don't really have to worry about people modifying the members of the ReadOnlyPerson object.
Update 2:
Note, as StriplingWarrior has suggested, downcasting can lead to problems, but this is generally true as casting a Monkey to and Animal back down to a Dog can be bad. However, it seems that even though the casting is allowed at compile time, it is not actually allowed at runtime.
A wrapper class may also do the trick, but I like this better because it avoids the problem of having to deep copy the passed in object / allow the passed in object to be modified thus modifying the wrapper class.
The Liskov Substitution Principle says that you shouldn't make your read-only class inherit from your read-write class, because consuming classes would have to be aware that they can't call the Save method on it without getting an exception.
Making the writable class extend the readable class would make more sense to me, as long as there is nothing on the readable class that indicates its object can never be persisted. For example, I wouldn't call the base class a ReadOnly[Whatever], because if you have a method that takes a ReadOnlyPerson as an argument, that method would be justified in assuming that it would be impossible for anything they do to that object to have any impact on the database, which is not necessarily true if the actual instance is a WriteablePerson.
Update
I was originally assuming that in your read-only class you only wanted to prevent people calling the Save method. Based on what I'm seeing in your answer-response to your question (which should actually be an update on your question, by the way), here's a pattern you might want to follow:
public abstract class ReadablePerson
{
public ReadablePerson(string name)
{
Name = name;
}
public string Name { get; protected set; }
}
public sealed class ReadOnlyPerson : ReadablePerson
{
public ReadOnlyPerson(string name) : base(name)
{
}
}
public sealed class ModifiablePerson : ReadablePerson
{
public ModifiablePerson(string name) : base(name)
{
}
public new string Name {
get {return base.Name;}
set {base.Name = value; }
}
}
This ensures that a truly ReadOnlyPerson cannot simply be cast as a ModifiablePerson and modified. If you're willing to trust that developers won't try to down-cast arguments in this way, though, I prefer the interface-based approach in Steve and Olivier's answers.
Another option would be to make your ReadOnlyPerson just be a wrapper class for a Person object. This would necessitate more boilerplate code, but it comes in handy when you can't change the base class.
One last point, since you enjoyed learning about the Liskov Substitution Principle: By having the Person class be responsible for loading itself out of the database, you are breaking the Single-Responsibility Principle. Ideally, your Person class would have properties to represent the data that comprises a "Person," and there would be a different class (maybe a PersonRepository) that's responsible for producing a Person from the database or saving a Person to the database.
Update 2
Responding to your comments:
While you can technically answer your own question, StackOverflow is largely about getting answers from other people. That's why it won't let you accept your own answer until a certain grace period has passed. You are encouraged to refine your question and respond to comments and answers until someone has come up with an adequate solution to your initial question.
I made the ReadablePerson class abstract because it seemed like you'd only ever want to create a person that is read-only or one that is writeable. Even though both of the child classes could be considered to be a ReadablePerson, what would be the point of creating a new ReadablePerson() when you could just as easily create a new ReadOnlyPerson()? Making the class abstract requires the user to choose one of the two child classes when instantiating them.
A PersonRepository would sort of be like a factory, but the word "repository" indicates that you're actually pulling the person's information from some data source, rather than creating the person out of thin air.
In my mind, the Person class would just be a POCO, with no logic in it: just properties. The repository would be responsible for building the Person object. Rather than saying:
// This is what I think you had in mind originally
var p = new Person(personId);
... and allowing the Person object to go to the database to populate its various properties, you would say:
// This is a better separation of concerns
var p = _personRepository.GetById(personId);
The PersonRepository would then get the appropriate information out of the database and construct the Person with that data.
If you wanted to call a method that has no reason to change the person, you could protect that person from changes by converting it to a Readonly wrapper (following the pattern that the .NET libraries follow with the ReadonlyCollection<T> class). On the other hand, methods that require a writeable object could be given the Person directly:
var person = _personRepository.GetById(personId);
// Prevent GetVoteCount from changing any of the person's information
int currentVoteCount = GetVoteCount(person.AsReadOnly());
// This is allowed to modify the person. If it does, save the changes.
if(UpdatePersonDataFromLdap(person))
{
_personRepository.Save(person);
}
The benefit of using interfaces is that you're not forcing a specific class hierarchy. This will give you better flexibility in the future. For example, let's say that for the moment you write your methods like this:
GetVoteCount(ReadablePerson p);
UpdatePersonDataFromLdap(ReadWritePerson p);
... but then in two years you decide to change to the wrapper implementation. Suddenly ReadOnlyPerson is no longer a ReadablePerson, because it's a wrapper class instead of an extension of a base class. Do you change ReadablePerson to ReadOnlyPerson in all your method signatures?
Or say you decide to simplify things and just consolidate all your classes into a single Person class: now you have to change all your methods to just take Person objects. On the other hand, if you had programmed to interfaces:
GetVoteCount(IReadablePerson p);
UpdatePersonDataFromLdap(IReadWritePerson p);
... then these methods don't care what your object hierarchy looks like, as long as the objects you give them implement the interfaces they ask for. You can change your implementation hierarchy at any time without having to change these methods at all.
Definitely do not make the read-only class inherit from the writable class. Derived classes should extend and modify the capabilities of the base class; they should never take capabilities away.
You may be able to make the writable class inherit from the read-only class, but you need to do it carefully. The key question to ask is, would any consumers of the read-only class rely on the fact that it is read-only? If a consumer is counting on the values never changing, but the writable derived type is passed in and then the values are changed, that consumer could be broken.
I know it is tempting to think that because the structure of the two types (i.e. the data that they contain) is similar or identical, that one should inherit from the other. But that is often not the case. If they are being designed for significantly different use cases, they probably need to be separate classes.
A quick option might be to create an IReadablePerson (etc) interface, which contains only get properties, and does not include Save(). Then you can have your existing class implement that interface, and where you need Read-only access, have the consuming code reference the class through that interface.
In keeping with the pattern, you probably want to have a IReadWritePerson interface, as well, which would contain the setters and Save().
Edit On further thought, IWriteablePerson should probably be IReadWritePerson, since it wouldn't make much sense to have a write-only class.
Example:
public interface IReadablePerson
{
string Name { get; }
}
public interface IReadWritePerson : IReadablePerson
{
new string Name { get; set; }
void Save();
}
public class Person : IReadWritePerson
{
public string Name { get; set; }
public void Save() {}
}
The question is, "how do you want to turn a modifiable class into a read-only class by inheriting from it?"
With inheritance you can extend a class but not restrict it. Doing so by throwing exceptions would violate the Liskov Substitution Principle (LSP).
The other way round, namely deriving a modifiable class from a read-only class would be OK from this point of view; however, how do you want to turn a read-only property into a read-write property? And, moreover, is it desirable to be able to substitute a modifiable object where a read-only object is expected?
However, you can do this with interfaces
interface IReadOnly
{
int MyProperty { get; }
}
interface IModifiable : IReadOnly
{
new int MyProperty { set; }
void Save();
}
This class is assignment compatible to the IReadOnly interface as well. In read-only contexts you can access it through the IReadOnly interface.
class ModifiableClass : IModifiable
{
public int MyProperty { get; set; }
public void Save()
{
...
}
}
UPDATE
I did some further investigations on the subject.
However, there is a caveat to this, I had to add a new keyword in IModifiable and you can only access the getter either directly through the ModifiableClass or through the IReadOnly interface, but not through the IModifiable interface.
I also tried to work with two interfaces IReadOnly and IWriteOnly having only a getter or a setter respectively. You can then declare an interface inheriting from both of them and no new keyword is required in front of the property (as in IModifiable). However when you try to access the property of such an object you get the compiler error Ambiguity between 'IReadOnly.MyProperty' and 'IWriteOnly.MyProperty'.
Obviously, it is not possible to synthesize a property from separate getters and setters, as I expected.
I had the same problem to solve when creating an object for user security permissions, that in certain cases must be mutable to allow high-level users to modify security settings, but normally is read-only to store the currently logged-in user's permissions information without allowing code to modify those permissions on the fly.
The pattern I came up with was to define an interface which the mutable object implements, that has read-only property getters. The mutable implementation of that interface can then be private, allowing code that directly deals with instantiating and hydrating the object to do so, but once the object is returned out of that code (as an instance of the interface) the setters are no longer accessible.
Example:
//this is what "ordinary" code uses for read-only access to user info.
public interface IUser
{
string UserName {get;}
IEnumerable<string> PermissionStrongNames {get;}
...
}
//This class is used for editing user information.
//It does not implement the interface, and so while editable it cannot be
//easily used to "fake" an IUser for authorization
public sealed class EditableUser
{
public string UserName{get;set;}
List<SecurityGroup> Groups {get;set;}
...
}
...
//this class is nested within the class responsible for login authentication,
//which returns instances as IUsers once successfully authenticated
private sealed class AuthUser:IUser
{
private readonly EditableUser user;
public AuthUser(EditableUser mutableUser) { user = mutableUser; }
public string UserName {get{return user.UserName;}}
public IEnumerable<string> PermissionNames
{
//GetPermissions is an extension method that traverses the list of nestable Groups.
get {return user.Groups.GetPermissions().Select(p=>p.StrongName);
}
...
}
A pattern like this allows you to use code you've already created in a read-write fashion, while not allowing Joe Programmer to turn a read-only instance into a mutable one. There are a few more tricks in my actual implementation, mainly dealing with persistence of the editable object (since editing user records is a secured action, an EditableUser cannot be saved with the Repository's "normal" persistence method; it instead requires calling an overload that also takes an IUser which must have sufficient permissions).
One thing you simply must understand; if it is possible for your program to edit the records in any scope, it is possible for that ability to be abused, whether intentionally or otherwise. Regular code reviews of any usage of the mutable or immutable forms of your object will be necessary to make sure other coders aren't doing anything "clever". This pattern also isn't enough to ensure that an application used by the general public is secure; if you can write an IUser implementation, so can an attacker, so you'll need some additional way to verify that your code and not an attacker's produced a particular IUser instance, and that the instance hasn't been tampered with in the interim.
We have a Student class in our business model. something struck me as strange, if we are manipulating one student from another student, the students private members are visible, why is this?
class Program {
static void Main(string[] args) {
Student s1 = new Student();
Student s2 = new Student();
s1.SeePrivatePropertiesAndFields(s2);
}
}
public class Student {
private String _studentsPrivateField;
public Student() {
_studentsPrivateField = DateTime.Now.Ticks.ToString();
}
public void SeePrivatePropertiesAndFields(Student anotherStudent) {
//this seems like these should be private, even from the same class as it is a different instantiation
Console.WriteLine(anotherStudent._studentsPrivateField);
}
}
Can i have some thoughts on the design considerations/implications of this. It seems that you can't hide information from your siblings. Is there a way to mark a field or member as hidden from other instances of the same class?
There's an easy way to ensure this:
Don't mess around with private members of other instances of the same class.
Seriously - you're the one writing the Student code.
The easiest way to ensure this is to program to an interface, such as:
class Program
{
static void Main(string[] args)
{
IStudent s1 = new Student();
IStudent s2 = new Student();
s1.ExamineStudentsMembers(s1);
}
}
public interface IStudent
{
void ExamineStudentsMembers(IStudent anotherStudent);
}
public class Student : IStudent
{
private string _studentsPrivateMember;
public Student()
{
_studentsPrivateMember = DateTime.Now.Ticks.ToString();
}
public void ExamineStudentsMembers(IStudent anotherStudent)
{
Console.WriteLine(anotherStudent._studentsPrivateMember);
}
}
This will no longer compile due to ExamineStudentsMembers trying to access a private field.
If you are writing the class, you have complete control over it, so if you don't want one object to be able to modify another, don't write in that functionality.
Classes will often use private variables in other instances to implement efficient comparison and copy functions.
Private just means that the member (field/method/etc.) can be accessed only from the within the code of the parent type. From CSharpOnline
Private members of multiple instances are visible and can be invoked. This comes in handy when you are implementing a "copy constructor" or a "clone" method on your type, where the argument is an instance of the same type. If the designers would have made private fields inaccessible, then you may have to create a bunch of getter methods just for clone/copy to get at them. IMHO, I like it better the way it is. Within the same type, Reading another object's state isn't that bad as writing to it though (which could be a DONT-code-convention for you/your team.)
Accessing a sibling's private data may seem wrong when phrased like:
public void ExamineStudentsMembers(Student anotherStudent) {
//this seems very wrong
Console.WriteLine(anotherStudent._studentsPrivateMember);
}
However, it doesn't seem so odd for methods which require this sort of functionality. What methods require accessing a sibling's private data? Comparison methods (in particular equals) and objects in a data structure (say a tree or linked list).
Comparison methods often compare private data directly rather than just the public data.
For a class of nodes that make up a linked list, graph or tree, being able to access a sibling's private data is exactly what is needed. Code in the know (part of the class) can tinker around with the data structure, but code outside of the data structure cannot touch the internals.
It is interesting to note that these two cases are less common in day-to-day programming than when this language feature were first developed. Back in 1990s and early 2000s, in C++ it would have been much more common to build custom data structures and comparison methods. Perhaps it is a good time to reconsider private members.
i like the second point, you can look, but dont touch those private members.
it's funny you should say that, i knew a teacher once and he said he often had a problem deciding what classes it was ok to look at the members and which ones he could actually have a play with.
An object is just a piece of data; the class contains the functionality. A member method is just a nice trick the compiler plays; it's really more like a static method with an implied argument (sort of like extension methods). With that in mind, protecting objects from each other doesn't make any sense; you can only protect classes from each other. So it's natural that it works that way.
No, this is necessary, the method code is not specific to the instance, it is only specific to the type of the object. (virtual methods) or the declared type of the variable (for non-virtual methods). The non-static fields, on the other hand, are instance specific... That's where you have instance-level isolation.
The only difference between a static method and a non-static method is that the static method is not allowed to access other instance based (non-static) methods or fields. Any method that CAN be made static without modification will not be affected in any way by making it static, except to force compiler to throw errors anywhere it was called using instance-based syntax.
If you intend to examine a given student's information then I would change the method to be static:
public static void ExamineStudentsMembers(Student student)
{
Console.WriteLine(student._studentsPrivateMember);
}
You would then use Student.ExamineStudentsMembers(s1). Using s1.ExamineStudentsMembers(s2) would be invalid.
If this isn't the intended purpose I would rewrite the method as:
public void ExamineStudentsMembers()
{
Console.WriteLine(_studentsPrivateMember);
}
The above would then be used by writing s1.ExamineStudentsMembers()
Private members are to hide implementation details from clients. The clients should only see the interface (public methods / fields / properties).
The purpose is not to protect the programmer from himself.
This is also NOT a security feature because you can always access private fields via reflection.
It's really to separate interface & implementation (black box design), and clients programming against a contract (all public fields).
For example if you have a public get property, it could access some private field directly, or it could calculate the value from some other fields.
The purpose is, the client only knows the contract (the public property) and the implementation can be changed without affecting the client
Object scope does not ever imply security - ever! It is role of the OS to provide runtime security. It is a bug to design a system that relies on language specific object scope to limit runtime object instance data access. If this were not the case, then all non OO languages are, by definition, not secure.
I hit this problem all the time. Suppose I am making a command line interface (Java or C#, the problem is the same I think, I will show C# here).
I define an interface ICommand
I create an abstract base class CommandBase which implements ICommand, to contain common code.
I create several implementation classes, each extending the base class (and by extension the interface).
Now - suppose that the interface specifies that all commands implement the Name property and the Execute method...
For Name each of my instance classes must return a string that is the name of that command. That string ("HELP", "PRINT" etc) is static to the class concerned. What I would love to be able to do is define:
public abstract static const string Name;
However (sadly) you cannot define static members in an interface.
I have struggled with this issue for years now (pretty much any place I have a family of similar classes) and so will post my own 3 possible solutions below for your votes. However since none of them is ideal I am hoping someone will post a more elegant solution.
UPDATE:
I can't get the code formatting to work properly (Safari/Mac?). Apologies.
The example I am using is trivial. In real life there are sometimes dozens of implementing classes and several fields of this semi-static type (ie static to the implementing class).
I forgot to mention - ideally I want to be able to query this information statically:
string name = CommandHelp.Name;
2 of my 3 proposed solutions require that the class be instantiated before you can find out this static information which is ugly.
You may consider to use attributes instead of fields.
[Command("HELP")]
class HelpCommand : ICommand
{
}
As you mentioned, there is no way to enforce this from the interface level. Since you are using an abstract class, however, what you can do is declare the property as abstract in the base class which will force the inheriting class it override it. In C#, that would look like this:
public abstract class MyBaseClass
{
public abstract string Name { get; protected set; }
}
public class MyClass : MyBaseClass
{
public override string Name
{
get { return "CommandName"; }
protected set { }
}
}
(Note that the protected set prevents outside code changing the name.)
This may not be exactly what you're looking for, but it's as close as I think you can get. By definition, static fields do not vary; you simply can't have a member that is both static and overridable for a given class.
public interface ICommand {
String getName();
}
public class RealCommand implements ICommand {
public String getName() {
return "name";
}
}
Simple as that. Why bother having a static field?
Obs.: Do not use a field in an abstract class that should be initiated in a subclass (like David B suggestion). What if someone extends the abstract class and forget to initiate the field?
just add the name property to the base class and pass it ito the base class's constructor and have the constuctor from the derived class pass in it's command name
What I usually do (in pseudo):
abstract class:
private const string nameConstant = "ABSTRACT";
public string Name
{
get {return this.GetName();}
}
protected virtual string GetName()
{
return MyAbstractClass.nameConstant;
}
----
class ChildClass : MyAbstractClass
{
private const string nameConstant = "ChildClass";
protected override string GetName()
{
return ChildClass.nameConstant;
}
}
Of course, if this is a library that other developers will use, it wouldn't hurt if you add some reflection in the property to verify that the current instance in fact does implement the override or throw an exception "Not Implemented".
My answer will relate to Java, as that is what I know. Interfaces describe behavior, and not implementation. Additionally, static fields are tied to the classes, and not instances. If you declared the following:
interface A { abstract static NAME }
class B { NAME = "HELP" }
class C { NAME = "PRINT" }
Then how could this code know which NAME to link to:
void test(A a) {
a.NAME;
}
How I would suggest to implement this, is one of the following ways:
Class name convention, and the base class derives the name from the class name. If you wish to deviate from this, override the interface directly.
The base class has a constructor which takes name
Use annotations and enforce their presence through the base class.
However, a much better solution is proabably to use enums:
public enum Command {
HELP { execute() }, PRINT { execute() };
abstract void execute();
}
This is much cleaner, and allows you to use switch statements, and the NAME will be easily derived. You are however not able to extended the number of options runtime, but from your scenario description that might not be even needed.
[Suggested answer # 3 of 3]
I have not tried this yet and it would not be so nice in Java (I think?) but I could just tag my classes with Attributes:
[CammandAttribute(Name="HELP")]
Then I can use reflection to get that static information. Would need some simple helper methods to make the information easily available to the clients of the class but this could go in the base class.
From a design perspective, I think it is wrong to require a static implementation member... The relative deference between performance and memory usage between static and not for the example string is minimal. That aside, I understand that in implementation the object in question could have a significantly larger foot print...
The essential problem is that by trying to setup a model to support static implementation members that are avaialble at a base or interface level with C# is that our options are limited... Only properties and methods are available at the interface level.
The next design challenge is whether the code will be base or implementation specific. With implementation your model will get some valdiation at compile time at the code of having to include similar logic in all implementations. With base your valdiation will occur at run time but logic would be centralized in one place. Unfortunately, the given example is the perfect show case for implemntation specific code as there is no logic associated with the data.
So for sake of the example, lets assume there is some actual logic associated with the data and that it is extensive nad/or complex enough to provide a showcase for base classing. Setting aside whether the base class logic uses any impelementation details or not, we have the problem of insuring implemtation static initialization. I would recommend using an protected abstract in the base class to force all implementations to created the needed static data that would be valdated at compile time. All IDE's I work with make this very quick any easy. For Visual Studio it only takes a few mouse clicks and then just changing the return value essentially.
Circling back to the very specific nature of the question and ignoring many of the other design problems... If you really must keep this entire to the nature of static data and still enforce it thru the nature confines of the problem... Definately go with a method over properties, as there are way to many side effects to make go use of properties. Use a static member on the base class and use a static constructor on the implementations to set the name. Now keep in mind that you have to valdiate the name at run-time and not compile time. Basically the GetName method on the base class needs to handle what happens when an implementation does not set it's name. It could throw an exception making it brutally apparent that something is worng with an implementation that was hopefulyl cause by testing/QA and not a user. Or you could use reflection to get the implementation name and try to generate a name... The problem with reflection is that it could effect sub classes and set up a code situation that would be difficult for a junior level developer to understand and maintain...
For that matter you could always generate the name from the class name thru reflection... Though in the long term this could be a nightmare to maintain... It would however reduce the amount of code needed on the implementations, which seems more important than any other concerns. Your could also use attributes here as well, but then you are adding code into the implementations that is equivalent in time/effort as a static constructor and still have the problem off what todo when the implementation does not include that information.
What about something like this:
abstract class Command {
abstract CommandInfo getInfo();
}
class CommandInfo {
string Name;
string Description;
Foo Bar;
}
class RunCommand {
static CommandInfo Info = new CommandInfo() { Name = "Run", Foo = new Foo(42) };
override commandInfo getInfo() { return Info; }
}
Now you can access the information statically:
RunCommand.Info.Name;
And from you base class:
getInfo().Name;
[Suggested solution #1 of 3]
Define an abstract property Name in the interface to force all implementing classes to implement the name property.
(in c#) Add this property as abstract in the base class.
In the implementations implement like this:
public string Name
{
get {return COMMAND_NAME;}
}
Where name is a constant defined in that class.
Advantages:
Name itself defined as a constant.
Interface mandates the property be created.
Disadvantages:
Duplication (which I hate). The exact same property accessor code pasted into every one of my implementations. Why cant that go in the base class to avoid the clutter?
[Suggested solution #2 of 3]
Make a private member variable name.
Define an abstract property Name in the interface.
Implement the property in the base class like this:
public string Name
{
get {return Name;}
}
Force all implementations to pass name as a constructor argument when calling the abstract base class constructor:
public abstract class CommandBase(string commandName) : ICommand
{
name = commandName;
}
Now all my implementations set the name in the constructor:
public class CommandHelp : CommandBase(COMMAND_NAME) {}
Advantages:
My accessor code is centralised in the base class.
The name is defined as a constant
Disadvantages
Name is now an instance variable -
every instance of my Command classes
makes a new reference rather than
sharing a static variable.