A proper way of defining methods strongly connected to the interface - c#

I have a following interface:
interface IName
{
string Name { get; }
}
And some base class BaseClass. Childs of this class may implement IName interface, but not all of them do.
If a Child implements IName, I would also like to override ToString() method, exactly the same way for all cases, as follows:
public override string ToString()
{
return Name;
}
It seems that a good place for overriding ToString() would be in IName interface, but i believe that it is not possible in C#.
Implementing ToString() in every class seems a bad idea too, because it's a lot of code redundancy (and a waste of time).
What is a proper solution for a case like this?

I'd suggest to make a second base class as such:
public abstract class BaseClass
{
// your base class implementation
}
public abstract class NamedBaseClass : BaseClass, IName
{
public string Name { get; set;}
public override string ToString()
{
return Name;
}
}
this way, if you want a child to implement both BaseClass and IName, then you should inherit from NamedBaseClass.
According to your words that "some might implement IName and some not", then BaseClass should not implement IName, but you should still have some sort of a base implementation. this is my solution.
EDIT:
to make a single class which returns the name and has nothing to do with BaseClass, then you can make an unrelated abstract implementation just for that:
public abstract class NameStringClass : IName
{
public string Name { get; set; }
public override string ToString()
{
return Name;
}
}

Consider cFoo as the child class which has IName. And cBar parent class, and cBaz as a class which doesnt implement IName.
public interface IName
{
string Name { get; }
}
public class CBaz : CBar
{
}
public class CFoo : CBar, IName
{
public CFoo(string name)
{
Name = name;
}
public string Name { get; }
}
abstract public class CBar
{
public override string ToString()
{
if (this is IName)
{
var temp = (IName) (this);
return temp.Name;
}
else
{
return base.ToString();
}
}
}
[Old Answer]
Note that an interface is essentially empty. You need to think of an interface as bearing more of the meaning of contract, implying that the person whom implements this interface as requiring to implement a property/method/field/etc of such signature.
For implementation specific tasks which may be shared commonly by many classes, an abstract class is more suitable.
The moment you need to resolve some kind of logic, you must go through a gateway of implementation, some implementation must occur, interfaces are essentially empty templates. The most loose way of implementing this is via an abstract class which contains both the name property and the ToString override, from which you then inherit from for all your subsequent classes.
At the same time you can consider an abstract class for your CBar class. As well as calling the base method base.ToString().
[End of Old Answer]

Related

an abstract class inherits another abstract class issue

I have an inheritance schema like below:
public abstract class BaseAttachment
{
public abstract string GetName();
}
public abstract class BaseFileAttachment:BaseAttachment
{
public abstract string GetName();
}
public class ExchangeFileAttachment:BaseFileAttachment
{
string name;
public override string GetName()
{
return name;
}
}
I basically want to call GetName() method of the ExchangeFileAttachment class; However, the above declaration is wrong. Any help with this is appreciated. Thanks
The two immediate problems I see is that your final ExchangeFileAttachment class is declared abstract, so you'll never be able to instantiate it. Unless you have another level of inheritance you are not showing us, calling it will not be possible - there's no way to access it. The other problem is that BaseFileAttachment has a property that is hiding the GetName() in BaseAttachment. In the structure you are showing us, it is redundant and can be omitted. So, the 'corrected' code would look more like:
public abstract class BaseAttachment
{
public abstract string GetName();
}
public abstract class BaseFileAttachment : BaseAttachment
{
}
public class ExchangeFileAttachment : BaseFileAttachment
{
string name;
public override string GetName()
{
return name;
}
}
I put corrected in quotes because this use-case still does not make a ton of sense so I'm hoping you can give more information, or this makes a lot more sense on your end.
Just remove the redeclaration from BaseFileAttachment:
public abstract class BaseFileAttachment : BaseAttachment
{
}
BaseFileAttachment already inherits the abstract GetName declaration from BaseAttachment. If you really want to mention it again in BaseFileAttachment, use the override keyword:
public abstract class BaseFileAttachment : BaseAttachment
{
public override abstract string GetName(); // that's fine as well
}

C# interface and abstract class

I have defined an interface, an abstract class that implements that interface and a class that derives from the abstract class. I need the interface because I am using a dynamic loader to implement the plugins and I created an abstract class to implement a few things that all plugins will have.
Now I want to implement a class-wide string as a name. What I created is this:
public interface IDevicePlugin {
string name { get; }
}
abstract public class DevicePlugin : IDevicePlugin {
abstract public string name { get; }
}
public class somePlugin : DevicePlugin, IDevicePlugin {
public override string name {
get {
return "my name";
}
}
}
But this gives me the error "cannot override because 'name' is not a property'. If I remove the override, it says it is hiding the inherited member 'name'.
How do I correctly implement this?
It doesn't error for me, but... I suspect that this is because you are re-implementing the interface. Drop the , IDevicePlugin in somePlugin:
public class somePlugin : DevicePlugin {
public override string name {
get { return "my name"; }
}
}
It inherits the interface from the parent class.

Disable Implementation of an Abstract Method

I have a code below that has an Interface, abstract class and a class. I want to disable the implementation of the abstract method Print() in the FreeCustomer Class. Is this possible? Thank you very much.
public interface ICustomer
{
string CustomerName { get; set; }
double Amount { get; set; }
string Print();
}
public abstract class Customer : ICustomer
{
public string CustomerName { get; set; }
public double Amount { get; set; }
public abstract string Print();
}
public class GoldCustomer : Customer
{
public override string Print() {
return "You are a Gold Customer: " + CustomerName;
}
}
public class FreeCustomer : Customer
{
}
Even if it were possible, it would be a bad idea: Why do you want to implement only part of a contract?
It seems that you are having this issue because the ICustomer interface is trying to do too many different things (and thereby violates the Interface Segregation Principle).
If you don't always need, or want to implement, the Print method, then take it out of the interface, or move it into a separate interface.
The only case when a derived class does not need to implement abstract method of base class is when you declare the derived class as abstract as well.
As MSDN doc says here,
"If a base class declares a member as abstract, that method must be overridden in any non-abstract class that directly inherits from that class. If a derived class is itself abstract, it inherits abstract members without implementing them."
So you may Declare FreeCustomer to be abstract and then need not implement print in there, although I don't see it serving any purpose.
In your particular case, do not declare the function as abstract in the base Customer class - instead use public virtual, and provide an empty implementation in the base class.
Then all you have to do is override it in the classes where you actually need the Print() functionality, in everything else it will do nothing (because the base implementation will be used). This means you can keep it on the interface.

Adding setters to properties in overrides

Why is it allowed to change the visibility and existence of getters or setters in a property when implementing an interface?
interface IFoo
{
string Bar { get; }
}
class RealFoo : IFoo
{
public RealFoo(string bar)
{
this.Bar = bar;
}
public string Bar { get; private set; }
}
class StubFoo : IFoo
{
public string Bar { get; set; }
}
...and not legal to do the same when implementing an abstract class?
abstract class AbstractFoo : IFoo
{
public abstract string Bar { get; }
}
class RealFoo : AbstractFoo
{
public RealFoo(string bar)
{
this.Bar = bar;
}
// Cannot override because 'Bar' does not have an overridable set accessor
public override string Bar { get; private set; }
}
The interface declares what public properties the class must have (It's just a contract). Which means you need to have those properties, but can add to them.
The abstract class declares the actual structure of those properties. So if you don't have the setter in the abstract base, you can't add to it in the implementation.
When you write the override modifier it looks in the base class for something to override.
It perhaps becomes clearer if you think of the getters and setters as the methods that they eventually become.
In the case of the interface you are defining this:
interface IFoo
{
string GetBar();
}
Which can be read as "all classes that implement this interface must include this method."
Both of your classes do:
class RealFoo : IFoo
{
public string GetBar();
private void SetBar(string value);
}
they also implement SetBar(), but that is immaterial; they have fulfilled the contract defined by the interface and are valid.
The abstract class, on the other hand is this:
abstract class AbstractFoo : IFoo
{
public abstract string GetBar();
}
Which means that all child classes must provide a method body for GetBar()
The class you made is this:
class RealFoo : AbstractFoo
{
public override string GetBar();
public override void SetBar(string value);
}
By putting the override modifier in front of the SetBar method the compiler is expecting to find an abstract or virtual version in the base class. You don't have that so the compilation fails.
An abstract class is a class that cannot be instantiated, but must be inherited from. An abstract class may be fully implemented, but is more usually partially implemented or not implemented at all, thereby encapsulating common functionality for inherited classes.
An interface, by contrast, is a totally abstract set of members that can be thought of as defining a contract for conduct. The implementation of an interface is left completely to the developer.
Taken from the MSDN
http://msdn.microsoft.com/en-us/library/scsyfw1d(v=VS.71).aspx
According to the C# specification
An accessor that is used to implement
an interface may not have an
accessor-modifier. If only one
accessor is used to implement an
interface, the other accessor may be
declared with an accessor-modifier:
public interface I
{
string Prop { get; }
}
public class C: I
{
public Prop {
get { return "April"; } // Must not have a modifier here
internal set {...} // Ok, because I.Prop has no set accessor
}
}
That means it is OK to have an access modified on a class implementing the interface. However, the abstract class declares an implementation and you cannot change that with a derived class.

C#: Semi-Abstract Automatic Properties?

In a base class, I want to define an abstract get, but at that point, I don't care about the set. How can I define a setter in my child class?
I tried a few things, but I can't get it to work. For example I tried :
public class BaseClass
{
public abstract bool MyBool { get; }
}
public class ChildClass : BaseClass
{
public override bool MyBool { get; protected set;}
}
And :
public class BaseClass
{
public bool MyBool { abstract get; }
}
public class ChildClass : BaseClass
{
public bool MyBool { override get; protected set;}
}
I know I can workaround this by not using automatic properties in the child class and directly setting the underlying field instead of creating a setter, but I'm looking for something better.
Edit: I don't want to add an abstract setter in the BaseClass.
It may make more sense to use an interface rather than a base class. Then you simply have the classes that need to provide that property implement that interface.
For instance, you can create this interface:
public interface IBoolable {
bool MyBool { get; }
}
Then it is still valid to implement the interface like so:
public class BoolableItem : IBoolable {
public bool MyBool { get; protected set; }
}
Done this way, your code can safely assume anything that implements IBoolable has a property called MyBool that is at minimum read-only.
One solution is to make MyProperty not abstract but delegate its implementation to an abstract protected property that children must override:
public abstract class BaseClass
{
public bool MyBool { get { return MyBoolInternal; } }
protected abstract bool MyBoolInternal { get; set; }
}
public class ChildClass : BaseClass
{
protected override bool MyBoolInternal { get; set; }
}
You have to make up your mind what behavior you want: if it is defined as abstract then a deriving class MUST implement it.
So what you should do is this:
public abstract class BaseClass
{
public abstract string MyProperty { get; set; }
}
public class DerivedClass : BaseClass
{
public override string MyProperty
{
get { return "myValue"; }
set { /* do nothing, not applicable for this class */ }
}
}
Don't throw the NotImplementedException - that is not what you want, you simply want the setter to do nothing for some child classes.
To leave it ambiguous whether you want a setter in inherited classes would violate OOP principles--that is, if a class (abstract or not) has a public/protected setter (abstract or not), then all inheriting classes must also; if a class does not, then inheriting classes must not.
Another way to think about this is to consider properties such that read-only or read-write is part of the contract of the class. Since instances of inheriting classes must adhere to an "Is-a relationship" (the LSP), inheriting classes cannot "add a setter" where the main class didn't have one, because the fact that the main class had a property without as setter is part of the main class definition. In effect, since the main class cannot change the property in question via a setter, therefore all inheriting classes MUST guarantee the same behavior.
Consider using a protected backing field; then you can split this property into a read-only property and a separate setter method. Then, the main class can have the property only and the subclass can have a setter method that the main class doesn't know about. However, I'm not sure this would be a good design either.

Categories

Resources