why can't a compiler resolve method overriding? - c#

In the following C# snippet
public class Animal
{
public virtual void MakeSound()
{
Console.WriteLine("Animal sound");
}
}
public class Dog:Animal
{
public override void MakeSound()
{
Console.WriteLine("Dog sound");
}
}
class Program
{
static void Main(string[] args)
{
Animal an = new Dog();
an.MakeSound();
Console.ReadLine();
}
}
the method to be called is determined at runtime. Why exactly can't the compiler figure out, which method to call?
Why doesn't the compiler see that an refers to a Dog object and then choose the method from that class?
And how does the runtime determine which method to be called?

This sounds an awful lot like an exam/homework question. But let me answer your question with another question.
Consider the following code:
static void Main(string[] args)
{
var random = new Random();
Animal an = null;
if (random.NextDouble() < 0.5) {
an = new Dog();
} else {
an = new Cat();
}
an.MakeSound();
Console.ReadLine();
}
How is the compiler supposed to know at compile time which method to call? It can not, only during runtime is the concrete type known.

You told the compilier that the variable is of type Animal. It looks only at declarations, while you expect it to execute your code to figure out what you mean. That's not how it works.

Consider following code:
class Program
{
static void Main(string[] args)
{
Animal dog = new Dog();
MakeSoundAbstract(dog);
Animal an = new Animal();
MakeSoundAbstract(an);
Console.ReadLine();
}
static void MakeSoundAbstract(Animal animal)
{
animal.MakeSound();
}
}
If compiler will determine virtual calls during compilation not during runtime then MakeSoundAbstract method will always execute MakeSound method of class Animal so we are loosing here the power of abstraction.

Consider this change to your code:
public class Animal
{
public virtual void MakeSound()
{
Console.WriteLine("Animal sound");
}
}
public class Dog : Animal
{
public override void MakeSound()
{
Console.WriteLine("Woof!");
}
}
public class Cat : Animal
{
public override void MakeSound()
{
Console.WriteLine("Purrrrrrrrrrrrrr");
}
}
class Program
{
static void Main(string[] args)
{
Animal an = GetAnimal(DateTime.Now);
an.MakeSound();
Console.ReadLine();
}
private Animal GetAnimal(DateTime dateTime)
{
if (dateTime.DayOfWeek == DayOfWeek.Monday)
{
return new Dog();
}
else
{
return new Cat();
}
}
}
Now it is impossible to know what type of animal to create at compile time, as it depends on the day of the week when the code is actually run. On Mondays you will get a Dog, but at any other time you will get a Cat. This is a defining benefit of polymorphism--types are not baked in by the compiler, but are derived on the fly when the code is executing. Polymorphism allows you work with these derived types, even though you do not know exactly what they will be when you write your code (but you do know they are all types of animals).

Related

c# composition and multiple inheritance design

I'm having troubles thinking of the design for my assignment.
for the assignment I would have 2 inheritance hierarchies and I would need to mimic multiple inheritance functionalities and the cross product so robotDog, robotBigDog, robotSmallDog, attackRobotDog, etc... it seems just doing multiple inheritance would end up being 9 different class files which is probably not the best approach.
for instance:
public class dog{
public virtual void bark{ Console.WriteLine("woof")};
}
public class bigDog : dog{
public override void bark{ Console.WriteLine("WOOF")};
}
public class smallDog : dog{
public override void bark{ Console.WriteLine("arf arf")};
}
public class robot{
public virtual void action{ Console.WriteLine("moves")}
}
public class attackRobot : robot{
public virtual void action{ Console.WriteLine("attacks")}
}
public class serviceRobot : robot{
public virtual void action{ Console.WriteLine("serves")}
}
I was instead thinking of doing a double composition of one class containing a dog and a robot because smallDog and bigDog can stand in for dog and attackRobot and serviceRobot can stand in for robot.
public class robotDog{
dog myDog;
robot myRobot;
public robotDog(dog typeDog, robot typeRobot){
myDog = typeDog;
myRobot = typeRobot;
}
.
. various functionality
.
}
is it a practical design to use double composition and also have a constructor that ask for a dog and robot? Or is there a different way to think/approach this?
You can not have multiple inheritance in C#, but you can have multiple interfaces.
You can use interfaces to define what a dog and a robot look like, create some different flavours of dog and robot, then combined them into a RobotDog class that has some defaults that can be overridden, i.e.
using System;
namespace ConsoleApp1
{
public interface IDog
{
void bark();
}
public interface IRobot
{
void action();
}
public class dog : IDog
{
public virtual void bark() { Console.WriteLine("woof"); }
}
public class bigDog : dog
{
public override void bark() { Console.WriteLine("WOOF"); }
}
public class smallDog : dog
{
public override void bark() { Console.WriteLine("arf arf"); }
}
public class robot : IRobot
{
public virtual void action() { Console.WriteLine("buzz, click"); }
}
public class attackRobot : robot
{
public override void action() { Console.WriteLine("attacks"); }
}
public class serviceRobot : robot
{
public override void action() { Console.WriteLine("attacks"); }
}
public interface IRobotDog : IDog, IRobot
{
IDog dog { get; set; }
IRobot robot { get; set; }
}
public class RobotDog : IRobotDog
{
public IDog dog { get; set; }
public IRobot robot { get; set; }
public RobotDog()
{
dog = new dog();
robot = new robot();
}
public RobotDog(IDog dogType)
{
dog = dogType;
robot = new robot();
}
public RobotDog(IRobot robotType)
{
dog = new dog();
robot = robotType;
}
public RobotDog(IDog dogType, IRobot robotType)
{
dog = dogType;
robot = robotType;
}
public void bark() { dog.bark(); }
public void action() { robot.action(); }
}
class Program
{
static void Main(string[] args)
{
RobotDog robotDog = new RobotDog();
robotDog.bark();
robotDog.action();
robotDog = new RobotDog(new bigDog(), new attackRobot());
robotDog.bark();
robotDog.action();
robotDog = new RobotDog(new bigDog());
robotDog.bark();
robotDog.action();
robotDog = new RobotDog(new attackRobot());
robotDog.bark();
robotDog.action();
robotDog = new RobotDog();
robotDog.dog = new bigDog();
robotDog.bark();
robotDog.action();
}
}
}
I would like to expand just a bit from what Xavier has offered. An interface is nothing more than a "contract". In its simplest form, any class that inherits an interface MUST declare the functions / methods / properties within it. So this way, any other object attempting to rely on its defined exposed components knows that it can, and they wont be missing. Now, you as the developer can implement that however you want and even have an empty function, provided the function actually exists but otherwise does nothing.
public interface IDog
{
void bark();
}
public interface IRobot
{
void action();
}
First, just simple dog or robot. Notice each implements their respective "REQUIRED" methods from the interface.
public class Dog : IDog
{
public void bark()
{
Console.WriteLine("Woof");
}
}
public class Robot : IRobot
{
public void action()
{
Console.Write("Activate jet pack, fly");
}
}
Notice below, the robotic dog never has an actual Dog or Robot class of its own. However, it DOES implement both individual requirements of each interface respectively into one major class of both.
public class RoboticDog : IDog, IRobot
{
public void bark()
{
Console.WriteLine("Woof -beep- woof");
}
public void action()
{
Console.Write("Activate jet pack, flying with fur");
}
}
Now, lets see how they operate individually.
static void Main(string[] args)
{
object testDog = new Dog();
object testRobot = new Robot();
object testBoth = new RoboticDog();
WhatCanIDo(testDog);
WhatCanIDo(testRobot);
WhatCanIDo(testBoth);
}
public void WhatCanIDo( object theThing )
{
// Here I am checking if the object is of a class type
// the inherits from IDog. If so, I can type-cast it as such
// and then call its "bark()" method as required to exist from interface.
if (theThing is IDog)
((IDog)theThing).bark();
// likewise if the object has interface of an IRobot
if (theThing is IRobot)
((IRobot)theThing).action();
}
I created a small console application for you with some small tips on how to catch when you need an interface over a base class, or vice-versa.
using System;
namespace ConsoleApp6
{
class Program
{
interface IWalkable
{
void Walk(int xAxis, int yAxis);
}
class Robot : IWalkable
{
public int RobotId { get; set; }
public Robot(int robotId)
{
RobotId = robotId;
Console.Write("Robot created! \n");
}
public void Walk(int xAxis, int yAxis)
{
Console.WriteLine("Im walking beep boop");
Console.WriteLine("*walks*");
Console.WriteLine($"Ended up in X: {xAxis} y:{yAxis}");
}
}
class BadRobot : Robot
{
public BadRobot(int robotId) : base(robotId)
{
}
}
class Dog : IWalkable
{
public Dog()
{
Console.Write("Dog created! \n");
}
public void Walk(int xAxis, int yAxis)
{
Console.WriteLine("Im walking, roof roof");
Console.WriteLine("*walks*");
Console.WriteLine($"Ended up in X: {xAxis} y:{yAxis}");
}
public virtual void Breath()
{
Console.WriteLine("I breath normal");
}
}
class BadDog : Dog
{
public override void Breath()
{
Console.WriteLine("I breath normal");
Console.WriteLine("But then I bark, because im bad");
}
//I can't "extend" an interface
//but I can extend a virtual method from the base class
}
static void Main(string[] args)
{
//three tips over inheritance
//1. If you want to abstract some *behavior*, you probably want an interface:
//for example here, both dogs and robots can walk. They are going to do that
//on their own way, so each need their own proper implementation,
//but the actions is the same thus, the interface
// An interface is meant to group objects over shared functionality
//so for example I can later do something like this
var dog = new Dog();
var badDog = new BadDog();
var badRobot = new BadRobot(1);
// these function doesn't care if its a dog or a robot
void WalkOverThere(IWalkable walkable)
{
//some other code...
walkable.Walk(5, 10);
}
//The key here is that the object pass over parameter implements the IWalk interface
WalkOverThere(badDog);
WalkOverThere(badRobot);
//Please notice that for each class that inherits "IWalkable"
//There will be a new implementation, so in this case, if
//all the robots inherit from the class robot, all will walk the same way
//In that, I cannot extend, or modify how that method is performed in the base
//class from the child class
//2. Now, the case is different when we talk about some functionality that could change
//for any child implementation of the base class. Think about the breath functionality
//A robot can't breathe, but a dog does. And given that every dog breaths differently
//it makes sense to create and virtual method, that means that I can reconfigure how
//the breath method behaves. For example:
dog.Breath();
badDog.Breath();
//3. Another thing that is useful to take into account is that
//whenever I can't create a given object without some piece of information,
//it makes sense to create the necessity of that data in the constructor.
//take for example in this code that I cannot create a robot without a valid int robotId
//This practice enforces me to create a robot like:
//var robot = new Robot(100); where 100 is the id
//var robot = new Robot(); the compile would not allow that
}
}
}

A get or set accessor required with inheritance

I want to see is if the method bark will be overridden.
For some reason i am getting the error a get or set accessor required and another error when i try to call the method bark from main with a.bark.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace animals
{
class Animal
{
public void bark {
Console.WriteLine("woohhoo");
}
}
class dog : Animal
{
public void bark
{
Console.WriteLine("woof");
}
}
class Program
{
static void Main(string[] args)
{
Animal a = new Animal();
a.bark;
dog d = new dog();
d.bark;
}
}
}
You're missing the parenthesis on your method declarations:
Here: have a look at this fiddle
You should declare your method with () in C# and also call them using the parenthesis after the method name: a.bark();
class Animal
{
public void bark() {
Console.WriteLine("woohhoo");
}
}
class dog : Animal
{
public void bark()
{
Console.WriteLine("woof");
}
}
Call it like this:
public static void Main()
{
Animal a = new Animal();
a.bark();
dog d = new dog();
d.bark();
}
Also, no, the method will no override because in C#, if you want a derived type to override a method from the base class you must mark that method with virtual in the base and override it on the derived class.
Consider refactor your code like in this fiddle. Note that now you can create dog in an Animal variable and method is called correctly.
Animal d = new dog();
d.bark();
to override you need a virtual function. You also need brackets for functions. If you don't have brackets it thinks it's a property
which has the basic form :-
public void talk
{
get { return somevariable; }
set { somevariable = value}
}
which is why it's telling you it wants a get or set
Also calling it 'bark' is weird on Animal. So changing it a bit, what you want is something like :-
class Animal
{
public virtual void talk() {
Console.WriteLine("woohoo");
}
}
class dog : Animal
{
public override void talk()
{
Console.WriteLine("woof");
}
}
class Program
{
static void Main(string[] args)
{
Animal a = new Animal();
a.talk();
dog d = new dog();
d.talk();
// this part is key, when you have a dog as an animal, when you
// call talk it will use the overriden method. If you don't have
// virtual and override, then this would go "woohoo"
Animal da = d;
da.talk();
}
}
As mentioned in the comments, you need to have parenthesis after bark.
C# gives you a couple options in terms of overriding. Given the following main method.
static void Main(string[] args)
{
Animal a = new Animal();
a.bark();
dog d = new dog();
d.bark();
}
If you consider the following classes (Version A), this technique is called hiding. The dog's bark method hides Animal's. Notice the new keyword in front of the dog's bark method.
class Animal {
public void bark (){
Console.WriteLine("woohhoo");
}
}
class dog : Animal {
public new void bark() {
Console.WriteLine("woof");
}
}
output
woohhoo
woof
Now consider the following classes (Version B) where dog's bark method overrides animal's.
class Animal {
public virtual void bark (){
Console.WriteLine("woohhoo");
}
}
class dog : Animal {
public override void bark() {
Console.WriteLine("woof");
}
}
The output is the same. So what's the difference? Change the main method as follows and run the code with Version A and Version B.
static void Main(string[] args)
{
Animal a = new Animal();
a.bark();
Animal d = new dog();
d.bark();
}
Version A output
woohhoo
woohhoo
Version B output
woohhoo
woof

Passing instances of a class without knowing the Type

I want to know how to pass down instances of objects without knowing the Type that they are. I'd like to know this because if I have a 100 animal types, then I don't want to have a 100 if statements or a switch. I have provided a snippet, which is an example of what I want to basically achieve. Right now it obviously doesn't work where I put the comments at.
using System.IO;
using System;
using System.Collections.Generic;
class Program
{
Dictionary<string, dynamic> myAnimals = new Dictionary<string, dynamic>();
Program(){
myAnimals.Add("Maggie", new Dog("Maggie"));
myAnimals["Maggie"].bark();
myAnimals.Add("Whiskers", new Cat("Whiskers"));
myAnimals["Whiskers"].meow();
animalClinic clinic = new animalClinic();
clinic.cureAnimal(myAnimals["Whiskers"]);
}
static void Main()
{
new Program();
}
}
class Dog{
string name;
public Dog(string n){
name = n;
}
public void bark(){
Console.WriteLine("\"Woof Woof\" - " + name);
}
}
class Cat{
string name;
public Cat(string n){
name = n;
}
public void meow(){
Console.WriteLine("\"Meow Meow\" - " + name);
}
}
class animalClinic(){
public void cureAnimal(object animal){ //This is where I need some help.
if(animal.name == "Maggie"){ //I know I can use 'animal.GetType() == ...' That isn't the point.
Console.WriteLine("We heal fine dogs!"); //The point is to access various methods within the object.
}else{//I know it kind of beats the point of Type-Safety, but this is only an example and another way to do this is perfectly fine with me.
Console.WriteLine("Eww a cat!")
}
}
}
If anyone knows an alternative solution to this, then please go ahead and share!
Thanks.
EDIT: I think you'll also need to reference the animal instead of just passing it down.
This is what polymorphism is for:
public interface IAnimal
{
string name {get;set;}
void speak();
void cure();
}
public class Dog : IAnimal
{
public Dog (string n)
{
name = n;
}
public string name {get;set;}
public void bark()
{
Console.WriteLine("\"Woof Woof\" - " + name);
}
public void speak() { bark(); }
public void cure()
{
Console.WriteLine("We heal fine dogs!");
}
}
public class Cat : IAnimal
{
public Cat(string n)
{
name = n;
}
public string name {get;set;}
public void meow()
{
Console.WriteLine("\"Meow Meow\" - " + name);
}
public void speak() { meow(); }
public void cure()
{
Console.WriteLine("Eww a cat!");
}
}
class Program
{
static Dictionary<string, IAnimal> myAnimals = new Dictionary<string, IAnimal>();
static void Main()
{
myAnimals.Add("Maggie", new Dog("Maggie"));
myAnimals["Maggie"].speak();
myAnimals.Add("Whiskers", new Cat("Whiskers"));
myAnimals["Whiskers"].speak();
animalClinic clinic = new animalClinic();
clinic.cureAnimal(myAnimals["Whiskers"]);
}
}
public class animalClinic
{
public void cureAnimal(IAnimal animal)
{
animal.cure();
}
}
Create an interface (contains definitions for a group of related functionalities that a class or a struct can implement) called IAnimal which contains a Description property which returns "We heal fine dogs!" for your Dog class etc. Each of your concrete animal classes implement this interface meaning you can just call the Description property in your cureAnimal method.
Use polymorphism.
public abstract class Animal
{
public string Name { get; set; }
public abstract void Cure();
}
public class AnimalClinic
{
public void CureAnimal(Animal animal)
{
animal.Cure();
}
}
public class Dog : Animal
{
public override void Cure()
{
Console.WriteLine("We heal fine dogs!");
}
}
If you want to define the Cure logic inside of the AnimalClinic class like you do now, you might have to perform conditional execution of some sort.
This conditional execution does not have to be as unwieldy as a massive if statement or even a switch. You can research alterantive solutions to if statements here on SO. In fact, Joel Coehoorn has supplied one.
I believe the best option here is to use the strategy design pattern. Perfectly explained here http://www.dofactory.com/net/strategy-design-pattern
An example for your case is provided by ByteBlast and Joel Coehoorn's answers

new Keyword confusion

All -
Have read various articles on the new keyword and when it should be used:
MSDN - http://msdn.microsoft.com/en-us/library/6fawty39(v=vs.80).aspx
StackOverflow - benefit of using new keyword in derived class member having same name with base class member
Here is a sample code I have written to practice this concept
static void Main(string[] args)
{
Animal a2 = new Dog();
a2.Talk();
a2.Sing();
a2.Greet();
a2.Dance();
Console.ReadLine();
}
class Animal
{
public Animal()
{
Console.WriteLine("Animal constructor");
}
public void Talk()
{
Console.WriteLine("Animal is Talking");
}
public virtual void Sing()
{
Console.WriteLine("Animal is Singing");
}
public void Greet()
{
Console.WriteLine("Animal is Greeting");
}
public virtual void Dance()
{
Console.WriteLine("Animal is Dancing");
}
}
//Derived Class Dog from Animal
class Dog : Animal
{
public Dog()
{
Console.WriteLine("Dog Constructor");
}
public new void Talk()
{
Console.WriteLine("Dog is Talking");
}
public override void Sing()
{
//base.Sing();
Console.WriteLine("Dog is Singing");
}
public new void Dance()
{
Console.WriteLine("Dog is Dancing");
}
}
Any my output is coming as follows:
Whats confusing me is that by using the new keyword in the derieved class is actually showing an output of the base class. Isnt that wrong - isnt new keyword supposed to hide the base class membership so the result for Animal is Talking and Animal is Dancing should not be printed.
Thanks
The "new" means the method is "new" and not an "override". Therefore, if you call a method by that name from the base, it hasn't been overriden so the derived won't be called.
This was confusing to me as well but to put it simply:
The new keyword hides the child's member from the parent.

novice inheritance question

I don't understand why my output is not how I think it should be. I think that it should be Dog barks line break Cat meows. But there is nothing there.
Code:
namespace ConsoleApplication2
{
class Program
{
static void Main(string[] args)
{
Pets pet1 = new Dog();
Pets pet2 = new Cat();
pet1.Say();
pet2.Say();
Console.ReadKey();
}
}
class Pets
{
public void Say() { }
}
class Dog : Pets
{
new public void Say() { Console.WriteLine("Dog barks."); }
}
class Cat : Pets
{
new public void Say() { Console.WriteLine("Cat meows."); }
}
}
I have tried to go through the c# programming guide on MSDN but I find it very difficult to understand some of the examples on there. If someone could link to a good "inheritance for dummies" site, it would be much appreciated.
Make the Say function in your base class virtual and then override this function in your derived classes:
namespace ConsoleApplication2
{
class Program
{
static void Main(string[] args)
{
Pets pet1 = new Dog();
Pets pet2 = new Cat();
pet1.Say();
pet2.Say();
Console.ReadKey();
}
}
class Pets
{
public virtual void Say() {
Console.WriteLine("Pet makes generic noise");
}
}
class Dog : Pets
{
public override void Say() { Console.WriteLine("Dog barks."); }
}
class Cat : Pets
{
public override void Say() { Console.WriteLine("Cat meows."); }
}
}
The new modifier as you've written it:
class Dog : Pets
{
new public void Say() { Console.WriteLine("Dog barks."); }
}
essentially means that the Say method you've defined is only called when that instance is used as an instance of Dog.
So
Dog dog = new Dog();
dog.Say(); // barks (calls Dog.Say)
Pet pet = dog;
pet.Say(); // nothing (calls Pet.Say)
That explains why you received the results you have; for what you wanted, use virtual methods -- #fletcher's answer explains it well.

Categories

Resources