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
}
}
}
Related
I'm having a base class defined in my app
Something like,
using System;
public class BaseClass
{
public virtual void Method2() {Console.WriteLine("base2");}
public virtual void Method1() {Console.WriteLine("base1");}
}
public class Derived1 : BaseClass
{
public override void Method2() {Console.WriteLine("derived1-2");}
public override void Method1() {Console.WriteLine("derived1-1");}
}
public class Derived2 : Derived1
{
public override void Method1() {Console.WriteLine("derived2-2");}
}
public class Program
{
public static void Main()
{
var obj = new Derived2();
((BaseClass)obj).Method2();
Console.WriteLine("Hello World");
}
}
Say I need to access the Method2() of my very first BaseClass. Even after typecasting it to ((BaseClass)obj).Method2(), I'm still getting derived1-2 while I'm expecting base2'.
How do I do that ?
I completely agree with the comments: it sounds like the behaviour that you require would need you to re-think your classes - possibly inheritance is not the best solution in this case. It depends what you're trying to do; you could obviously just do this:
var obj = new BaseClass();
((BaseClass)obj).Method2();
Console.WriteLine("Hello World");
My guess would be that what you actually want here is some form of injection; for example:
public class BaseClass
{
private readonly IFunctionality1 functionality1;
public virtual void Method2() { Console.WriteLine("base2"); }
public virtual void Method1() { this.functionality1.Method1(); }
public BaseClass(IFunctionality1 functionality1)
{
this.functionality1 = functionality1;
}
}
public class Derived1 : BaseClass
{
public Derived1(IFunctionality1 functionality1) : base (functionality1)
{
}
}
In this case, you might find that inheritance isn't even required anymore.
Hi everyone I am programming in Unity3d with C# and while I was writing my code I stumbled with a little issue, I write to you an example because I dont know explain me.
class Base
{
public string name;
}
class Derived : Base
{
public void Gun();
}
class BasePlayer
{
public Base x;
}
class SoldierPlayer : BasePlayer
{
}
The situation is this, I want to do something like that
SoldierPlayer.x.Gun();
But I don't know how do it
The real case is this
public class BasePlayerController : MonoBehaviour
{
public BasePlayerManager playerManager;
...
public class RobotPlayerController : BasePlayerController {
...
playerManager = gameObject.AddComponent<RobotPlayerManager>();
And I will use new methods
UPDATE 1
I did a example better, I want to do in Base Controller manager.user.energy and be treated as the next type RobotManager.RobotUser.energy
BaseController
BaseManager
BaseUser
class BaseController
{
BaseManager manager;
public virtual void Move(int x,int y)...
}
class BaseManager {
BaseUser user;
public virtual Pause(bool state);
}
class BaseUser {
int life
}
RobotController
RobotManager
RobotUser
class RobotController : BaseController
{
// manager as RobotManager?
public void Ray(int x,int y);
}
class RobotManager : BaseManager
{
// user as RobotUser?
}
class RobotUser : BaseUser
{
int energy;
}
UPDATE 2
I seek to do this
public Run()
{
RobotController rc = new RobotController();
rc.manager.energy;
}
You can't call SoldierPlayer.x.Gun(); because SoldierPlayer.x has type Base which has not method Gun(). OOP world and C# can provide you many solutions, your choose depends on your goals.
some of them (order by best practise):
1) Overriding Polymorphism. Add .Gun() method to Base class and implemend it in derived classes. For example
class Base
{
public string name;
public void virtual Gun()
{
Trace.Log("I'm base class, i can't do anything");
}
}
class Derived : Base
{
public override void Gun()
{
Consule.WriteLine("Hello i have gun");
}
}
class Derived2 : Base
{
public override void Gun()
{
Consule.WriteLine("Hello i have 2 guns");
}
}
2) Overloading Polymorphism In many source this method is mentioned like some kind of polymorphism AD-HOC
public void GunAction(Derived2 o)
{
o.Gun();
}
public void GunAction(Derived1 o)
{
o.Gun();
}
public void GunAction(Base o)
{
Trace.Log("I'm base class, i can't do anything");
}
3) is-cast
public void GunAction(Base o)
{
if(o is Derived1 )
o.Gun();
if(o is Derived2 )
o.Gun();
}
UPDATE 1 answering to your new requirements
class BaseController
{
public BaseManager manager;
...
class RobotController1 : BaseController
{
// manager as RobotManager? - no it is stil BaseManager
public void Ray(int x,int y);
}
class RobotController2 : BaseController
{
// manager as RobotManager? - yes. now it is RobotManager
public void Ray(int x,int y);
public RobotController2()
{
manager = new RobotManager();
}
}
public void Run()
{
var controller = new RobotController2();// you have RobotManager
controller.manager = new BaseManager();// it is again BaseManager
}
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)
{
}
}
I have ElectricCar and DieselCar classes which inherits from Vehicle.
They have ElectricEngine and DieselEngine respectively.
Both engine classes have the Start method. Originally I implemented the StartAllEngines() in both car subclasses, but I found it highly repetitive, so I want to abstract it in the base vehicle class.
The problem is, how do I define the type of engines in the base class? dynamic is an option but I dont feel very safe using it.
Or I should not abstract the method? But then it violates the DRY principle.
public class Vehicle{
protected List<???Engine> engines; // What should be the type?
public void StartAllEngines (){
foreach (???Engine engine in this.engines){
engine.Start();
}
}
}
public class ElectricCar: Vehicle{
public ElectricCar(){
this.engines = List<ElectricEngine>();
}
}
public class DieselCar: Vehicle{
public DieselCar(){
this.engines = List<DieselEngine>();
}
}
public class ElectricEngine: Engine {...}
public class DieselEngine: Engine {...}
Use a generic parameter in the base class w/ Engine as the constraint:
public class Vehicle<TEngine> where TEngine: Engine
{
protected List<TEngine> engines = new List<TEngine>();
public void StartAllEngines (){
foreach (TEngine engine in this.engines){
engine.Start();
}
}
}
public class ElectricCar: Vehicle<ElectricEngine>
{
public ElectricCar(){
}
}
public class DieselCar: Vehicle<DieselEngine>
{
public DieselCar(){
}
}
public class ElectricEngine: Engine {...}
public class DieselEngine: Engine {...}
As Plutonix said, strange having a list of engines in a base class, makes no sense
public class Vehicle{
protected Engine engine;
public void Start (){
engine.Start();
}
}
public class ElectricCar : Vehicle
{
public ElectricCar(){
engine = new ElectricEngine();
}
public void Start()
{
}
}
public class DieselCar: Vehicle
{
public DieselCar(){
engine = new DieselEngine();
}
}
public class ElectricEngine : Engine
{
public override void Start()
{
//Start Electric Engine
}
}
public class DieselEngine: Engine {
public override void Start()
{
//Start Diesel Engine
}
}
public abstract class Engine
{
//Alternatively use virtual, depending on what you want to achieve...
public abstract void Start();
}
You could have an IEngine interface that exposes a Start method that is then inherited by ElectricEngine and DieselEngine
Eg.
public interface IEngine
{
void Start();
}
public class ElectricEngine : IEngine {
public void Start()
{
// start code
}
}
public class Vehicle{
protected List<IEngine> engines;
public void StartAllEngines (){
foreach (IEngine engine in this.engines){
engine.Start();
}
}
}
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