C# interface and abstract class - c#

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.

Related

A proper way of defining methods strongly connected to the interface

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]

Cannot implement an interface member because it is not public

I wrote some VB code that I converted to C# using Sharp Develop IDE.
I defined an Interface, IElement, that is implemented by objects that return XML representations of themselves. Any object that implements this interface should be able to return its TagName and it's XML string representation. To get the it's XML string, it may have to loop through its child/nested collection to get the XML representation of all of its child objects.
Classes that inherit from Element can use the GetXml and GetNestedXml of its base class or choose to override it but the GetNestedXml function would not need to be public because it would only be called from the public GetXml function of derived classes. Therefore, in the original VB version, the scope of the GetNestedXML was set to protected. However, Sharp Develop and I have issues trying to convert this code to C#. Please see the error below.
On a side note, I do realize that there might be better ways to implement this and I would be interested in side suggestions that are easy on flames. :-) Thanks.
Public Interface IElement
ReadOnly Property TagName() As String
ReadOnly Property GetXml(Optional ByVal targetXml As Integer = TargetXmlEnum.All) As String
Function GetNestedXml() As String
End Interface
Public Class Element
Implements IElement
Public ReadOnly Property TagName() As String Implements IElement.TagName
Get
'....
End Get
End Property
Public Overridable ReadOnly Property GetXml(Optional ByVal targetXml As Integer = TargetXmlEnum.All) _
As String Implements IElement.GetXml
Get
'....
End Get
End Property
Protected Overridable Function GetNestedXml() As String Implements IElement.GetNestedXml
'....
End Function
End Class
Converted C# :
public interface IElement
{
string TagName { get; }
string GetXml { get; }
string GetNestedXml();
}
public class Element : IElement
{
public string TagName {
get { //... }
}
public virtual string GetXml
{
get
{
//...
}
}
protected virtual string GetNestedXml()
{
//...
}
}
error:
Error 1 'Smit.SpreadsheetML.Element' does not implement interface member 'Smit.SpreadsheetML.IElement.GetNestedXml()'. 'Smit.SpreadsheetML.Element.GetNestedXml()' cannot implement an interface member because it is not public. D:\Users\Chad\Desktop\SMIT\SMIT.SpreadsheetML.ConvertedToC#\Element.cs 41 24 Smit.SpreadsheetML.Converted
As Interface implementations need to be public or explicit:
change this method
protected virtual string GetNestedXml()
{
//...
}
to
protected virtual string IElement.GetNestedXml()
{
//...
}
Edit
create an Interface like this:
public interface IElement
{
string TagName { get; }
string GetXml { get; }
}
create an abstract base class like this
abstract class ElementBase:IElement
{
public abstract string TagName { get; }
public abstract string GetXml { get; }
protected abstract string GetNestedXml();
}
Impelement your Element class
public class Element : ElementBase
{
public override string TagName {
get { //... }
}
public override string GetXml
{
get
{
//...
}
}
protected override string GetNestedXml()
{
//...
}
}
An interface declared the responsibilities of its all inheriting instances. So you can not use not-public method to implement your interface method.
If it is non-public for any reason else, I suggest that you can use abstract class and use a abstract/virtual method to declare it.
abstract method like this:
public interface IElement
{
string TagName { get; }
string GetXml { get; }
}
public abstract class ElementBase : IElement
{
public string TagName { get; private set; }
public string GetXml { get; private set; }
protected abstract string GetNestedXml();
}
virtual method:
public interface IElement
{
string TagName { get; }
string GetXml { get; }
}
public abstract class ElementBase : IElement
{
public string TagName { get; private set; }
public string GetXml { get; private set; }
protected virtual string GetNestedXml()
{
throw new NotImplementedException();
}
}
The quick way to solve this is to make GetNestedXml public. If you don't want this, you can also declare GetNestedXml as a protected abstract method in an abstract base class. But this means that all classes need to derive from this base class and implement the method. If you want to provide an implementation in the base class, you can also make the method virtual so that the derived classes can but do not necessarily need to override it. In order to achieve this, perform the following steps:
Create a new abstract base class.
Add a protected abstract/virtual implementation of GetNestedXml(). If it is virtual, also provide a method body (and you do not need to make the class abstract).
Remove the method from the interface.
Derive all classes that implement the interface (and want to have the comfort of the basic implementation GetNestedXml) from the base class.
Another way to hide the method would be to implement IElement explicitly, so that the the callers only see it when they access the object using the interface.
The thing is, that when you declare Element implements IElement you say: "Hey, I know how to get my nested XML, and every one can use it! (public...)".
On your class the GetNestedXml is protected, i.e. you are not fulfilling your declaration.
Even if you do an explicit protected implementation:
protected override string IElement.GetNestedXml()
{
//Implementation...
}
Behind the scenes, It will still actually be public.

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
}

4 Classes with the same properties and methods - is it possible to create only one?

i have another question open here on SO and after thinking about it, i may be approaching this in the wrong way.
i have 4 classes, that have the same properties and methods.
some of the classes, have their own properties and methods ( not overrides of the existing ones ).
currently i create each class as:
public class ClassOne
{
public ClassOne()
{
}
public int ID {get;set;}
// More properties here
public void Set(){
// Do Stuff to save this
}
// More Methods here
}
cant i create one class that will generate all of the 4 classes?
and in the classes themselfs i only create specific properties/methods for that class?
repeating the code seems very odd to me, im sure there must be a way to do this, just dont know how.
Your situation is one of the main reasons why inheritance was invented. So with that, you can write
public class Base
{
// Properties and methods common to all
}
public class ClassOne : Base
{
// Properties and methods specific to ClassOne
}
public class ClassTwo : Base
{
// Properties and methods specific to ClassTwo
}
public class ClassThree : Base
{
// Properties and methods specific to ClassThree
}
public class ClassFour : Base
{
// Properties and methods specific to ClassFour
}
As requested, more code, using interfaces and abstract classes:
An interface is just a blueprint, defining what properties and methods are required to be compatible with other "BaseClasses"
public interface IBaseClass
{
public int ID {get;set;}
public void Set();
}
Abstract classes can contain code, but can not be instantiated, they are form of starting point for a class, but not a complete class themselves.
public abstract class ABaseClass : IBaseClass
{
public int ID {get;set;}
public void Set(){
// Do Stuff to save
}
}
Each class inherits from the abstract class and can then override and implement whatever it wants, customizing it however is necessary.
public class ClassOne : ABaseClass
{
}
public class ClassTwo : ABaseClass
{
}
public class ClassThree : ABaseClass
{
}
public class ClassFour : ABaseClass
{
}
ps. not entirely sure if my syntax is 100% correct
Could you simply make a base class with your properties and inherit from that class?
Why not use inheritance??
public class ClassOne
{
public ClassOne()
{
}
public virtual int ID {get;set;}
// More properties here
public virtual void Set(){
// Do Stuff to save this
}
// More Methods here }
public class ClassTwo : ClassOne
{
public string ClassTwoString { get; set; }
}
public class ClassThree : ClassOne
{
public string ClassThreeString { get; set; }
}
Can you make them all inherit off of the same class? If so, that sounds ideal.
Barring the possibility of making them inherit, you could write an interface that describes the methods and properties which each of them use. Then you can call each instance of the class through the same interface.
Barring again that possibility, you could write a reflective assignor/accessor. But you shouldn't do that.

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.

Categories

Resources