Choosing Between Classes and Interfaces [duplicate] - c#

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Interface vs Abstract Class (general OO)
In one of the MSDN article following line is mentioned
Interfaces cannot specify new members in later versions while
abstract classes can add members as needed to support additional
functionality.
I picked this sentence from here. You can read the same sentence in paragraph 3.
I have a confusion, sorry in advance for in case I am missing something.
Once the Abstaract Class or Interface is declared and then any Derived class is inheriting the methods, in either case, all the methods should be overridden. Otherwise compilation error will come.
Your comments?

Once the Abstaract Class or Interface is declared and then any Derived class is inheriting the methods, in either case, all the methods should be overridden. Otherwise compilation error will come.
No, for an abstract class only the abstract methods need to be overridden. You can add non-abstract methods with no errors.
For example, version 1:
public abstract class FooBase
{
public abstract void Bar();
}
public class FooImpl : FooBase
{
public override void Bar() {}
}
Now introduce a new non-abstract method in FooBase for version 2:
public abstract class FooBase
{
public abstract void Bar();
public void NewMethod() {}
}
... and there's no problem.
Note that for company internal code, where all the code which is going to use the API is rebuilt at the same time, this is often not a problem at all, with either interfaces or abstract classes. If you want to add a method to an interface, you can do so as you can upgrade all implementations at the same time.
It's really when you don't have control over the whole code base that you need to be careful.

an class implementing an interface MUST implement all methods and properties defined in the interface.
when inheriting from an Abstract class, you MUST implement/override all the Abstract members, but any non-abstract members will be inherited just as when you inherit from a concrete class.

When you inherit from Interfaces, you must implement all members of that interface. But you can expand on the interface as you deem fit. You can also inherit multiple interfaces. Valid Example:
public interface IPerson
{
string FullName { get; set; }
string SSN { get; set; }
}
public interface IPersonDBContext
{
void Save(IPerson person);
}
public class PersonData : IPerson, IPersonDBContext
{
// Implements IPerson FullName
public string FullName { get; set; }
// Implements IPerson SSN
public string SSN { get; set; }
// Implements IPersonDBContext Save()
public void Save(IPerson person)
{
// Code to save the IPerson instance to the DB...
}
// Added method, not included in any interface...
public void Validate(IPerson person)
{
// Code to validate the IPerson instance...
}
}
Now, for Abstract classes, you can include concrete methods that can be inherited, but also specify some methods that must be overridden. However, note, you cannot have more than one Base Class (and an Abstract Class is still a class...) So you can't mix two abstract classes like you can an interface. Example:
public abstract class Person
{
public string FullName { get; set; }
public string SSN { get; set; }
public abstract void Save();
}
public class PersonData : Person
{
// Implements Abstract Person Save() Method
public override void Save()
{
// Save logic here...
}
// Non-inherited member...
public void Validate()
{
// Access properties of the base class (Abstract Person)
this.FullName.ToString();
this.SSN.ToString();
}
}
Lastly, and most powerfully, you can mix a single abstract base class with as many interfaces as you want... So, If I kept the Abstract class Person, from example 2, and the Interface IPersonDBContext from example 1, I could do this:
public class PersonData : Person, IPersonDBContext
{
// Implements Abstract Person Save() Method
public override void Validate()
{
// Access properties of the base class (Abstract Person)
this.FullName.ToString();
this.SSN.ToString();
}
// Inplmenets IPersonDBContext Save()
public void Save(Person person)
{
// Save logic here...
}
// Non-inhereted method
public void Clone(Person person)
{
// Logic to make a member-wise clone.
}
}
Hope that helps...

Implementing an interface forces you to override its methods - inheriting a class however gives you a choice. Only abstract methods needs to be overriden. The MSDN excerpt points out that the price of a strict interface contract can prove to be expensive later on, when all implementors will need to implement the added methods. Using a class parent with virtual methods let you decide later on whether you need a specialization.

Related

Interface and abstract class in this case

In case I want any class inherits/implements some methods which is better an interface or an abstract class contains these abstract methods only and acts as an interface. I know the difference between the interface and the abstract class well but in this case do the two have the same function or there are different something?
I think we can feel free to use one of them but still I take the side of interface because my aim is to enforce any class to implement these methods and it is the job of interface.
I agree an abstract class with no concrete behavior seems a little pointless so I would favour an interface.
Abstract classes are far more useful when bringing together some common behavior that cannot be overridden along with some elements that can eg) template methods
public abstract class Base
{
public void TemplateMethod()
{
AbstractMethod1();
AbstractMethod2();
}
public abstract void AbstractMethod1();
public abstract void AbstractMethod2();
}
public class Concrete : Base
{
public override void AbstractMethod1()
{
Console.Write("Override Abstract Method 1");
}
public override void AbstractMethod2()
{
Console.Write("Override Abstract Method 2");
}
}
public class Main
{
public Main()
{
var concrete = new Concrete();
concrete.TemplateMethod();
}
}

Is it a right generalization association of an interface class

As the ttitle said, im asking if is this a good programmation/design way.
I got a class, that can be just an Interface (only got 1 abstract method and few attributes)
As a example of my case, this is similar:
We got a main class Car than could be a truck, auto, moto, ...
and has an abstract method void move()
Could I design CAR as interface, and the other concrete classes as a generalization of CAR class? or is this wrong?
public interface Car{
private int length;
private float speed;
public void move();
}
public class truck : Car{
//Constructor
public Car(int size)
{
length=size;
}
public void move()
{
//Move code
}
}
and then
Car myCar = new truck();
myCar.move();
Would be right?
You're mixing up the terms "abstract" and "interface" here.
It is perfectly fine to refer to an instance of a class by the interface it implements. Here you see an interface, ICookieFactory which bakes abstract Cookies:
public interface ICookieFactory
{
Cookie BakeCookie();
}
public class ChocolateChipCookieFactory : ICookieFactory
{
public Cookie BakeCookie()
{
return new ChocolateChipCookie();
}
}
public abstract class Cookie
{
public abstract IEnumerable<Crumb> Crumble();
}
public class ChocolateChipCookie : Cookie
{
public override IEnumerable<Crumb> Crumble()
{
...
}
}
ICookieFactory factory = new ChocolateChipCookieFactory();
Cookie cookie = factory.BakeCookie();
foreach (Crumb crumb in cookie.Crumble())
{
...
}
An interface tells implementations of it which methods or properties it must support, but cannot provide any implementation code itself. You can't define fields in an interface.
An abstract class can include any number of fields and methods, and abstract methods that must be overridden by child classes.
A single class can implement multiple interfaces but only inherit from a single abstract class.
As far as i Know, yes, its possible and right to create an interface which child classes would be a case of generalization association.
But in my case, and thanks to the only answer of C.Evenhuis, i realized it'll be better to make an abstract class (so i can combine some abstract methods that child classes must override, with some concrete methods that childs can override or simply use).

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.

Abstract class does not implement interface

I have an interface so class writers are forced to implement certain methods. I also want to allow some default implemented methods, so I create a abstract class. The problem is that all classes inherit from the base class so I have some helper functions in there.
I tried to write : IClass in with the abstract base, but I got an error that the base didn't implement the interface. Well of course because I want this abstract and to have the users implement those methods. As a return object if I use base I can't call the interface class methods. If I use the interface I can't access base methods.
How do I make it so I can have these helper classes and force users to implement certain methods?
Make sure methods in the base class have the same name as the interface, and they are public. Also, make them virtual so that subclasses can override them without hiding them.
interface IInterface {
void Do();
void Go();
}
abstract class ClassBase : IInterface {
public virtual void Do() {
// Default behaviour
}
public abstract void Go(); // No default behaviour
}
class ConcreteClass : ClassBase {
public override void Do() {
// Specialised behaviour
}
public override void Go() {
// ...
}
}
Move the interface methods into the abstract class and declare them abstract as well. By this, deriving classes are forced to implement them. If you want default behaviour, use abstract classes, if you want to only have the signature fixed, use an interface. Both concepts don't mix.
Having faced with the same problem recently, I've came up with a somewhat more elegant (to my mind) solution. It looks like:
public interface IInterface
{
void CommonMethod();
void SpecificMethod();
}
public abstract class CommonImpl
{
public void CommonMethod() // note: it isn't even virtual here!
{
Console.WriteLine("CommonImpl.CommonMethod()");
}
}
public class Concrete : CommonImpl, IInterface
{
void SpecificMethod()
{
Console.WriteLine("Concrete.SpecificMethod()");
}
}
Now, according to C# spec (13.4.4. Interface mapping), in the process of mapping IInterface on Concrete class, compiler will look up for CommonMethod in CommonImpl too, and it doesn't even have to be virtual in the base class!
The other significant advantage, compared to Mau's solution, is that you don't have to list every interface member in the abstract base class.

How to force sub classes to implement a method

I am creating an object structure and I want all sub classes of the base to be forced to implement a method.
The only ways I could think of doing it were:
An abstract class - Would work but the base class has some useful helper functions that get used by some of the sub classes.
An interface - If applied to just the base class then the sub classes don't have to implement the function only the base class does.
Is this even possible?
N.B. This is a .NET 2 app.
You can have abstract methods in a class with other methods that are implemented. The advantage over an interface is that you can include some code with your class and have the new object be forced to fill in the details for the abstract methods.
public abstract class YourClass
{
// Your class implementation
public abstract void DoSomething(int x, int y);
public void DoSomethingElse(int a, string b)
{
// You can implement this here
}
}
An abstract class - Would work but the
base class has some useful helper
functions that get used by some of the
sub classe
An abstract class doesn't require all functions it provides to be abstract.
abstract class Base {
public void Foo() {} // Ordinary method
public virtual void Bar() {} // Can be overridden
public abstract void Xyz(); // This one *must* be overridden
}
Note that if you replace public with protected, the marked method will be only visible to base classes and subclasses.
An interface - If applied to just the
base class then the sub classes don't
have to implement the function only
the base class does.
This is not entirely correct. If the base class is abstract, you can mark methods that belong to the interface as abstract, and force the implementation in the subclasses.
That brings an option you didn't mention: to use both. You have an IFoo interface, and a FooBase abstract base class the implements it, or part of it. This provides subclasses with a "default" implementation of the interface (or part of it), and also lets you inherit from something else and still implement the interface, or if you want to implement the interface but not inherit the base class implementation. An example might help:
// Your interface
interface IFoo { void A(); void B; }
// A "default" implementation of that interface
abstract class FooBase : IFoo
{
public abstract void A();
public void B()
{
Console.WriteLine("B");
}
}
// A class that implements IFoo by reusing FooBase partial implementation
class Foo : FooBase
{
public override void A()
{
Console.WriteLine("A");
}
}
// This is a different class you may want to inherit from
class Bar
{
public void C()
{
Console.WriteLine("C");
}
}
// A class that inherits from Bar and implements IFoo
class FooBar : Bar, IFoo
{
public void A()
{
Console.WriteLine("Foobar.A");
}
public void B()
{
Console.WriteLine("Foobar.B");
}
}
Yes, and if all the classes you need to do this for are logically subclasses of an existing abstract base class, then add an abstract method to the base class... This is better than an interface because it allows you to add implementation later (by changing abstract base class method to virtual method with a default implementation), if/when it turns out that, say, eight of ten derived classes will have the same implementation, and say, only two of them differ...
EDIT: (based on thread in comments below) The base class must be declared as abstract to do this... You can't have an abstract method in a non-abstract class because a non-abstract class can be instantiated, and if an instance of it was created, there wouldbe NO implementation for that method. So this is illegal. By declaring the base as abstract, you inhibit instantiation of the class. Then, only non-abstract derived classes can be instantiated, where, (because the base method is abstract) you MUST add an implementation for that method.
And full worker sample with params (.netcore 2.2):
class User{
public string Name = "Fen";
}
class Message{
public string Text = "Ho";
}
// Interface
interface IWorkerLoop
{
// Working with client message
string MessageWorker(string msg);
}
// AbstractWorkerLoop partial implementation
public abstract class AbstractWorkerLoop : IWorkerLoop
{
public User user;
public Message msg;
// Append session object to loop
public abstract AbstractWorkerLoop(ref User user, ref Message msg){
this.user = user;
this.msg = msg;
}
public abstract string MessageWorker(string msg);
}
// Worker class
public class TestWorkerLoop : AbstractWorkerLoop
{
public TestWorkerLoop(ref User user, ref Message msg) : base(user, msg){
this.user = user;
this.msg = msg;
}
public override string MessageWorker(string msg){
// Do something with client message
return "Works";
}
}

Categories

Resources