Reputation: 16239
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
Reputation: 84785
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 abc
s, but these references allow you to do different things:
add
and subtract
on obj
;add
on obj1
;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
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
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:
abc
abc
if called from within a derived class of abc
abc
, if called from within the same assemblyabc
, if called from elsewhere within the abc
class itselfYou 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
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
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
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