Understanding Interfaces

My first contact with interfaces was so bad that I forgot they even existed. This short tutorial aims to take a look at this concept demonstrate with an example.

Project can be downloaded here.

Some code might be slightly different from the project code due to subtle changes.

Maybe you have heard before “An Interface is a contract of functionality”, but what does that mean?

In C# there is not multiple inheritance, the solution for this problem is a layer of abstraction called an Interface. When we implement an interface in a class we are saying that the class will behave in a certain way.

Classes implementing interfaces allow us to call methods even if their inheritance tree is not directly connected.

Imagine a SpaceCar with an interface IFlyable which has the method Fly().

But now we have a Bird, and a he is IFlyable too, but a Bird is an Animal, on the other hand im pretty sure a SpaceCar isn’t.

The good thing is that we dont need to know what is what, Bird and SpaceCar both implement their Fly() method separately, maybe the car consumes 2x+ fuel when flying, maybe the bird stops singing when he flies.

If we have a list of IFlyable we just need to call Fly() and there it goes.

The example:

(For the sake of the tutorial lets assume a WaterPistol is a Gun and a Slingshot is not)

structure

The interface IShootable has 1 method that outputs damage to a target with 2 parameters, one for the target and an optional parameter attackModifier which is going to affect the damage.

Methods in interfaces are just declared but not implemented, this means they have no code whatsoever.

public interface IShootable
{
  string ShootAtTarget(ITargetable target, AttackModifierType attackModifier = AttackModifierType.None);
}

The interface ITargetable has a method that takes care of the damage with 3 parameters, the damageSource, the damageAmmount and an optional parameter for attackModifier.

public interface ITargetable
    {
        string TakeDamage(string damageSource, int damageAmmount, AttackModifierType attackModifier = AttackModifierType.None);
    }

Now that the interfaces are set, lets start with the Weapon class.

So the weapon is an abstract class, we wont instantiate it, it can be a melee weapon…a ranged wapon… etc.

(Note: Some properties may serve as demonstration only)

public abstract class Weapon
    {
        // Some properties may serve as demonstration only.

        public int Durability { get; set; }
        public int Damage { get; set; }
        public AttackModifierType AttackModifier { get; set; }
    }

The Gun class inherits from Weapon and it is too an abstract class.

public abstract class Gun : Weapon
 {
 // Some properties may serve as demonstration only.

 public int ShootSpeed { get; set; }
 public int Ammo { get; set; }
 public int Recoil { get; set; }
 }

So this far we have 2 Interfaces, IShootale and ITargetable.

We have 2 abstract classes, Weapon and Gun which inherits from the previous.

Lets build our weapons already!

Starting with a bazooka, it inherits from Gun and implements IShootable.

Implementing an Interface is pretty easy:

  1. Follow a Public class declaration (Bazooka) with a colon, then the abstract class (Gun) and the Interface (IShootable) separated by a comma.
  2. In your class declare all the interface methods as public.

So a bazooka shoots differently from a WaterPistol, maybe the bazooka gives the user some damage…. the ShootAtTarget(…) implementation is different in these two cases.

(The bazooca constructor sets the ShootSpeed and Damage hardcoded just for demo purposes )

 public class Bazooka : Gun, IShootable
 {
  public Bazooka()
  {
   ShootSpeed = 50;
   Damage = 100;
  }

  public string ShootAtTarget(ITargetable dummy, AttackModifierType attackModifier = AttackModifierType.None)
  {
    // Affect other properties here

    return dummy.TakeDamage(
    damageSource: 'Bazooka';,
    damageAmmount: Damage,
    attackModifier: AttackModifier);
  }
 }

Same old same old for the WaterPistol class.

 public class WaterPistol : Gun, IShootable
    {
        public WaterPistol()
        {
            ShootSpeed = 1;
            Damage = 1;
        }       

        public string ShootAtTarget(ITargetable dummy, AttackModifierType attackModifier = AttackModifierType.None)
        {
            // Affect other properties here

            return dummy.TakeDamage(
                damageSource: 'water pistol',
                damageAmmount: Damage,
                attackModifier: AttackModifier);
        }
    }

And the SlingShot

 public class SlingShot : Weapon, IShootable
    {
        public SlingShot()
        {
            Damage = 10;
        }

        public string ShootAtTarget(ITargetable dummy, AttackModifierType attackModifier = AttackModifierType.None)
        {
            // Affect other properties here            

            return dummy.TakeDamage(
                damageSource: 'slingshot',
                damageAmmount: Damage,
                attackModifier: AttackModifier);
        }
    }

Now the Target, lets create a PracticeDummy .

(Explanation below)

 public class PracticeDummy : ITargetable
    {
        // Number of ticks when taking damage
        int numberOfDamageTicksOverTime = 5;
        public PracticeDummy(int health)
        {
            Health = health;
        }

        public int Health { get; set; }

        public string TakeDamage(string damageSource, int damageAmmount, AttackModifierType attackModifier = AttackModifierType.None)
        {

            Health -= damageAmmount;

            Console.WriteLine(string.Format('ouch i took {0} damage from a {1}', damageAmmount, damageSource));
            Console.WriteLine(string.Format('now i have {0} health', Health));

            HandleDamageModifier(attackModifier);           

            if (Health == 0)
            {
                return ' XXX bye bye dummy XXX';
            }
            else
            {
                return 'dummy survived';
            }
        }

        void HandleDamageModifier(AttackModifierType attackModifier = AttackModifierType.None)
        {
            switch (attackModifier)
            {
                case AttackModifierType.None:
                    break;

                case AttackModifierType.Fire:
                    HandleFireModifier();
                    break;

                case AttackModifierType.Water:
                    Console.WriteLine('Water modifier not implemented');
                    break;

                case AttackModifierType.DuplicateDamage:
                    Console.WriteLine(';Water modifier not implemented');
                    break;

                default:
                    Console.WriteLine('error: invalid attack modifier');
                    break;
            }
        }

        void HandleFireModifier()
        {
            int fireDamage = 3;
            Console.ForegroundColor = ConsoleColor.Red;
            Console.WriteLine('FIRE ATTACK MODIFIER !! (burning)');

            Console.ResetColor();
            for (int tick = 0; tick < numberOfDamageTicksOverTime; tick++)
            {

                Console.WriteLine(string.Format(
                                    'burning inflicts {0} damage. Tick {1}/{2}',
                                    fireDamage,
                                    tick +1,
                                    numberOfDamageTicksOverTime));

                Health -= fireDamage;
            }
            Console.WriteLine(string.Format('now i have {0} health';, Health));
        }
    }

A practice dummy will TakeDamage() and modify its properties, the HandleDamageModifier() will see which type of modifier was added to the attack and act accordingly, for example  fire will burn the dummy for 3 damage over 5(numberOfDamageTicksOverTime) ticks.

As for the main Program.

 public enum AttackModifierType
    {
        None,
        Fire,
        Water,
        DuplicateDamage
    }

    class Program
    {
        static void Main(string[] args)
        {

            // create my shootables
            var b1 = new Bazooka();

            var w1 = new WaterPistol();

            var s1 = new SlingShot();
            // set the attackmodifier of the sligshot 1 to fire.
            s1.AttackModifier = AttackModifierType.Fire;

             IEnumerable shootableCollection = new List<IShootable> { b1, w1, s1 };

            foreach (var shootable in shootableCollection )
            {
                // Create a new dummy for every gun
                // otherwise we would be shooting the same dummy with all those guns....poor dummy
                PracticeDummy dummy = new PracticeDummy(health: 100);

                Console.WriteLine(shootable.ShootAtTarget(dummy));

                Console.WriteLine('-------------------------------------------------');

            }
                Console.ReadLine();
        }
    }

We declare our enum AttackModifier.

And in Main, we create our “IShootables”and add a Fire AttackModifier to the slingshot.

Then we create an IEnumerable of type IShootalble passing the weapons we just created.

And at last, for each IShootable in the list, we create a new PracticeDummy and shoot him with whatever weapon/shootable is in that list.

Console output:

console-output

And thats it, hope you found this helpfull in some way.

Thanks for reading!

Html Helpers

Html helpers are like functions/methods, they are pretty easy to create and very useful.

Helpers can be created in a complete different view called “HtmlHelpers.cshtml” for example. But for the sake of this post ill add it to my  current view.

<h1>Helper view</h1>
@helper MyCustomHelper(string name, string place) {
<div>
-------------------------------------------****------------------------------------------
Hi <span style="background-color:#dddbdb">@name</span> !
Welcome to : <span style="background-color:#dddbdb">@place</span>
-------------------------------------------****------------------------------------------</div>
}

@MyCustomHelper(name:"Dev" , place: "public string notes")

“MyCustomHelper” its pretty self explanatory, it has 2 string which can be used witht the usual “@”.

The result:

helperView

Now if you need to clone this block, just call the method and send another string as param, no need to write more code. Keep it DRY.

 

The “UIHint” Decorator

Today’s discover was a handy csharp decorator, the “UIHint”.

uihtin

The string is the name of the template that we want to call.

Next in our view we call the displayFor and we pass the Color property.

view

Looking good, but we still need to call our template. So we create a folder called “DisplayTemplates” and inside we add a new View with the same name as the string in our decorator, in this case “ColorTemplate”.

folders

And finally inside our template view we just need to say what we want.

for example ,use the properties of our model to pass as arguments to the style of our div.

view2

 

End