Question

I'm very new to c# and I'm practicing with polymorphism. What I want to do is have a device be one of 3 class types (Joystick, Mouse or Keyboard). I figure the best approach is to use a class and virtual. Having troubles with the layout here?

namespace HID
{
    public class HIDControl
    {
.
.
.
    class agnosticDevice
    {
        private Joystick jDevice;
        private Mouse jMouse;
        private Keyboard jKeyboard;
        public string type;

        public virtual void device()// no way to return different types?
        {
            //if type is mouse return jMouse...ect?
        }
    }
.
.
.
    }
}

Just not understanding how to do this right or maybe I'm way off. can anyone help?

Further info, I'm using DX here and maybe there is provision for this but I dont see how. Basically in my HIDControl class I set up the DX and create a device based on user input. This input could later change and I need to changed my device. All of the devices for the most part use the same functions. As a matter a fact everything can be treated as a Joystick. Though for some advanced function I need the type changed. I know I could do class level polymorphism but so much of the classes would be redundant.

The other immediate solution is just make 3 devices in my class but if I do this I need 3 if statements for every use and that is just ugly.

[ updated code to comment on the comments and suggestions ]

I think I'm getting close here but when I create my device its not inheriting the members right. Here is what I have so far

public abstract class AgnosticDevice
    {
        public abstract void SomeDeviceOperation();
    }

    public class vJoystick : AgnosticDevice, Joystick
    {
        public vJoystick( DirectInput di, Guid g){}
        public override void SomeDeviceOperation()
        {
            /* Joystick operation */
        }
    }

    public class vMouse : AgnosticDevice, Mouse
    {
        public vMouse( DirectInput di ){}
        public override void SomeDeviceOperation()
        {
            /* Mouse operation */
        }
    }

    public class vKeyboard : AgnosticDevice, Keyboard
    {
        public vKeyboard( DirectInput di , Guid g){}
        public override void SomeDeviceOperation()
        {
            /* Keyboard operation */
        }
    }

    public class DeviceFactory
    {
        public static AgnosticDevice Create( string type, DirectInput di, Guid g )
        {
            if ( type == "Mouse" )
            {
                return new vMouse( di);
            }
            if ( type == "Joystick" )
            {
                return new vJoystick( di, g);
            }
            if ( type == "Keyboard" )
            {
                return new vKeyboard( di, g);
            }
            return new vJoystick( di, g );//defult
        }
    }

then I do

AgnosticDevice device = (vJoystick)DeviceFactory.Create( type, directInput, deviceGuid );

but device.( some DX function ) is not available.

No correct solution

OTHER TIPS

What you need here is an interface. Something that defines the common functionality between these various input devices. You can then have each of these classes implement that interface to perform those various actions in whatever specific manor they need to.

Here is something that might give you an idea:

Create an interface or an abstract class and define the functionality that will be shared between all your "devices":

public abstract class AgnosticDevice
{
    // methods ...
    public virtual void DoStuff()
    {
        // something
    }
}

Then use it for your more specific devices:

public class Joystick : AgnosticDevice
{
    // perhaps overwrite DoStuff here ...
}

public class Mouse : AgnosticDevice
{

}

Here is how you can use this (this is essentially polymorphism):

public class DeviceFactory
{
    public static AgnosticDevice Create(string someInput)
    {
        if (someInput == "something")
        {
            return new Mouse();
        }
        return new Joystick();
    }
}

In case you want to specify a behavior that each agnostic device must have you're better off creating an interface (it can have NO implementation), for example:

public interface IPluggable
{
    void Disconnect();
}

Then implement it in one of your "pluggable" devices:

public class Joystick : IPluggable
{
    public void Disconnect()
    {
        // awesome
    }
}

See from here on you can do magic such as:

// I want you to pass me a pluggable device, I don't care if it's a Joystick or a Mouse
public static void DoWork(IPluggable pluggableDevice)
{
    try
    {
        // something will go wrong !
    }
    catch (Exception ex)
    {
        LogException(ex);

        // all pluggable devices can disconnect, I don't care what you've passed as an argument!
        pluggableDevice.Disconnect();
    }
}

This is how you can use that:

public void Test()
{
    DoWork(new Joystick());
    DoWork(new Mouse());

    // you can do some tests by throwing in a fake device
    // to simulate behaviors that you expect
    DoWork(new FakeDevice());
}

What you are doing is composition, not polymorphism. You can achieve polymorphism by having one abstract Device class and three specialization:

public abstract class Device
{
    public abstract void SomeDeviceOperation();
}

public class Joystick : Device
{
    public override void SomeDeviceOperation()
    {
        /* Joystick operation */
    }
}

public class Mouse : Device
{
    public override void SomeDeviceOperation()
    {
        /* Mouse operation */
    }
}

public class Keyboard : Device
{
    public override void SomeDeviceOperation()
    {
        /* Keyboard operation */
    }
}

You can then assign any class subclassing Device to a Device typed variable, argument, parameter, etc.. For example:

public void DoOperationOnDevice(Device d)
{
    d.SomeDeviceOperation();
}

Device d = new Joystick();
d.SomeDeviceOperation();
DoOperationOnDevice(new Keyboard());
d = new Mouse();
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top