Interfaces and shared implementation - c#

I have this interface
public interface IColumn
{
bool IsVisible {get;set;}
bool IsGroupBy { get; set; }
Type CLRType { get; set; }
string GetGroupByString();
string GetFilterString();
}
and i have classes which will inherit from it, for the first 3 properties the implementation is exactly the same.
for string GetGroupByString(); the implementation is the same for all classes except 2
so i made an abstract class called ColumnBase which inherits the IColumn interface and implements all of its members and added backing fields because i need to implement INotifyPropertyChanged.
and made my classes inherit from ColumnBase and i did override the implmentations that are not meant to be the same.
I have a very limited experience with Interfaces and Abstract classes, my question is if you had an Interface and some classes that will inherit from it and you realized that the implementation for some but not all properties and functions is the same, do you create an abstract class and put the default implementation and override it inside the classes that have special implementation?

This will get you answers based on opinion and preference.
IMHO, I think this would be best suited to an abstract class with the two methods requiring differing implementations being declared as abstract methods; using abstract on the methods means that the implementations must have an implementation of that method.
public abstract class ColumnBase
{
public bool IsVisible { get; set; }
public bool IsGroupBy { get; set; }
public Type CLRType { get; set; }
public virtual string GetGroupByString()
{
return "base string";
}
public abstract string GetFilterString();
}
public class ConcreteColumn : ColumnBase
{
public override string GetGroupByString()
{
return "concrete string";
}
public override string GetFilterString()
{
return "who owns the filter string?";
}
}

do you create an abstract class and put the default implementation and override it inside the classes that have special implementation?
Yes, I would do it exactly.Actually it's kind a purpose of abstract classes and virtual / override features.In your case I think you don't need IColumn interface,you can use an abstract class.And implement all common methods inside of it, then if you want to change behavior of a method override it in nested class.
If you mark a method with virtual you can override it in nested classes and you can change the behaviour of this method depends on your current class.You might want take a look at the documentation for more details.

If your derived class is some specialized version of the base class then it would be a good idea to inherit it from the a base class, like class Rectangle : Shape. This why the derived classes are all specialized version of a same thing. For example Rectangle and Circle are in fact, inherently a shape. But consider using interfaces when you have different objects and you want some similar behaviors. For instance, you can serialize a Bird object and a Chair object, even if they have only Name and Age properties, it's not a good idea to derive them form a base class which has a Name and Age properties and Serialize() method, because they are different things. Although the implementation of Serialize() method would be the same in both of them, it's better to have an ISerializable interface and implement it in both classes.

Related

Why constants are not allowed in c# interface? [duplicate]

For example, suppose I want an ICar interface and that all implementations will contain the field Year. Does this mean that every implementation has to separately declare Year? Wouldn't it be nicer to simply define this in the interface?
Though many of the other answers are correct at the semantic level, I find it interesting to also approach these sorts of questions from the implementation details level.
An interface can be thought of as a collection of slots, which contain methods. When a class implements an interface, the class is required to tell the runtime how to fill in all the required slots. When you say
interface IFoo { void M(); }
class Foo : IFoo { public void M() { ... } }
the class says "when you create an instance of me, stuff a reference to Foo.M in the slot for IFoo.M.
Then when you do a call:
IFoo ifoo = new Foo();
ifoo.M();
the compiler generates code that says "ask the object what method is in the slot for IFoo.M, and call that method.
If an interface is a collection of slots that contain methods, then some of those slots can also contain the get and set methods of a property, the get and set methods of an indexer, and the add and remove methods of an event. But a field is not a method. There's no "slot" associated with a field that you can then "fill in" with a reference to the field location. And therefore, interfaces can define methods, properties, indexers and events, but not fields.
Interfaces in C# are intended to define the contract that a class will adhere to - not a particular implementation.
In that spirit, C# interfaces do allow properties to be defined - which the caller must supply an implementation for:
interface ICar
{
int Year { get; set; }
}
Implementing classes can use auto-properties to simplify implementation, if there's no special logic associated with the property:
class Automobile : ICar
{
public int Year { get; set; } // automatically implemented
}
Declare it as a property:
interface ICar {
int Year { get; set; }
}
Eric Lippert nailed it, I'll use a different way to say what he said. All of the members of an interface are virtual and they all need to be overridden by a class that inherits the interface. You don't explicitly write the virtual keyword in the interface declaration, nor use the override keyword in the class, they are implied.
The virtual keyword is implemented in .NET with methods and a so-called v-table, an array of method pointers. The override keyword fills the v-table slot with a different method pointer, overwriting the one produced by the base class. Properties, events and indexers are implemented as methods under the hood. But fields are not. Interfaces can therefore not contain fields.
Why not just have a Year property, which is perfectly fine?
Interfaces don't contain fields because fields represent a specific implementation of data representation, and exposing them would break encapsulation. Thus having an interface with a field would effectively be coding to an implementation instead of an interface, which is a curious paradox for an interface to have!
For instance, part of your Year specification might require that it be invalid for ICar implementers to allow assignment to a Year which is later than the current year + 1 or before 1900. There's no way to say that if you had exposed Year fields -- far better to use properties instead to do the work here.
The short answer is yes, every implementing type will have to create its own backing variable. This is because an interface is analogous to a contract. All it can do is specify particular publicly accessible pieces of code that an implementing type must make available; it cannot contain any code itself.
Consider this scenario using what you suggest:
public interface InterfaceOne
{
int myBackingVariable;
int MyProperty { get { return myBackingVariable; } }
}
public interface InterfaceTwo
{
int myBackingVariable;
int MyProperty { get { return myBackingVariable; } }
}
public class MyClass : InterfaceOne, InterfaceTwo { }
We have a couple of problems here:
Because all members of an interface are--by definition--public, our backing variable is now exposed to anyone using the interface
Which myBackingVariable will MyClass use?
The most common approach taken is to declare the interface and a barebones abstract class that implements it. This allows you the flexibility of either inheriting from the abstract class and getting the implementation for free, or explicitly implementing the interface and being allowed to inherit from another class. It works something like this:
public interface IMyInterface
{
int MyProperty { get; set; }
}
public abstract class MyInterfaceBase : IMyInterface
{
int myProperty;
public int MyProperty
{
get { return myProperty; }
set { myProperty = value; }
}
}
Others have given the 'Why', so I'll just add that your interface can define a Control; if you wrap it in a property:
public interface IView {
Control Year { get; }
}
public Form : IView {
public Control Year { get { return uxYear; } } //numeric text box or whatever
}
A lot has been said already, but to make it simple, here's my take.
Interfaces are intended to have method contracts to be implemented by the consumers or classes and not to have fields to store values.
You may argue that then why properties are allowed? So the simple answer is - properties are internally defined as methods only.
Interfaces do not contain any implementation.
Define an interface with a property.
Further you can implement that interface in any class and use this class going forward.
If required you can have this property defined as virtual in the class so that you can modify its behaviour.
Beginning with C# 8.0, an interface may define a default implementation for members, including properties. Defining a default implementation for a property in an interface is rare because interfaces may not define instance data fields.
https://learn.microsoft.com/en-us/dotnet/csharp/programming-guide/classes-and-structs/interface-properties
interface IEmployee
{
string Name
{
get;
set;
}
int Counter
{
get;
}
}
public class Employee : IEmployee
{
public static int numberOfEmployees;
private string _name;
public string Name // read-write instance property
{
get => _name;
set => _name = value;
}
private int _counter;
public int Counter // read-only instance property
{
get => _counter;
}
// constructor
public Employee() => _counter = ++numberOfEmployees;
}
For this you can have a Car base class that implement the year field, and all other implementations can inheritance from it.
An interface defines public instance properties and methods. Fields are typically private, or at the most protected, internal or protected internal (the term "field" is typically not used for anything public).
As stated by other replies you can define a base class and define a protected property which will be accessible by all inheritors.
One oddity is that an interface can in fact be defined as internal but it limits the usefulness of the interface, and it is typically used to define internal functionality that is not used by other external code.

Not sure when to use an abstract property and when not

I'm not really sure what looks better or when do I really use in abstract classes and properties, or when to use non abstract properties. I'll try to make a simple example. Let's say I have this:
abstract class Human
{
public GenderType Gender { get; set; }
public string Name { get; set; }
public Date Born { get; set; }
public bool IsNerd { get; set; }
abstract public void Speak();
abstract public void Sleep();
abstract public void AnoyingPeopleOnStackOverflow();
//... so on
}
class Peter : Human
{
//Peter is special, he got a second name
//But thats all, everything else is the same as like on other humans
public string SecondName { get; set; }
//...override abstract stuff
}
Is this alright? As I understood, I don't have to use an abstract property if I dont want to override it. And in this situation it would be ok, just the methods like Speak, Sleep and so on should be abstract.
Now, if this is ok, when would or should I use an abstract property?
Use an abstract property when you have no default implementation and when derived classes must implement it.
Use a virtual property when you have an implementation in the base class but want to allow overriding.
Use the override keyword to override a member. Mark the member as sealed override if it should not be overridden again.
Don't mark the property as abstract or virtual if you don't want it to be overridden.
Use the new keyword to hide a non-abstract, non-virtual member (this is rarely a good idea).
How to: Define Abstract Properties
I find that abstract properties often occur in a design which implies that they will have type-specific logic and/or side effects. You are basically saying, "here is a data point that all subclasses must have, but I don't know how to implement it". However, properties which contain a large amount of logic and/or cause side effects may not be desirable. This is an important consideration, though there is no fixed right/wrong way to do it.
See:
Should Properties have Side Effects
CA1024: Use properties where appropriate
Personally, I find that I use abstract methods frequently but abstract properties rarely.
I know what I want them to do, I don't care how they do it: Interface.
I know what I want them to do, I don't care how they do some of it, but I've firm ideas on how they'll (or at least most of them) do other bits: Abstract class.
I know what I want them to do, and how most of them will do it: Concrete class with virtual members.
You can have other cases such as e.g. an abstract class with no abstract members (you can't have an instance of one, but what functionality it offers, it offers completely), but they're rarer and normally come about because a particular hierarchy offers itself cleanly and blatantly to a given problem.
(Incidentally, I wouldn't think of a Peter as a type of Human, but of each peter as an instance of human who happens to be called Peter. It's not really fair to pick on example code in this way, but when you're thinking about this sort of issue it's more pertinent than usual).
Abstract members are simply virtual members that you have to override. You use this for something that has to be implemented, but can't be implemented in the base class.
If you want to make a virtual property, and want that it has to be overridden in the class that inherits your class, then you would make it an abstract property.
If you for example have an animal class, its ability to breathe would not be possible to detemine just from the information that it's an animal, but it's something that is pretty crucial:
public abstract class Animal {
public abstract bool CanBreathe { get; }
}
For a fish and a dog the implementation would be different:
public class Dog : Animal {
public override bool CanBreathe { get { return !IsUnderWater; } }
}
public class Fish : Animal {
public override bool CanBreathe { get { return IsUnderWater; } }
}
Use abstract when all sub-classes have to implement the method/property. If there's no need for each and every sub-class to implement it, then don't use it.
As for your example, if SecondName is not required for each person, then there's no need to make an abstract property in the base class. If on the other hand, every person does need a second name, then make it an abstract property.
Example of correct usage of an abstract property:
public class Car
{
public abstract string Manufacturer { get; }
}
public class Odyssey : Car
{
public override string Manufacturer
{
get
{
return "Honda";
}
}
}
public class Camry : Car
{
public override string Manufacturer
{
get
{
return "Toyota";
}
}
}
Making Maker abstract is correct because every car has a manufacturer and needs to be able to tell the user who that maker is.
An abstract property would be used where you want the class to always expose the property, but where you can't pin down the implemetation of that property - leaving it up to/forcing the inheriting class to do so.
There's an example here, where the abstract class is named Shape, and it exposes an abstract Area property. You can't implement the Area property in the base class, as the formula for area will change for each type of shape. All shapes have an area (of some sort), so all shapes should expose the property.
Your implementation itself looks just fine. Was trying to think of a sensible example of an abstract property for a Human, but couldn't think of anything reasonable.

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.

Difference between abstract class and interface [duplicate]

This question already has answers here:
Closed 12 years ago.
Possible Duplicate:
Interface vs Base class
I am not understanding the difference between an abstract class and an interface. When do I need to use which art of type?
Try thinking of it like this:
An abstract class creates an "is-a" relationship. Volkswagon is a Car.
An interface creates a "can-do" relationship. Fred can IDrive.
Moreover, Fred can IDrive, but Fred is a Person.
When we create an interface, we are basically creating a set of methods without any implementation that must be overridden by the implemented classes. The advantage is that it provides a way for a class to be a part of two classes: one from inheritance hierarchy and one from the interface.
When we create an abstract class, we are creating a base class that might have one or more completed methods but at least one or more methods are left uncompleted and declared abstract. If all the methods of an abstract class are uncompleted then it is same as an interface. The purpose of an abstract class is to provide a base class definition for how a set of derived classes will work and then allow the programmers to fill the implementation in the derived classes.
article along with the demo project discussed Interfaces versus Abstract classes.
An abstract class is class probably with some abstract methods and some non-abstract methods. They do stuff (have associated code). If a new non-abstract class, subclasses the abstract class it must implement the abstract methods.
I.E.
public abstract class A {
public string sayHi() { return "hi"; } // a method with code in it
public abstract string sayHello(); // no implementation
}
public class B
: A
{
// must implement, since it is not abstract
public override string sayHello() { return "Hello from B"; }
}
Interface is more like a protocol. A list of methods that a class implementing that interface must have. But they don't do anything. They have just method prototypes.
public interface A
{
string sayHi(); // no implementation (code) allowed
string sayHello(); // no implementation (code) allowed
}
public class B
: A
{
// must implement both methods
string sayHi() { return "hi"; }
string sayHello() { return "hello"; }
}
Both are often confused because there is no protocol/interface in C++. So the way to simulate an interface behavior in that language is writing a pure virtual class (a class with only pure virtual functions).
class A {
virtual int a() = 0; // pure virtual function (no implementation)
}

When should a class member be declared virtual (C#)/Overridable (VB.NET)?

Why wouldn't I choose abstract? What are the limitations to declaring a class member virtual? Can only methods be declared virtual?
An abstract method or property (both can be virtual or abstract) can only be declared in an abstract class and cannot have a body, i.e. you can't implement it in your abstract class.
A virtual method or property must have a body, i.e. you must provide an implementation (even if the body is empty).
If someone want to use your abstract class, he will have to implement a class that inherits from it and explicitly implement the abstract methods and properties but can chose to not override the virtual methods and properties.
Exemple :
using System;
using C=System.Console;
namespace Foo
{
public class Bar
{
public static void Main(string[] args)
{
myImplementationOfTest miot = new myImplementationOfTest();
miot.myVirtualMethod();
miot.myOtherVirtualMethod();
miot.myProperty = 42;
miot.myAbstractMethod();
}
}
public abstract class test
{
public abstract int myProperty
{
get;
set;
}
public abstract void myAbstractMethod();
public virtual void myVirtualMethod()
{
C.WriteLine("foo");
}
public virtual void myOtherVirtualMethod()
{
}
}
public class myImplementationOfTest : test
{
private int _foo;
public override int myProperty
{
get { return _foo; }
set { _foo = value; }
}
public override void myAbstractMethod()
{
C.WriteLine(myProperty);
}
public override void myOtherVirtualMethod()
{
C.WriteLine("bar");
}
}
}
You would use abstract if you do not want to define any implementation in the base class and want to force it to be defined in any derived classes. Define it as a virtual if you want to provide a default implementatio that can be overriden by derived classes.
Yes, only methods can be virtual.
A member should be declared virtual if there is a base implementation, but there is a possibility of that functionality being overridden in a child class. Virtual can also be used instead of abstract to allow a method implementation to be optional (ie. the base implementation is an empty method)
There is no limitation when setting a member as virtual, but virtual members are slower than non-virtual methods.
Both methods and properties can be marked as virtual.
There is a gotcha here to be aware of with Windows Forms.
If you want a Control/UserControl from which you can inherit, even if you have no logic in the base class, you don't want it abstract, because otherwise you won't be able to use the Designer in the derived classes:
http://www.urbanpotato.net/default.aspx/document/2001
If you want to give it an implementation in your base class you make it virtual, if you don't you make it abstract.
Yes, only methods can be declared virtual.
Abstract means that you can't provide a default implementation. This in turn means that all subclasses must provide an implementation of the abstract method in order to be instantiable (concrete).
I'm not sure what you mean by 'limitations', so can't answer that point.
Properties can be declared virtual, but you can conceptually think of them as methods too.
You question is more related to style than technicalities. I think that this book
http://www.amazon.com/Framework-Design-Guidelines-Conventions-Development/dp/0321246756
has great discussion around your question and lots of others.
First of all, I will answer you second question. Only methods can be declared virtual.
You would choose virtual instead of abstract when you want some default functionality in your base class, but you want to leave the option of overriding this functionality by classes that inherit from your base class.
For examples:
If you are implementing the Shape class, you would probably have a method called getArea() that returns the area of your shape. In this case, there's no default behavior for the getArea() method in the Shape class, so you would implement it as abstract. Implementing a method as abstract will prevent you to instantiate a Shape object.
On the other hand, if you implement the class Dog, you may want to implement the method Bark() in this case, you may want to implement a default barking sound and put it in the Dog class, while some inherited classes, like the class Chiwawa may want to override this method and implement a specific barking sound. In this case, the method bark will be implemented as virtual and you will be able to instantiate Dogs as well as Chiwawas.
I personally mark most methods and properties virtual. I use proxies and lazy loading alot, so I don't want to have to worry about changing things at a later date.

Categories

Resources