I have an interface IFace implemented by class Animal. I cannot modify IFace or Animal. I want to extend Animal with my subclass Human and have it reimplement IFace. However, I want to be able to store an instance of Human in a variable of type IFace such that accessing that variable uses the Animal implementation directly—as if the variable’s type was Animal.
https://dotnetfiddle.net/6JjNfR
using System;
interface IFace
{
void Talk();
}
class Animal : IFace
{
public void Talk()
{
Console.WriteLine("Oink");
}
}
class Human : Animal, IFace
{
public new void Talk()
{
Console.WriteLine("Hi");
}
}
public class Program
{
public static void Main()
{
var human = new Human();
human.Talk();
var face = (IFace)human;
face.Talk();
var animal = (Animal)human;
animal.Talk();
var face2 = animal;
face2.Talk();
IFace face3;
face3 = human;
face3.Talk();
// How to get the following to oink like animal?
face3 = animal;
face3.Talk();
}
}
Is this possible or do I have to create a proxy class like the following?
https://dotnetfiddle.net/marXND
class AnimalProxy : IFace
{
Animal Animal { get; set; }
public AnimalProxy(Animal animal)
{
Animal = animal;
}
public void Talk()
{
Animal.Talk();
}
}
And if the proxy is required, why is the proxy required if I can access the Animal implementation of IFace by just casting to Animal?
I bet the answer has something to do with how explicit interfaces work and how casting a Human to an Animal and then again casting to IFace should return Human’s implementation… Maybe implicit interface implementation syntax just lets the C# compiler automatically generate an explicit implementation which just calls the implicit implementation. Which means that when I cast something to Animal I’m accessing Animal methods instead of IFace methods even though those same methods are the “implicit” implementation of IFace.
So, how can I cast directly to the base implementation of a reimplemented interface—and if that’s impossible, why?
Don't have the Human definition re-implement the interface:
class Human : Animal // , IFace
{
public new void Talk()
{
Console.WriteLine("Hi");
}
}
If you do that, the calling Talk on a Human will use the new implementation, but calling Talk on an IFace that happens to be a Human will use the base class' implementation.
See this article for some more informatoin, and even weirder circumstances, surrounding interface re-implementation.
Related
I have seen an Interface instance being generated from a class many times. Why do we use interface this way? An interface instance is created only itself with the help of the derived class and we can access only these interface members through this instance. How does this give an advantage? I'm so confused.
interface IPrint
{
void Print();
}
class Sample : IPrint
{
public void Print()
{
Console.WriteLine("Print...");
}
public void Sample()
{
Console.WriteLine("Sample...");
}
}
class Program
{
static void Main(string[] args)
{
IPrint print = new Sample();
print.Print();
}
}
Interfaces define that a class MUST be able to do something. This means that you know the object being worked on will do what you want to be able to do. It allows you greater freedom and is one of the advantages of OOP. This is a deep topic but a very basic example would be this:
public interface IAnimal
{
string Speak();
}
public class Dog : IAnimal
{
public string Speak()
{
return "Woof, woof";
}
}
public class Cat : IAnimal
{
public string Speak()
{
return "Meow";
}
}
public class Parrot : IAnimal
{
public string Speak()
{
return "Sqwark!";
}
}
Then you could use any animal you like!
class Program
{
static void Main(string[] args)
{
// Writes Woof, Woof
IAnimal animal = new Dog();
Console.WriteLine(animal.Speak());
// Now writes Meow
animal = new Cat();
Console.WriteLine(animal.Speak());
// Now writes Sqwark etc
animal = new Parrot();
Console.WriteLine(animal.Speak());
}
}
This also allows you to then get into things like Inversion Of Control where you would take an item in like this and you could pass a dog, cat or parrot and the method would always work, not knowing or caring which animal it was:
public void ShoutLoud(IAnimal animal)
{
MessageBox.Show("Shout " + animal.Speak());
}
This then makes ShoutLoud unit testable because you could use a mock object rather than a real animal. It basically makes your code flexible and dynamic rather than rigid and tightly coupled.
Also, expanding on Matthew's question. In C# you can only inherit from one base class but you can have multiple interfaces. So, you could have:
public class Dog : IAnimal, IMammal, ICarnivor
This allows you to have small interfaces (recommended) that then allow you to build up so giving maximum control over what an item can / must do.
Using an interface this way gives you the ability to create methods that use standard template of the interface. So here you might have many classes of printer that all inherit from IPrinter
class SamsungPrinter : IPrinter
{
// Stuff and interface members.
}
class SonyPrinter : IPrinter
{
// Stuff and interface members.
}
interface IPrinter
{
void Print();
}
So for each type SamsungPrinter, SonyPrinter, etc. you can pre-process using something like
public static void PreProcessAndPrint(IPrinter printer)
{
// Do pre-processing or something.
printer.Print();
}
You know from inheriting from IPrinter and using that type in the method parameters that you can always safely use the Print method on what ever object is passed.
Of course there are many other uses for using interfaces. One example of their use is in design patterns, in particular the Factory and Strategy patterns. The description of which and examples can be found here.
I hope this helps.
But how does this differ from, for example, using a base class with virtual methods?
You are all in the assumption that one programmer or one program writes the interface and the classes, but this doesn't always have to be this way.
Maybe you have a complete finished program that works with animals and you have this worked out using:
public abstract class Animal { public abstract string Speak(); }
And then some day you download some awesome DLL from nuget that shows pictures for animals. The class library contains a contract - interface - 'IAnimal':
namespace AwesomeAnimalLibrary
{
public interface IAnimal
{
string AnimalName;
}
}
The class library also maybe contains :
namespace AwesomeAnimalLibrary
{
public class AnimalPhotos
{
[Byte] GetPhotos(IAnimal animal);
}
}
What could you do now ? Your bas class Animal can implement the AwesomeAnimalLibrary IAnimal interface and that's it.
Don't assume that other people will use you abstract base classes but work together using interface contracts.
Interface can not have instance because interface implements only signatures of properties or methods. Interface is just a pointer to an instance of some class:
interface IExample
{
// method signature
void MyMethod();
}
public class MyClass : IExample
{
// method implementation
public void MyMethod()
{
ConsoleWriteline("This is my method");
}
}
// interface pointing to instance of class
IExample ie = new MyClass();
ie.MyMethod();
When I try define an variable like that:
IVeterinarian<IAnimal> v = (IVeterinarian<IAnimal>)new CatVeterinarian();
These are an example for the interfaces and classes decleration:
interface IAnimal
{
}
class Dog : IAnimal
{
}
class Cat : IAnimal
{
}
interface IVeterinarian<TAnimal> where TAnimal : IAnimal
{
void Heal(TAnimal animal);
}
class DogVeterinarian : IVeterinarian<Dog>
{
public void Heal(Dog animal)
{
}
}
class CatVeterinarian : IVeterinarian<Cat>
{
public void Heal(Cat animal)
{
}
}
What's the difference btw my example and declaring IEnumerable of strings in a IEnumerable of objects variable?
Why am I getting an InvalidCastException.
Any ideas?
You can't create an instance like that;
IVeterinarian v = (IVeterinarian)new CatVeterinarian();
Because, you should pass a type which is implemented from IAnimal;
IVeterinarian<Cat> v = new CatVeterinarian();
EDIT
You are getting cast invalid exception because IVeterinarian<IAnimal> is not IVeterinarian<Cat> even implements it.
public interface IEnumerable<out T> : IEnumerable
{
IEnumerator<T> GetEnumerator();
}
As you see, IEnumerable uses out parameter and it makes it covariant. Please review this page.
In your case, you can't make your generic as covariant because the generic is being used as signature. By using covariants you can return derived types as you mentioned in the question.
IEnumerable<object> list = new List<string>();
In short, it has different purpose from your case which you want to try.
In my usecase, I wanted to take care differently each animal. I found an easy way to do it - Here's my solution:
Remove the generic from the IVeterinarian
Create a generic base Veterinarian class which implements IVeterinarian where T implements IAnimal
Create an abstract method in the base class with the same name that gets an animal argument in type T
Implement the original Heal method with calling the abstract method giving the animal argument after casting to T
In the Cat&Dog Veterinarian classes, just override the abstract method
Here's an example:
interface IAnimal
{
}
class Dog : IAnimal
{
}
class Cat : IAnimal
{
}
interface IVeterinarian
{
void Heal(IAnimal animal);
}
abstract class BaseVeterinarian<T> : IVeterinarian
where T : IAnimal
{
public void Heal(IAnimal animal)
{
Heal((T)animal);
}
protected abstract void Heal(T animal);
}
class DogVeterinarian : BaseVeterinarian<Dog>
{
protected override void Heal(Dog animal)
{
}
}
class CatVeterinarian : BaseVeterinarian<Cat>
{
protected override void Heal(Cat animal)
{
}
}
Be aware that you must send a correct IAnimal object as argument - or it will throw an InvalidCastException.
Now I can make IVeterinarian objects with different implementations almost like I whished in my question.
IVeterinarian v = new CatVeterinarian();
v.Heal(new Cat());
IVeterinarian v2 = new DogVeterinarian();
v2.Heal(new Dog());
Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 6 years ago.
Improve this question
I have been reading up on programing to interfaces rather than implementation. One area I am not properly understanding is how to deal with non-interface methods. For example an interface IAnimal and a Cat class that implements it. My examples are in C# but I think it should also apply to other languages.
public interface IAnimal
{
void Eat();
}
public class Cat : IAnimal
{
public Cat()
public void Eat()
{
//Do something
}
public string Meow()
{
return "meow";
}
}
From what I've read it seems like I should be trying to work with the interface rather than the cat implementation such as,
Main()
{
IAnimal cat = new Cat();
}
But this leaves me without access to my meow method as it is not a part of the IAnimal interface. Should I be creating another interface ICat which implements IAnimals and have Cat implement it? And does this mean that all methods should be an implementation from an interface or abstract class? Or am I doing something else here wrong.
Thanks for your help.
What you would do is you is have another interface that represent's speaking animals and either inherit from IAnimal or add it as a 2nd interface. Classes that have animals that speak implement the 2nd interface.
with a inherited interface.
public interface IAnimal
{
void Eat();
}
public interface ISpeakingAnimal : IAnimal
{
string Speak();
}
public class Cat : ISpeakingAnimal
{
public Cat()
public void Eat()
{
//Do something
}
public string Speak()
{
return "meow";
}
}
public class Fish : IAnimal
{
public Fish()
public void Eat()
{
//Do something
}
}
With a 2nd decorator interface
public interface IAnimal
{
void Eat();
}
public interface ISpeakable
{
string Speak();
}
public class Cat : IAnimal, ISpeakable
{
public Cat()
public void Eat()
{
//Do something
}
public string Speak()
{
return "meow";
}
}
public class Fish : IAnimal
{
public Fish()
public void Eat()
{
//Do something
}
}
If you need the method not be Speak() but instead be Meow() you can use explicit interface implementations to expose the Speak() method only though that interface.
public class Cat : ISpeakingAnimal
{
public Cat()
public void Eat()
{
//Do something
}
string ISpeakingAnimal.Speak()
{
return Meow();
}
public string Meow()
{
return "meow";
}
}
The point of an interface is to define behavior common to classes that implement that interface. You are correct in noting that defining cat like so:
IAnimal cat = new Cat();
leaves you unable to access methods in the Cat class that are not in IAnimal. So why is it encouraged to implement things in this way?
The answer is simple: it makes it very easy to change the code later on. For example, if we have a Dog class that implements IAnimal, like so:
public class Dog : IAnimal
{
// some methods
}
then we can very easily replace our Cat class with the Dog class, without having to change any other code. In other words, we can replace:
IAnimal cat = new Cat();
with
IAnimal dog = new Dog();
without having to change any other code in the entire program (besides the variable names). This is because defining Cat and Dog with respect to IAnimal forces them to only use methods found within IAnimal, though they may be implemented differently in Cat and Dog.
Of course, if you want to use something specific only to Cat or Dog, you will have to define the class explicitly, as mentioned by #Erick in his answer, like so:
Cat cat = new Cat();
In general, you should try to define as many common behaviors in the interface as possible, only explicitly casting to a certain class like Cat or Dog when absolutely necessary. This makes your code a lot more versatile and changeable.
If you need to access the method it would be necessary to make an explicit cast.
In this case it would be more interesting to leave your Meow() method more generic for other possible classes that could implement it:
public interface IAnimal
{
void Eat();
void Speak();
}
public class Cat : IAnimal
{
public void Eat() { }
public string Speak()
{
return "meow";
}
}
public class Dog : IAnimal
{
public void Eat() { }
public string Speak()
{
return "au";
}
}
My two cents on this topic is that it's true that you need to depend on abstractions (i.e. interfaces) rather than implementations.
BTW, doesn't this going too far? There's no need to define an interface for any class within your object model. Usually you define interfaces if you need to accept certain objects fulfilling a given contract.
For example, I wouldn't define IAnimal or ICat interfaces. Probably I would define an abstract class Animal and just a concrete class Cat.
If for some reason I need to accept living beings in some API that could eat I would define an interface like this:
public interface IFeedable
{
void Feed(Food food);
}
and if a living being can talk:
public interface ITalkative
{
void Talk(Food food);
}
Unless there's no feature/property/behavior that could be exclusive to animals, I would leave these interfaces as is.
public abstract class Animal : ITalkative, IFeedable
{
public Animal(AudioPlayer audioPlayer)
{
AudioPlayer = audioPlayer;
}
private AudioPlayer AudioPlayer { get; }
public abstract void Feed(Food food);
public void Talk()
{
// Probably you would want to load an animal sound library
// here, and later pass the audio player with the sound library
// already loaded
OnTalk(AudioPlayer.LoadLibrary("animals"));
}
protected abstract void OnTalk(AudioLibrary audioLibrary);
}
public sealed class Cat : Animal
{
public Cat(AudioPlayer audioPlayer) : base(audioPlayer)
{
}
public override void Feed(Food food)
{
if(food is Vegetable)
{
throw new NotSupportedException("MeeEEEEooW (=O ò.ó)=O!!");
}
else if(food is Meat)
{
// Proceed to eat this meat!
}
}
protected override void OnTalk(AudioLibrary audioLibrary)
{
audioLibrary.Play("sweet-cat");
}
}
And if somewhere you need to make an object to talk:
ITalkative talkative = some as ITalkative;
if(talkative != null)
{
talkative.Talk();
}
Or if you need to feed the object:
IFeedable feedable = some as IFeedable;
if(feedable != null)
{
feedable.Feed(new Vegetable());
}
As you can see, you don't define interfaces for everything, but just for those things that you need to handle inside some API and you don't care who can do some actions and/or own some data, but you just care about the object can do or exposes certain behaviors and data respectively.
I want something like this:
public interface IAnimal
{ }
public class Dog : IAnimal
{
public Dog() {}
}
public class Cat : IAnimal
{
public Cat() {}
}
public abstract class TestClassBase
{
public TestClassBase()
{
_lazyAnimal = CreateLazyAnimal();
}
private Lazy<IAnimal> _lazyAnimal = null;
public IAnimal Animal
{
get
{
IAnimal animal = null;
if (_lazyAnimal != null)
animal = _lazyAnimal.Value;
return animal;
}
}
// Could be overridden to support other animals
public virtual Lazy<IAnimal> CreateLazyAnimal()
{
// default animal is a dog
return new Lazy<Dog>(); // this type of casting doesn't work and I don't know a good workground
}
}
I know from tinkering with MEF that it manages to find and store different types, implementing a single interface, into Lazy<T>. Just not sure how to do it myself.
Lazy<Dog> cannot be converted directly to Lazy<IAnimal>, but since Dog can be converted to IAnimal you can use the Lazy<IAnimal> constructor overload that expects an IAnimal (strictly speaking, it takes a Func that returns an IAnimal) and provide a Dog instead:
public virtual Lazy<IAnimal> CreateLazyAnimal()
{
// default animal is a dog
return new Lazy<IAnimal>(() => new Dog());
}
Casting Lazy<Dog> to Lazy<IAnimal> is not allowed because the types are different (the Lazy<T> type inherits just from object). In some cases, the casting can make sense - for example casting IEnuerable<Dog> to IEnumerable<IAnimal>, but the casting isn't safe in all cases.
C# 4.0 adds support for this casting in the safe case. It is called covariance and contravariance. For example, this article gives a nice overview.
Unfortunatelly, in C# 4.0 this works only for interfaces and delegates and not for concrete classes (e.g. Lazy<T>). You could probably solve the problem by creating interface ILazy<out T> and a wrapper for standard Lazy type, but it is probably easier to just write conversion from Lazy<Dog> to Lazy<IAnimal>.
In C# I have three classes: Person, Cat, and Dog.
Both the Cat and Dog classes have the method Eat().
I want the Person class to have a property ‘Pet’.
I want to be able to call the Eat method of both the Cat and Dog via the Person via something like Person.Pet.Eat() but I can’t because the Pet property needs to be either of type Cat or Dog.
Currently I’m getting round this with two properties in the Person class: PetDog and PetCat.
This is okay for now, but if I wanted a 100 different types of animal as pets then I don’t really want to have 100 different Pet properties in the Person class.
Is there a way round this using Interfaces or Inheritance? Is there a way I can set Pet to be of type Object but still access the properties of whichever animal class is assigned to it?
You could have the pets derive from a common base class:
public abstract class Animal
{
protected Animal() { }
public abstract void Eat();
}
And then have Cat and Dog derive from this base class:
public class Cat: Animal
{
public override void Eat()
{
// TODO: Provide an implementation for an eating cat
}
}
public class Dog: Animal
{
public override void Eat()
{
// TODO: Provide an implementation for an eating dog
}
}
And your Person class will have a property of type Animal:
public class Person
{
public Animal Pet { get; set; }
}
And when you have an instance of Person:
var person = new Person
{
Pet = new Cat()
};
// This will call the Eat method from the Cat class as the pet is a cat
person.Pet.Eat();
You could also provide some common implementation for the Eat method in the base class to avoid having to override it in the derived classes:
public abstract class Animal
{
protected Animal() { }
public virtual void Eat()
{
// TODO : Provide some common implementation for an eating animal
}
}
Notice that Animal is still an abstract class to prevent it from being instantiated directly.
public class Cat: Animal
{
}
public class Dog: Animal
{
public override void Eat()
{
// TODO: Some specific behavior for an eating dog like
// doing a mess all around his bowl :-)
base.Eat();
}
}
Is there a way round this using Interfaces or Inheritance?
Yes.
Interfaces: make an interface IEat or IPet or whatever concept you want to represent. Make the interface have an Eat method. Have Cat and Dog implement this interface. Have the Pet property be of that type.
Inheritance: Make an abstract base class Animal or Pet or whatever concept you want to represent. Make an abstract method Eat on the base class. Have Cat and Dog inherit from this base class. Have the Pet property be of that type.
What is the difference between these two?
Use interfaces to model the idea "X knows how to do Y". IDisposable, for example, means "I know how to dispose of the important resource that I am holding onto". That is not a fact about what the object is, it is a fact about what the object does.
Use inheritance to model the idea of "X is a kind of Y". A Dog is a kind of Animal.
The thing about interfaces is you can have as many of them as you want. But you only get to inherit directly from one base class, so you have to make sure you get it right if you're going to use inheritance. The problem with inheritance is that people end up making base classes like "Vehicle" and then they say "a MilitaryVehicle is a kind of Vehicle" and "A Ship is a kind of Vehicle" and now you're stuck: what is the base class of Destroyer? It is both a Ship and a MilitaryVehicle and it can't be both. Choose your "inheritance pivot" extremely carefully.
Is there a way I can set Pet to be of type Object but still access the properties of whichever animal class is assigned to it?
Yes, in C# 4 there is, but do not do so. Use interfaces or inheritance.
In C# 4 you can use "dynamic" to get dynamic dispatch at runtime to the Eat method on the object that is in Pet.
The reason you don't want to do this is because this will crash and die horribly should someone put a Fruit or a Handsaw in the Pet property and then try to make it Eat. The point of compile-time checks is to decrease program fragility. If you have a way to make more compile-time checks, use it.
Use an abstract class.
public abstract class Pet { public abstract void Eat(); }
public class Dog : Pet { }
public class Cat : Pet { }
public class Person {
public Pet Pet;
}
I’m sure you can do the rest.
Using an interface;
abstract class Animal
{
public virtual void DoSomething() { }
}
interface ICanEat
{
void Eat();
}
class Dog : Animal, ICanEat
{
public void Eat()
{
Console.Out.WriteLine("Dog eat");
}
}
class Cat : Animal, ICanEat
{
public void Eat()
{
Console.Out.WriteLine("Cat eat");
}
}
class Person
{
public Animal MyAnimal { get; set; }
}
Then you can call
(person.MyAnimal as ICanEat).Eat();
performing the correct null-checks as you go.
Why not create a base class of type Pet
public abstract class Pet{
public abstract void Eat();
}
Have this cat and dog inherit from an interface IPet
public interface IPet
{
bool hungry();
void Eat();
}