как я превращаю два класса в один - PullRequest
0 голосов
/ 05 августа 2010

привет, у меня есть два класса, например: ftp1 (обрабатывает обычные ftp-файлы), ftp2 (обрабатывает защищенные ftp-соединения и прочее).основываясь на настройке конфигурации, мне нужно создать экземпляр типа, который может быть одним из этих двух типов, в качестве переменной уровня класса.Возможно ли это, если да, может ли кто-то указать мне правильное направление.Я пытался применить полиморфизм в этой ситуации, но я немного запутался, как это сделать?

Ответы [ 5 ]

0 голосов
/ 05 августа 2010

Может быть, вы можете реализовать Factory Mehod Patther или простой метод Стратегии. Пожалуйста, взгляните на примеры кода на

Шаблон фабричного метода

Шаблон стратегии

Надеюсь, это поможет вам достичь своей цели.

С уважением

0 голосов
/ 05 августа 2010

Если два класса FTP являются частью стороннего фреймворка (и еще не реализуют общий базовый класс), у вас есть два варианта:

Обернуть классы в новый класс, который реализует общий базовый класс или интерфейс

//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();
    }
}

После того, как написаны оболочки, вы пишете новый код, используя классы оболочек.

Сохраните значения в переменной типа Object

Тип данных object является общей базой для всех классов. Ваш код будет выглядеть так:

public someclass {
    private object myVariable;
    private void somemethod() {
        if(something) {
            myVariable = new something();
        } else {
            myvariable = new something2();
        }
    }
}

Когда вы используете значение переменной, вам почти всегда нужно приводить его обратно к исходному типу.

if(something) {
    ((something)myVariable).InvokeMethod();
} else {
    ((something2)myVariable).InvokeMethod();
}
0 голосов
/ 05 августа 2010

Мне доступны два варианта, которые можно использовать в зависимости от ситуации:

  • BaseClass с InheritedClassess
    • Если ftp1 и ftp2 совместно используют общие функциональные возможности, но расширяют эти функциональные возможности уникальными способами, вы можете использовать базовый класс с несколькими реализующими подклассами. Таким образом, вы можете иметь другие свойства и методы в вашей программе, которые ожидают базовый класс и имеют доступ к общим свойствам.

.

public abstract class FtpBase {
    public string ConnectionInformation
    public int TimeoutSeconds
}

public class ftp1 : FtpBase {
    public void MakeConnectionToFTPServer() {...}
}

public class ftp2 : FtpBase {
    public void MakeSecureConnectionToFTPSever() {...}
}
  • Интерфейсы
    • Другой вариант - использовать интерфейсы, где вы определяете, что вы ожидаете от реализации классов. Вы все еще можете указать другим свойствам и методам ожидать интерфейс как параметр или тип свойства; до тех пор, пока переданный объект реализует интерфейс, он сможет работать. Код потребления не заботится о том, что это за объект, пока он реализует интерфейс.

.

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().
}

Если ожидается, что оба класса ftp будут иметь одинаковую функциональность с разными реализациями, я бы использовал interfaces. Однако, если у каждого класса ftp есть только некоторые из одних и тех же свойств и методов (где функциональность методов в каждой реализации одинакова), но расширяет общую функциональность однозначно между ними, вы можете использовать BaseClass with InheritedClasses , Вы также можете использовать комбинацию из двух, в зависимости от вашей ситуации.

0 голосов
/ 05 августа 2010

Помните, что интерфейсы определяют, что что-то делает, а реализация определяет, как оно это делает.

Итак, в вашем случае, определите интерфейс ftp, который определил действия, которые вы хотите - войти в систему, получить список файлов,помещение файла, получение файла, отключение и т. д.

Создание двух реализаций, одна для обычного ftp, другая для защищенного.Может оказаться полезным создать «базовую» реализацию ftp с общей обработкой, которая расширена двумя конкретными производными.

Итак, у вас есть:

ftp интерфейс - содержащий объявления методов для обеспечения функциональности

абстрактный класс baseftp - реализация интерфейса ftp, вызов определенных абстрактных методов для конкретных безопасных или незащищенных действий

конкретный класс secureftp - реализует абстрактные методы, определенные в baseftp для безопасного соединения

конкретный класс insecureftp - реализует абстрактные методы, определенные в baseftp для незащищенного соединения

0 голосов
/ 05 августа 2010

Вы можете достичь этого с помощью интерфейсов. С помощью следующего кода вам нужно заставить принимающий метод принимать экземпляр класса, который реализует 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 */
  }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...