This question already has answers here:
What is the difference between an interface and abstract class?
(38 answers)
Closed 9 years ago.
As the title states i want to know the difference between using the class like this
public class Account
{
public string Username { get; set; }
public string Password { get; set; }
}
and using and Interface like this
public class Account : IAccount
{
public string Username { get; set; }
public string Password { get; set; }
}
public interface IAccount
{
string Username { get; set; }
string Password { get; set; }
}
I am really confused as i find interface is useless as all i can do with it can be done only using Class, Hence, i need someone to clarify things for me.
An interface is a contract: it specifies what members (methods and properties) a class implementing the interface must have. But because it is only a contract, it has no implementations for any of its members. A class can implement zero, one or multiple interfaces.
In contrast: a class is a... well... class of objects (like in taxonomy). For example, an Animal is a class of living things, and a Giraffe is a class of animals. Inheritance expresses this relationship: an Giraffe is an Animal when Giraffe inherits from Animal. It can do anything an animal can do, and more. It can provide implementations for its members, and in .NET a class will inherit from exactly one other class (which is Object unless specified otherwise).
So, if you want to express that your class adheres to one or more contracts: use interfaces. However, you cannot provide an implementation. If you want to express that your class is something, extend a base class. In that case you can provide an implementation, but you can extend only one base class.
For a concrete example:
A linked list, an array list, a stack and a dictionary have something in common: they represent a collection of elements. But their implementations are completely different. The only thing they have in common is the contract they adhere to: ICollection. This means your classes can ask for a collection, any collection: anything that implements ICollection, regardless of its implementation.
On the other hand: a car, a motorcycle and a truck also have something in common: they are wheeled vehicles. But they have more in common than that: they all have a motor, they all spin their tires to go forward. Essentially, they are members of the Vehicle class of objects, and can share (part of) their implementation. However, while a Truck may be a Vehicle and a CargoCarrier, you cannot express this in C#.
Basically:
An interface provides a contract specifying how to talk to an object, but not the specifics of how that object handles that request (apart from parameters and return types etc)
And:
A class (especially an abstract class) provides both the information on how to talk to an object, but in some cases the actual implementation (think overriding a method of a base class).
Interfaces allow you to define a common form of communicating between objects, without caring about the specifics of how they do the things.
An example would be logging:
public interface ILog
{
void WriteMessage(string message);
}
public class ConsoleLogger : ILog
{
public void WriteMessage(string message)
{
Console.WriteLine(message);
}
}
public class MessageBoxLogger : ILog
{
public void WriteMessage(string message)
{
MessageBox.Show(message);
}
}
public void DoSomethingInteresting(ILog logger)
{
logger.WriteMessage("I'm doing something interesting!");
}
Because both ConsoleLogger and MessageBoxLogger implement the ILog interface (the WriteMessage method, any part of code can take an ILog without ever needing to know what it actually does, they only care that it does something - in this case, writing a log message.
So in the code above, either a ConsoleLogger or MessageBoxLogger could be supplied to DoSomethingInteresting it doesn't matter at all because ILog "knows" how to talk to that object.
Related
In my project, I want to implement the SOLID principles, so that my code may be easier to test and extend later down the line. For this purpose, I am curious if I can use Liskov's Substitution Principle in order to make testing of code easier, by having a production class and a testing class both inherit an interface and act in it's place.
Interface + Object classes
public interface Iinterface {
int commonVariable { get; set; }
}
public class ProductionClass : IInterface{
public commonVariable { get; set; }
//Production variables + functions
public ProductionClass() {}
}
public class TestClass : IInterface {
public commonVariable { get; set; }
//Test variables + functions
public TestClass() {}
}
Domain Model
public class DomainModel() {
//Could object be either of ProductionClass or TestClass without breaking my database?
public virtual IInterface object { get; set; }
}
As ProductionClass and TestClass both inherit IInterface, I know that object of either class can be placed in a IInterface variable.
However, when constructing a database, would a IInterface object be valid?
Would it hold all the data of whatever class gets passed to it, or just the data specified when the interface was defined?
What would happen If I tried to insert an object of a different class in the object? Would the columns for the table be overwritten with the new class' variables?
Should I even be attempting to make TestClass, at this rate?
The class design you show is not an example of LSP (Liskov Substitution Principle). It's rather an example of DI (Dependency Inversion): the concretions (DomainModel) depend on abstractions (IInterface).
To have an LSP case, you'd need:
class Base { }
class Derived : Base { }
void Process(Base item)
{
// here, the method shall not care whether 'item' is in fact
// an instance of 'Base' or 'Derived'
}
"Inherit an interface" is incorrect. "Implement an interface" is correct. The classes cannot inherit interfaces, only implement them.
Having a variable (or a field, or a property) of type IInterface, you can only tell the following: the object I have implements that interface. You have no knowledge about the concrete type of the object - whether it is a TestClass, a ProductionClass or a ThirdPartyClass (unless you check for type explicitly of course). The object might be completely different internally. It might contain all the data you need or no data at all.
As a design suggestion: use interfaces to abstract your services and business entities. Use concrete types (POCO) to represent your DTOs (Data Transfer Objects).
I am learning OOP in C# however having trouble designing a mock application that simulates a University Card system which allows student and staff to access certain services/building.
I have a abstract class UniversityMember which contains information which is commons such as everyone has a firstname etc. I have interfaces which are more specific such as IStudent generates studentIds and set door/access level for each student using the enum AccessLevel class. However when I do
public static void Main(string[] args)
{
Student Majid = new Student();
Majid.FName = "foo";
Majid.LName = "hello";
Majid.SetStudentId();
Majid.ExpiryDate = new DateTime(2018, 09, 10);
Majid.Type = MemberType.Student;
Majid.setStudentLevel(AccessLevel.CharlesWilson,
AccessLevel.ComputerScienceBuilding,
AccessLevel.DavidWilson);
PayTutionFees(Majid);
}
public static void PayTutionFees(IStudent student)
{
//Design problem
//student.ID etc
}
I use polymorphism because every student implements IStudent however I dont have access to the Student information as its located in the UniversityMember abstract class. I dont want to have the interfaces filled with repeated methods as their are common information shared between students and teaching staff. How could I get around this problem?
If you know that the implementers of IStudent, IWorkingStaff etc. have some properties in common, you can describe those in a separate interface, say IUniversityMember:
public interface IUniversityMember
{
String ID {get;}
// etc.
}
And make your existing interfaces, which imply access to these common properties, extend IUniversityMember.
public interface IStudent : IUniversityMember {...}
public interface IWorkingStaff : IUniversityMember {...}
(Which means that both IStudent and IWorkingStaff now require their implementers to provide properties, listed in IUniversityMember interface in addition to their own.) Then you can make your abstract UniversityMember class implement this new IUniversityMemeberinterface.
Since your concrete classes extend UniversityMember anyway, they will satisfy this wider interface automatically, having inherited all the properties, required by IUniversityMember, from their base abstract class.
In this way you'll be able to accept IStudent as parameter in your method and still have access to properties, which it has in common with other kinds of university members.
When you are using interface as a parameter you can't use student.ID inside because you can't be sure that only Student class will implement given interface. You should rely only on interface members. In this case I suppose you just use wrong parameter type (as I've mentioned in my comment).
The problem is you did not separate an abstraction from the implementation. If you have more generic-like information, common for all members, then you should declare it in an interface, eg:
public interface IUniversityMember
{
publis string Name {get;set;}
publis string Id {get;set;}
}
and then inherit it in your IStudent interface:
public interface IStudent: IUniversityMember
{
publis string StudentRelatedProperty {get;set;}
}
while your UniversityMember class should implement the IUniversityMember. An abstract class is an implementation detail, which should not be exposed.
You try to acces IStudent.ID
public static void PayTutionFees(IStudent student)
{
student.ID // at this point student is a IStudent so no ID prop available
}
You could start casting at this point
public static void PayTutionFees(IStudent student)
{
//Design problem
(Student)student.ID;
var realStudent = student as Student;
//to avoid wrong cast check for type before
if(student.GetType() == typeof(Student))
{//jippy student is a Student!}
}
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.
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.
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.