Reputation: 5649
I have to implement classes to transfer files to USB (class USBTransfer
) and over FTP (class FTPTransfer
). Since both the classes use some common methods (like getting the filename, reading some parameters etc.) so, I have implemented those methods in an another class (class FileOperations
). I have inherited both the classes (i.e. class USBTransfer
and class FTPTransfer
) from the class FileOperations
.
class FileOperations
{
protected void CommonMethod1();
protected void CommonMethod2();
}
class USBTransfer : FileOperations
{
}
class FTPTransfer : FileOperations
{
}
PROBLEM: During the file transfer operations, I set different states (not using the state machine design pattern though). I want to use a ABSTRACT class for this purpose with the following structure.
abstract class FileTransferStateMachine
{
//Public
public enum FileTransferStates { Idle = 0, FileCopyingState = 1, SuccessfullyCopiedState = 2 }
public static FileTransferStates CurrentState = FileTransferStates.Idle;
abstract protected void IdleState();
abstract protected void FileCopyingState();
abstract protected void SuccessfullyCopiedState();
}
But in C# it is not allowed to have multiple inheritance.
QUESTION: I know that I can use interface. But you cannot have variables and in that case both of my classes (i.e. class USBTransfer
and class FTPTransfer
) will have their own variables for the following
public enum FileTransferStates { Idle = 0, FileCopyingState = 1, SuccessfullyCopiedState = 2 }
public static FileTransferStates CurrentState = FileTransferStates.Idle;
I want to reduce redundancy and want to force to have same variables/methods (hmm...same methods can be achieved by interface) for the state machine.
Question PART-2: I can transfer files to USB or FTP as mentioned above but both the transfer operations have some common states like IdleState
, FileCopyingState
or SuccessfullyCopiedState
which have their corresponding methods (i.e. IdleState()
, FileCopyingState()
or SuccessfullyCopiedState()
). I want to FORCE both the classes to implement these methods (i.e. IdleState()
, FileCopyingState()
or SuccessfullyCopiedState()
). If any class forgets to implement any method then, I should get a compiler error. Basically, the FileTransferStateMachine
should be an interface/abstract class whose methods should be overridden in USBTransfer
and FTPTransfer
classes (which are already inheriting another class called FileOperations
).
Upvotes: 0
Views: 1295
Reputation: 273229
Use composition (and avoid static
state members) :
abstract class FileOperations
{
protected void CommonMethod1();
protected void CommonMethod2();
protected FileTransferStateMachine Statemachine { get; set; }
}
Edit, regarding Part 2:
When you want to force the concrete classes to implement each of those methods then an interface IFileTransferStateMachine
is exactly right.
You could also derive FileOperations from the StateMachine:
abstract class FileOperations: FileTransferStateMachine { }
but I would use an interface, it can be applied more granular.
Upvotes: 3
Reputation: 6975
Addressing both of the parts you say are a problem:
FileTransferStates
can be moved out of the class, placed directly in the namespace (probably in its own file). Then it can be used by both implementations without being redefined
CurrentState
can be made a non-static property (not field). Properties can be put on an interface, so they don't need an abstract class. Properties are highly recommended over fields for public members anyway, and as others have said, static isn't appropriate here.
As others have mentioned, another option is to use one of these two classes as a dependency instead of a base class. I.e. using composition instead of inheritance.
Upvotes: 0