Как понять интерфейсы из фона Python - PullRequest
1 голос
/ 25 марта 2019

Я изо всех сил пытаюсь понять использование интерфейсов в C #. Это, вероятно, потому что я пришел из Python, и он там не используется.

Я не понимаю других объяснений, поскольку они не полностью отвечают на мои вопросы об интерфейсах. например Назначение интерфейсов продолжение

Из того, что я понимаю, интерфейсы говорят классу, что он может делать, а не как это делать. Это означает, что в какой-то момент классу нужно рассказать, как делать методы.

Если это так, какой смысл в интерфейсах? Почему бы просто не определить метод в классе?

Единственное преимущество, которое я вижу, это прояснить, что классы могут / не могут делать, но за счет не DRY-кода?

Я знаю, что Python не нуждается в интерфейсах, и я думаю, что это ограничивает мое понимание, но я не могу понять, почему.

Ответы [ 2 ]

1 голос
/ 25 марта 2019

Используется в python, в форме (обычно) абстрактных классов.

Цель варьируется, в Java они решают множественное наследование, в Python они действуют как контракт между 2 классами.

Класс A что-то делает, и часть этого что-то включает в себя класс B. Класс B может быть реализован несколькими способами, поэтому вместо создания 10 различных классов и НАДЕЖДЫ они будут использоваться должным образом, вы наследуете от абстрактного класса ( интерфейс), и вы должны убедиться, что они должны реализовать все методы, определенные как абстрактные. (ОБРАТИТЕ ВНИМАНИЕ, ЕСЛИ ОНИ НЕ РЕАЛИЗУЮТ ЛЮБОГО МЕТОДА, КОТОРЫЕ ОНА БУДЕТ РАСПРОСТРАНЯТЬСЯ ВО ВРЕМЯ СТРОИТЕЛЬСТВА, КОГДА ВЫ УСТАНАВЛИВАЕТЕ УПАКОВКУ, НЕ КОГДА ВЫ ЗАПУСКАЕТЕ ЭТО ОЧЕНЬ ВАЖНО В СРЕДНИХ / БОЛЬШИХ ПРОЕКТАХ).

Вы также знаете, что ЛЮБОЙ класс, который реализует эти методы, будет работать с классом, который его использует. Это звучит тривиально, но деловая сторона ЛЮБИТ это, потому что это означает, что вы можете передать часть своего кода на аутсорсинг, и он подключится и будет работать с остальным кодом.

Из того, что я понимаю, интерфейсы говорят классу, что он может делать, а не как это делать. Это означает, что в какой-то момент классу нужно рассказать, как делать методы.

Они на самом деле говорят ему, что он ДОЛЖЕН делать, о том, как они это делают, нам все равно.

Если это так, какой смысл в интерфейсах? Почему бы просто не определить метод в классе?

Дело не в этом, но да, абсолютно необходимо определение метода в классе, который наследуется от интерфейса.

Давайте приведем более конкретный пример.

Представьте, что у вас есть среда разработки Python, которая выполняет некоторые задачи. Задачи могут выполняться локально (на том же компьютере, на котором работает среда Python), они могут выполняться в распределенной системе, отправляя их в какой-то центральный планировщик, они могут выполняться в док-контейнере на веб-сервисах Amazon .... Вы поняли.

Все, что вам нужно, - это интерфейс (абстрактный класс в Python), который имеет метод run_task, в зависимости от того, какой из них вы используете.

например:

class Runner:
    __metaclass__ = abc.ABCMeta

    @abstractmethod
    def run_task(self, task_command):
         return


class LocalRunner(Runner):
    def run_task(self, task_command):
        subprocess.call(task_command)

class SlurmRunner(Runner):
    def run_task(self, task_command):
        subprocess.call('sbatch ' + task_command)

Теперь важный момент, как вы, возможно, спросите. Зачем мне все эти ^ $ ^ $%? осложнения? (вероятно, вы этого не сделаете, если проект yopur достаточно мал, но есть точка останова в зависимости от размера, когда вам почти НЕОБХОДИМО начать использовать эти вещи).

Класс, который использует ТОЛЬКО бегуна, должен понимать интерфейс, например у вас есть класс Task, этот класс может делегировать выполнение задачи TaskRunner, в зависимости от того, какая из них вам не нужна, они в некотором смысле полиморфны.

class Task:
    def __init__(self, task_runner):
        self.task_runner = task_runner
        self.task_command = 'ls'

    def run_this_task(self):
        self.task_runner.run_task(self.task_command)

И, если вы какой-то программист, ваш босс может сказать вам, мне нужен новый класс, который выполняет команды в AWS, вы присваиваете ему команду, и она реализует метод task_runner, тогда вам НЕ нужно знать НИЧЕГО об остальных код, вы можете реализовать этот бит как полностью изолированную часть (это часть аутсорсинга, теперь у вас может быть 100 человек, проектирующих 100 различных программ [т.е. им не нужно ничего знать о коде, только интерфейсы) .

0 голосов
/ 25 марта 2019
class Cat:
    def meow(self):
        print('meow')

def feed(cat):
    cat.moew()  # he thanks the owner

tom = Cat('Tom')
feed(tom)

C Sharp имеет статическую систему типов. Компилятор должен знать, какие методы имеет класс. Вот почему мы должны установить тип для каждой переменной:

def feed(cat: Cat):
    cat.moew()  # he thanks the owner

Но что если мы должны написать код и не знаем, какой именно тип должна иметь переменная?

def feed(it):
    it.thank_owner()

Кроме того, мы должны предположить, что наша функция будет использоваться для различных классов. Не забудьте, что мы должны сообщить компилятору тип каждой переменной! Что делать? Решение:

class Pet:  # an interface
    def thank_owner(self):
        raise NotImplementedError()

def feed(it: Pet):
    it.thank_owner()

Но что делать с Кэт? Решение:

class Cat(Pet):  # inherits the interface Pet
    def thank_owner(self):
        print('meow')  # or self.meow() if we want to avoid big changes and follow DRY rule at the same time

tom = Cat('Tom')
feed(tom)

Кстати, теперь мы можем легко добавлять новых питомцев. Нам не нужно переписывать наш код.

class Dog(Pet):
    def thank_owner(self):
        print('woof')

beethoven = Dog('Beethoven')
feed(beethoven)  # yes, I use the same function. I haven't changed it at all!

Обратите внимание, мы создали этот класс позже, чем feed() и Pet. Важно, что мы не думали о Dog при написании кода раньше. Нам не было интересно об этом. Однако у нас не было проблем с расширением кода.

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