Neo
Neo

Reputation: 16239

what is the difference between creating object of class and inteface(see following example)?

interface i1
{
    void add();
}

class abc : i1
{
    public void add()
    {
        Console.WriteLine("hi! add");
    }
}

now in Main I create two objects, like:

abc obj1 = new abc();

and

i1 obj2 = new abc();

Please tell me, what is the difference between the above two instantiations?

Upvotes: 2

Views: 368

Answers (6)

In the case you've shown, there's no difference for most practical purposes.

However, let's say abc implemented other interfaces besides i1:

interface i1 { void add(); }
interface i2 { void subtract(); }

class abc : i1, i2
{
    public void add() { ... }
    public void subtract() { ... }
}

Now, if you repeat your instantiations:

abc obj  = new abc();
i1  obj1 = new abc();
i2  obj2 = new abc();

You end up with three references to three abcs, but these references allow you to do different things:

  • You can call both add and subtract on obj;
  • You can call add on obj1;
  • You can call subtract on obj2;

That is because an interface type only gives you a "partial view" on a concrete type. (While this sounds like a constraint, it is actually a good thing, because it allows you to explicitly state, e.g. in a method's parameter list, what kind of behaviour, or contract, you expect from that parameter; it documents what you're requiring or plan to do with that parameter.)

Upvotes: 1

supercat
supercat

Reputation: 81247

The biggest difference is that obj1 would only be able to hold objects of type "abc" or a type derived therefrom, whereas obj2 would would be able to hold any object that implements "i1". The next-biggest difference is that obj1 could be passed to methods that expects an "abc" or an "i1", while the obj2 could only be passed to methods that expect an "i1".

Note that while both obj1 and obj2 will initially hold objects of type "abc", but that does not imply that they will never at some later time hold other objects, which could be of other types. Because obj2 would be allowed to hold objects of types other than "abc", whether or not it actually ever does, the compiler won't allow it to be passed to methods that require an "abc".

Upvotes: 0

Daniel Schaffer
Daniel Schaffer

Reputation: 57872

In the code you've shown, since there are no explicit implementations and no members besides the i1 implementation, there are no practical differences. Additionally, you specially ask about differences in the instantiation - since you're calling the same constructor in both cases, there is no difference. However, with different code, there could be some significant differences.

In the first example:

abc obj1 = new abc();

You will have access to the following:

  • Public members of abc
  • Protected members of abc if called from within a derived class of abc
  • Internal members of abc, if called from within the same assembly
  • Private members of abc, if called from elsewhere within the abc class itself

You will not have access to any explicitly implemented interface members.

In the second example:

i1 obj2 = new abc();

You will only have access to the members defined on the interface i1

Upvotes: 2

jason
jason

Reputation: 241711

The difference is that obj1 is typed as an instance of abc and obj2 is typed as an instance of i1. Both of these variables are references to instances of abc, but the difference comes in what is accessible in code. Let's say you have the following:

interface IFoo { void Bar(); }
public class Foo : IFoo {
    public void Bar() { Console.WriteLine("Foo.Bar!"); }
    public void Baz() { Console.WriteLine("Baz!"); }
}

Then:

Foo foo = new Foo();
IFoo iFoo = new Foo();

Then the following is legal:

foo.Baz();

but this is not:

iFoo.Baz(); // compile-time error

The point is that the compiler doesn't know that the referrent of iFoo is actually a Foo and thus has a method Baz. In particular, note that this is possible:

public class FooFoo : IFoo {
    public void Bar() { Console.WriteLine("FooFoo.Bar!"); }
}

IFoo foofoo = new FooFoo();
foofoo.Baz(); // not legal

Note that it's not legal to do this, and it's clear why. The only methods that you can invoke through a variable of type IFoo are those defined in the interface, regardless of any methods that might exist on the concrete type referred to by the variable of type IFoo.

Upvotes: 9

sinelaw
sinelaw

Reputation: 16563

The interface-related difference is that if abc implements anything other than i1 (some other interface or just other methods or public members) you'll be able to access them for obj1, but not on obj2.

Upvotes: 0

Larry Osterman
Larry Osterman

Reputation: 16142

An interface defines a contract between a caller and a callee. Any object which implements that interface also implements the contract. So you could also have

class cde : i1 { public void add() { console.writeline("cde add!"); } }

and then have a function:

void myFunction(i1 adder) { adder.add(); }

which is called as follows:

i1 myAbc = new abc();
i1 myCde = new cde();
myFunction(myAbc);
myFunction(myCde);

Even though two classes implement i1, they both implement the same contract and thus myFunction can call into methods on either.

Upvotes: 1

Related Questions