Click here to Skip to main content
15,887,886 members
Please Sign up or sign in to vote.
5.00/5 (1 vote)
See more:
I have doubt in creating an instance over interface or concrete class..
Posted

You don't understand one of the most basic programming ideas here: compile-time types vs runtime types.
It's important to understand when you do any kind of inheritance: with interfaces or base classes. When you have a member of a variable of some class, you declare its compile-time class, but runtime type can be different, because this reference object is assignment-compatible with a derived class.

For example:
C#
class Base { /* .. */ }
class Derived : Base { /* ... */ }

// ...

Base @object = // compile-time type is Base
new Derived(); // runtime type is Derived

It takes understanding of the whole OOP to understand why this is needed. Base class can be used as a contract hiding implementation detail and different implementation in derived classes, which is used to create polymorphous sets.

Now, interface is not a class, but you can consider interface as a special kind of a class which cannot have any implementations, any static members or type definitions in it. The interfaces allows multiple inheritance, they also can be implemented by struct, not just classes. Naturally, interface cannot be a runtime type of any really existing object, only a class or a structure can be. (Base class can be instantiated, to prevent it, one needs to declare it abstract and/or prevent access to all its constructors for code outside the inheritance tree.)

So, with interfaces, we have the same thing
C#
interface ISomeContract { void A(); /* .. */ }
interface ISomeOtherContract { void B(); /* .. */ }

class Implementation : ISomeContract, ISomeOtherContract {
    void ISomeContract.A() { /* ... */ }
    void IOtherSomeContract.A() { /* ... */ }
    internal int SomethingElse; // cannot be accessed
                                // through interface 
                                // (even with public :-)
    // ...
}

// ...

// Now, consider this

ISomeContract first = new Implementation();
ISomeOtherContract second = new Implementation();

first.A(); // yes, you can, but not first.B(), even though B is also implemented
second.B(); // // yes, you can, but not first.A(), even though A is also implemented

Can you see the point? You have two object of the same runtime type, but the compile-time types are interfaces. This is like looking at the same object from the point of view of different interfaces, representing different aspects of the same object.

Of course, you can cast this object to another interface type, but this would defeat the purpose and would be some violation of OOP. Likewise, you cannot access SomethingElse, which requires reference of the type Implementation. The goal is no access (do we ever have problems with access? :-)), but isolation. Interestingly, this way, the same object can participate in different polymorphous sets based on different types.

See also my past answers referenced in this one: Doubts on Interfaces[^].

—SA
 
Share this answer
 
v3
Programming to an Interfaces Not Concrete it's a good concept.
In MSDN about interface says
An interface contains definitions for a group of related functionalities that a class or a struct can implement.
It's Ok..But people's are not fully understandable about Why interfaces , Where and when we use interfaces why recommending Programming to an interface not concrete..a lot of questions in our mind.

Why we use Interfaces?
1.Extensibility
2.Maintainability
3.Testabilty

I am not telling this about detail..But l would like to share something about Extensibility.It's one of the best thing about interfaces.

Suppose In my application i am using Sqlserver for storing and retrieving the data.So i am going to create one class for saving Customer information.
Business Logic

C#
public class CustomerRepository{

public void Save(){//logic for saving data}
public void Update{}
//some other operations here
} 


Application Layer
In my application layer if i want to save a Customer information we should create an instance of a class and call the save method like below
C#
CustomerRepository objCustomer=new CustomerRepository();
objCustomer.Save();


Ok fine..We done all of the functionalities. After some days our client says i don't want to pull the data from Database i have some file system or some services.Hmmm..

How to handle this situation?
We have to modify our application layer as well as the business logic. Here Interfaces come in to the picture.

Modifying our existing application based on interfaces
C#
public interface ICustomerRepository{
void Save();
void Update();
}

C#
public class CustomerRepository:ICustomerRepository{

public void Save(){//logic for saving data}
public void Update{}
//some other operations here
} 


Modifying our Application Layer

C#
public class SomeApplicationLevelClass{
private ICustomerRepository _customerRepository;
public SomeApplicationLevelClass(){
//manual dependency injection.
_customerRepository=new CustomerRepository();
}
public void SaveCustomer(){
_customerRepository.Save();
}
}

Now my data access change from DB to File.
Note: keep the existing CustomerRepository class. It's working functionality. If we modify it will make error prone. In future client need db access also.We can't trust
So i am going to create one more class CustomerFileRepository and implement the same interfaces we have created before

C#
public class CustomerFileRepostory:ICustomerRepository{
public void Save(){//logic for saving data to file}
public void Update{}
}


Modifying application Layer.
Previously we should change all concrete implementation directly in all places. here i am manually injecting dependencies in our constructor.So we only modify the constructor.You can also inject dependencies via configuration by using Dependency Injection API's.For microsoft technologies we can use Ninject,Unity,StructureMap dependency containers.

Modified Code
C#
public class SomeApplicationLevelClass{
private ICustomerRepository _customerRepository;
public SomeApplicationLevelClass(){
//manual dependency injection.
//changes in constructor only
_customerRepository=new CustomerFileRepository();
}
public void SaveCustomer(){
_customerRepository.Save();
}
}

After applying the Dependency Injection Design Pattern your code will look like below
C#
public class SomeApplicationLevelClass{
private ICustomerRepository _customerRepository;
public SomeApplicationLevelClass(ICustomerRepository customerRepository){
//manual dependency injection.
//changes in constructor only
_customerRepository=customerRepository;
}
public void SaveCustomer(){
_customerRepository.Save();
}
}


we no need to mention our concrete implementation in application layer. Everything about concrete class can configure in dependency injection configuration section.If you want to change again to db.you only modify in the configuration or constructor.

Now our application in an Extensible way.I Hope you are got little bit idea about why interfaces and Programming to an interface not concrete concept
If you know more about interfaces you should know the following things deeply. It will take some time to grasp those things but you will get more gradually.

http://stackoverflow.com/questions/130794/what-is-dependency-injection[^]
Dependency Injection for Loose Coupling[^]

SOLID architecture principles using simple C# examples[^]

http://www.oodesign.com/factory-pattern.html[^]
Repository pattern, done right[^]

Hope this information helps you
 
Share this answer
 
v2
Comments
BillWoodruff 6-Nov-14 6:11am    
"An interface contains definitions for a group of related functionalities that a class or a struct can implement" A Class, or Struct, that inherits an Interface MUST implement the Methods, Properties, Events, or Indexers, that match the signatures the Interface specifies.
Do keep in mind that an Interface never has an 'instance: Classes, or Structs inherit from Interface(s). Note that an Interface can inherit from another Interface, and may extend it by adding additional objects' signatures.

Those Classes, or Structs, that inherit from Interface(s) must implement each Method, Property, Event, or Indexer, defined in the Interface so the implementation matches the signatures the Interface specifies.

Instances of Classes, or Structs, are created by program execution, either when the application loads ... or, at run-time, by programming.

I'm not sure what you mean by "concrete class:" perhaps you are thinking of an Abstract Class, which is like an Interface in that it may contain signatures, and can never be instantiated, but, it can provide a default implementation of methods.

Note that a Class or Struct, can only inherit from one Abstract Class.

I suggest you read: [^], [^], [^].
 
Share this answer
 

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900