How do I access the interface implementations from an object?
interface IGraphicsObject
{
Draw();
Delete();
}
I create 3 classes: Square, Circle and Triangle, all implementing IGraphicsObject. Then I do something like
object Shape = Activator.CreateInstance("myShapes", "Square");
Then I want to be able to type:
Shape.Draw();
Shape.Delete();
etc.
How do I do that?
Cast to IGraphicsObject
IGraphicsObject Shape = (IGraphicsObject)Activator.CreateInstance("myShapes", "Square");
With the created instance now, you can invoke the interface methods
Shape.Draw();
Shape.Delete();
The simple answer is to typecast it, but you can do it a bit better by:
public interface IGraphicsObject
{
void Draw();
void Delete();
}
public class Square : IGraphicsObject
{
public Square(string mysharpes, string square)
{
}
// fill out...
}
public class Circle : IGraphicsObject
{
public Circle(string mysharpes, string square)
{
}
// fill out...
}
public class Triangle : IGraphicsObject
{
public Triangle(string mysharpes, string square)
{
}
// fill out...
}
public class Main
{
public IGraphicsObject CreateInstance<T>(string mysharpes, string square) where T : IGraphicsObject
{
return (IGraphicsObject) Activator.CreateInstance(typeof(T), mysharpes, square);
}
public void Run()
{
var shape1 = CreateInstance<Square>("mysharpes", "square");
var shape2 = CreateInstance<Circle>("mysharpes", "square");
var shape3 = CreateInstance<Triangle>("mysharpes", "square");
Draw(shape1,shape2,shape3);
}
public void Draw( params IGraphicsObject[] shapes )
{
foreach( var shape in shapes )
shape.Draw();
}
}
So you ensure that only types that implement the interface is allowed for the typecasting creation method.
Related
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
}
}
}
I have to do a simple rpg game and there are 2 types of entities: heroes and monsters. Attack method will be implemented in both classes and it is contained by a interface called IAttack. The problem is that this method take a Monster type as parameter for hero class and a Hero type as parameter for monster class.
The code looks something like this:
The interface:
interface IAttack
{
void Attack(Object oponnnent);
}
The Hero class(which implements IAttack):
public void Attack(Monster opponent)
{
//code goes here
}
The Monster class(which implements IAttack):
public void Attack(Hero opponent)
{
//code goes here
}
The problem is I can not pass different types of arguments.
You could make an abstract class that Monster and Hero dervice from.
public abstract class PlayerType
{
public abstract int Health();
}
Then in your interface use the new abstract type:
interface IAttack
{
void Attack(PlayerType oponnnent);
}
Monster class:
public class Monster : PlayerType, IAttack
{
public override int Health()
{
return 100;
}
public void Attack(PlayerType hero)
{
}
}
Hero class:
public class Hero : PlayerType, IAttack
{
public override int Health()
{
return 500; // He is a hero afterall ;)
}
public void Attack(PlayerType monster)
{
}
}
Why not have two interfaces? Something that can attack and something that can be attacked?
public interface IAttackable
{
void OnAttacked(IAttacker attacker);
}
public interface IAttacker
{
void OnAttack(IAttackable opponet);
}
public class Hero : IAttacker, IAttackable
{
public void OnAttack(IAttackable opponet)
{
}
public void OnAttacked(IAttacker attacker)
{
}
}
public class Monster : IAttacker, IAttackable
{
public void OnAttack(IAttackable opponet)
{
}
public void OnAttacked(IAttacker attacker)
{
}
}
The code is simple enough to understand I hope.
I'm trying to use an interface type IColor in order to pass color objects to the ColorManager. I then want the ColorManager to pass this object to the IColor object as its own type, so the method overloads gets called.
However, it seems since it is being passed as the IColor type, C# will not implicity cast it into its complete type as either a BlueColor or GreenColor.
I hope this makes some sense to somebody on what I want to achieve. Is this possible in C#?
[Solution]
http://msdn.microsoft.com/en-us/library/dd264736.aspx
Overload Resolution with Arguments of Type dynamic
My code so far:
using System;
using System.Collections.Generic;
using System.Windows.Forms;
using System.IO;
namespace Example
{
public interface IColor
{
void CatchColor(IColor c);
}
public class BlueColor : IColor
{
public void CatchColor(IColor c)
{
}
}
public class GreenColor : IColor
{
public void CatchColor(BlueColor c)
{
Console.WriteLine("CAUGHT BLUE!");
}
public void CatchColor(GreenColor c)
{
Console.WriteLine("CAUGHT GREEN!");
}
public void CatchColor(IColor c)
{
Console.WriteLine("CAUGHT SOME COLOR!");
}
}
public class ColorManager
{
public void PassColor(IColor c)
{
// Don't use static type-checking
// Problem solved
dynamic AnyColor = c;
AnyColor.CatchColor(AnyColor);
}
public static void Main()
{
GreenColor G = new GreenColor();
new ColorManager().PassColor(G);
Console.ReadLine();
return;
}
}
}
One possiblity to tell the ColorManager class to use the correct type of the passed object is to use an abstract class, that already implements the CatchColor:
public abstract class IColor
{
// override in every class
public abstract void PrintColor();
// has the correct type passed with the interface
public void CatchColor(IColor c)
{
c.PrintColor();
}
}
Then the sub classes need to implement only PrintColor with the correct color:
public class BlueColor : IColor
{
public override void PrintColor()
{
Console.WriteLine("BLUE!");
}
}
public class GreenColor : IColor
{
public override void PrintColor()
{
Console.WriteLine("GREEN!");
}
}
The manager is the same:
public class ColorManager
{
public void PassColor(IColor c)
{
c.CatchColor(c);
}
}
It can be used like this:
GreenColor G = new GreenColor();
var cm = new ColorManager();
cm.PassColor(G);
cm.PassColor(new BlueColor());
The outputs is:
GREEN!
BLUE!
What you want is late method binding.
The downside to this is you have to add methods for each new type of color. The upside is you don't have to maintain a case statement or conditional logic.
See here for more detail:
Early and late binding
Edit: Here is a working example of this type of late-binding.
class Program {
static void Main(string[] args) {
//Declare instances
BaseClass myClass = new Class2();
BaseClass otherClass = new Class1();
//Invoke the action method which will match based on the BaseClass type
Action(myClass);
Action(otherClass);
Console.ReadLine();
}
public static void Action(BaseClass classType) {
//Remove the compile-time type so the runtime can select the method based on signature
dynamic aClass = classType;
ServiceMethod(aClass);
}
public static void ServiceMethod(dynamic input) {
Methods(input);
}
public static void Methods(Class1 classType) {
Console.WriteLine("Class1");
Debug.WriteLine("Class1");
}
public static void Methods(Class2 classtype) {
Console.WriteLine("Class2");
Debug.WriteLine("Class2");
}
public static void Methods(Class3 classType) {
Console.WriteLine("Class3");
Debug.WriteLine("Class3");
}
}
public abstract class BaseClass { //This could also be an interface
public Guid Id { get; set; }
public string Name { get; set; }
}
public class Class1 : BaseClass {
}
public class Class2 : BaseClass{
}
public class Class3 : BaseClass {
}
So you want something like:
public void CatchColor(Color c)
{
if (c is BlueColor)
CatchColor(c as BlueColor);
if (c is GreenColor)
CatchColor(c as GreenColor);
}
?
public abstract class State<T>
{
public virtual Enter(T item)
{
// an empty method
}
}
public class ChaseState : State<FieldPlayer>
{
public override Enter(Player pl)
{
// ...
pl.Fsm.CurrentState = ChaseState.Instance;
//...
}
}
public class TendGoal : State<Goalkeeper>
{
public override Enter(Goalkeeper gk)
{
// ...implementation
gk.Fsm.CurrentState = TendGoal.Instance;
// ...implementation
}
}
public class DefendState : State<Team>
{
public override Enter(Team team)
{
// ....
team.Fsm.CurrentState = DefendState.Instance;
//.....
}
}
"Goalkeeper" and "FieldPlayer" inherit from an abstract class "Player", while "Team" inherits from another class.
public class FSM
{
public /*some type*/ owner; // PROBLEM 1
// OWNER CAN BE TEAM, GOALKEEPEEPER
// OR FIELD PLAYER
public /*some type*/ globalState;
public /*some type*/ currentState;
public /*some type*/ previousState;
public void Update()
{
if (globalState != null)
{
globalState.Execute(owner); // PROBLEM 2
// IF GLOBAL STATE'S TYPE
// IS AN OBJECT, CANT CALL EXECUTE
// OBJECTS TYPE WILL BE KNOWN ONLY
// DURING RUNTIME
}
}
}
Each object of type "Goalkeeper", "FieldPlayer" and "Team" will have a State Machine instance. The problem is.. generics cant be properties.
What should I do ?
If you make State an ordinary interface, not generic, and have its Enter method take another interface that your teams, goalkeeprs, players, etc all implement (it can even just be empty), it ought to work.
public interface IOwner {}
public interface IState
{
void Enter(IOwner item);
}
public class ChaseState : IState
{
public void Enter(IOwner pl)
{
// ...
//...
}
}
public class Player :IOwner { }
public class Something {
IOwner owner = new Team();
IState globalState = new ChaseState();
IState currentState = new DefendState();
public void Update()
{
if (globalState != null)
{
globalState.Enter(owner);
}
else if (currentState != null)
{
currentState.Enter(owner);
}
}
}
After reading your code some more, an Abstract Class is unnecessary here. You should convert State to an interface, ex: IState and remove the generic signature from it. Then your properties in your FSM object can all be public IState globalState, etc..
I'd like to know if I follow the right path, because I feel that the following code is wrong. Sorry, I didn't know how to name properly this question.
I have a certain ShapeEntity class that is used for loading data from DB. There are other concrete classes for Shape (I can have many of them in the future) so I want to employ LSP to draw these shapes, that's why I use IShape abstraction. I instantiate concrete shape objects by using DB info which is provided by ShapeEntity.
So my concern lies inside Main() function where I create these Shapes just using simple if-else. Is this correct approach to create "unknown" objects using if-else block? Maybe I could carry out creation of Shape objects to some kind of ShapeService? How could it be solved the other way?
public class ShapeEntity
{
int idShape { get; set; }
}
public interface IShape
{
void Draw();
}
public class Square : IShape
{
public void Draw() { }
}
public class Rectangle : IShape
{
public void Draw() { }
}
public class Canvas()
{
public static void Main()
{
List<IShape> Shapes = new List<IShape>();
foreach(ShapeEntity ShapeItem in ShapeRepository.GetAll())
{
if(ShapeItem.idShape == 1)
{
Shapes.Add(new Square());
}
else if(ShapeItem.idShape == 2)
{
Shapes.Add(new Rectangle());
}
}
}
public void DrawShapesOnCanvas(IList<IShape> Shapes)
{
foreach(IShape Shape in Shapes)
{
Shape.Draw();
}
}
}
You should consider using Factory pattern and instead using Id you should use enum
Example:
public class ShapeFactory
{
public static IShape GetShape(ShapeType shapeType)
{
switch (shapeType)
{
case ShapeType.Square:
return new Square();
case ShapeType.Rectangle:
return new Rectangle();
default:
break;
}
return null;
}
}
public enum ShapeType
{
Square,
Rectangle
}