hi i have two classes, example: ftp1 (handles normal ftp stuff), ftp2 (handles secure ftp connections, and stuff). based on a configuration setting I need to instantiate a type that can be one of these two types as a class level variable. Is this possible, if so, can someone point me in the right direction. I've tried to apply polymorphism to this situation, but I'm a little confused as to how to do that?
You can achieve this by using interfaces. With the following code you need to make the receiving method accept an instance of a class which implements iftp.
interface iftp {
string address;
int port;
void SomeMethod();
}
class ftp1 : iftp {
void SomeMethod() {
/* implement regular ftp logic */
}
}
class ftp2 : iftp {
void SomeMethod() {
/* implement secure ftp logic */
}
}
Two options stick out to me and which to use changes depending on the situation:
- BaseClass with InheritedClassess
- If
ftp1
andftp2
share common functionality but extend that functionality in unique ways, you could use a base class with several implementing subclasses. This way, you can have other properties and methods in your program that expect the base class and have access to common properties.
- If
.
public abstract class FtpBase {
public string ConnectionInformation
public int TimeoutSeconds
}
public class ftp1 : FtpBase {
public void MakeConnectionToFTPServer() {...}
}
public class ftp2 : FtpBase {
public void MakeSecureConnectionToFTPSever() {...}
}
- Interfaces
- Another option is to use interfaces, where you define what you expect the implementing classes to have. You can still tell other properties and methods to expect the interface as a parameter or property type; as long as the passed object implements the interface, it will be able to work. The consume code doesn't care what the object is as long as it implements the interface.
.
public interface IFtp {
public void MakeConnection()
}
public class ftp1 : IFtp {
public void MakeConnection (){...code to make a regular connection}
}
public class ftp2 : IFtp {
public void MakeConnection (){...code to make a secure connection}
}
//Then you might have in some other code:
public void ConnectViaFtp(IFtp ftp) {
ftp.MakeConnection() // the code doesn't know if this is ftp1 or
// ftp2. All it cares about is calling
// MakeConnection().
}
If both ftp classes are expected to have the same functionality with different implementations, I would use interfaces
. However, if each ftp class shares only some of the same properties and methods (where the functionality of the methods in each implementation is the same) but extends common functionality uniquely between the two, you might use BaseClass with InheritedClasses
. You can also use a combination of the two, depending on your situation.
Remember that interfaces define what something does, and implementation defines how it does it.
So, in your case, define an ftp interface that defined the actions you want - logging in, getting a file listing, putting a file getting a file, disconnecting etc.
The create two implementations, one for normal ftp, one for secure. You may find it useful to create a 'base' ftp implemtation with general processing that is extended by the two specific derivatives.
So you have:
ftp interface - containing method declarations for provided fuinctionality
baseftp abstract class - implementation of ftp interface, calling defined abstract methods for secure or non-secure specific actions
secureftp concrete class - implements abstract methods defined in baseftp for a secure connection
insecureftp concrete class - implements abstract methods defined in baseftp for a nonsecure connection
If the two FTP classes are part of a third-party framework (and do not already implement a common base class), you have two options:
Wrap the classes in a new class, which implements a common base class or interface
//Interface for original library classes.
public someClass {
public void DoSomething();
}
public someClass2 {
public void DoSomething();
}
//Wrapper implementation
public wrappedSomeClass : baseSomeClass {
private someClass mSomeClass;
public wrappedSomeClass() {
mSomeClass = new someClass();
}
//DoSomething will need to be defined in baseSomeClass
public overrides void DoSomething() {
mSomeClass.DoSomething();
}
}
public wrappedSomeClass2 : baseSomeClass {
private someClass2 mSomeClass2;
public wrappedSomeClass2() {
mSomeClass2 = new someClass2();
}
//DoSomething will need to be defined in baseSomeClass
public overrides void DoSomething() {
mSomeClass2.DoSomething();
}
}
Once the wrappers are written, you write your new code using the wrapper classes.
Store the values in a variable of type Object
The object
data type is the common base for all classes. Your code would look like this:
public someclass {
private object myVariable;
private void somemethod() {
if(something) {
myVariable = new something();
} else {
myvariable = new something2();
}
}
}
When you use the value of the variable, you will almost always need to cast it back to its original type.
if(something) {
((something)myVariable).InvokeMethod();
} else {
((something2)myVariable).InvokeMethod();
}
Maybe you can implement a Factory Mehod Patther or a simple Strategy method one. PLase take a look at this code examples at
Hope this helps you to achieve your goal.
regards