Как реализовать интерфейс, используя член класса?

1

У меня есть этот класс собак:

public class Dog : IBarkable
{
      public void Bark()
      {
            Console.WriteLine("Woof!");
      }
}

и у меня есть этот человеческий класс:

public class Human : IBarkable
{
      private Dog _myDog = new Dog();

      public void Bark()
      {
            _myDog.Bark();
      }
}

Есть ли способ, которым я не буду выполнять каждую функцию явно? что-то вроде этого:

public class Human : IBarkable (_myDog)
{
      private Dog _myDog = new Dog();
}

благодарю!

  • 1
    Отсутствует автоматическое делегирование реализации интерфейса, это одна из причин (если не основной), почему «сложение по наследованию» иногда бывает болезненным. Вы должны сделать это вручную.
  • 8
    Это сильный признак того, что Human не должен реализовывать IBarkable и вместо этого он должен иметь метод / свойство, которое возвращает объект IBarkable (в данном случае это собака).
Показать ещё 4 комментария
Теги:
interface

3 ответа

1
Лучший ответ

Хотя для реализации делегирования элементов в визуальной студии нет никаких функций, resharper предоставляет один.

Вы ищете Генерирование делегирующих членов resharper.

1

С логической точки зрения человек не может лаять. Так что вывод человека из этого интерфейса не имеет смысла. Вместо этого вы должны предоставить хотя бы метод getter, возвращающий ваш объект собаки.

  • 0
    И почему он должен нарушать Закон Деметры, поступая так, как вы предлагаете?
0

Если вы пытаетесь разоблачить "питомец" человека, более гибким и технически правильным способом было бы абстрагирование метода Барка и заставить человека выставить определенные аспекты "домашнего животного". Что касается дизайна API, то это не очень интуитивно, чтобы иметь метод "Bark" на человеческом объекте. Также рассмотреть: что, если человек, как кошка, попугай, обезьяна и слон для домашних животных? В этом случае ваш код, поскольку его становится трудно поддерживать (я подозреваю, поэтому вы хотите "автоматизировать" методы интерфейса).

Я бы предложил небольшой рефакторинг вашего кода в нечто подобное:

public interface ISpeakingAnimal {

    void Speak();

} // end interface IAnimal

public interface IHasPets {

    List<ISpeakingAnimal> Pets {get; set;}

    bool HasPets();

} // end interface IHasPets

public class Dog : ISpeakingAnimal {

    public void Speak() {
        Console.WriteLine("Woof");
    }
} // end class Dog

public class Cat : ISpeakingAnimal {

    public void Speak() {
        Console.WriteLine("Meow");
    }
} // end class Cat

public class Human : IHasPets {

    public Human() {
        Name = "The Doctor";
        Pets = new List<ISpeakingAnimal>();
    } // end constructor

    public string Name {get; set;}

    public List<ISpeakingAnimal> Pets {get; set;}

    public bool HasPets() {
      return Pets.Any();
    } // end method HasPets

} // end class Human

//Somewhere in your executing code
Human person1 = new Human();
ISpeakingAnimal dog = new Dog();
ISpeakingAnimal cat = new Cat();
person1.Pets.Add(dog);
person1.Pets.Add(cat);

for(int i = 0; i<person1.Pets.Count; i++) {
    person1.Pets[i].Speak();
} // end for loop

Это объединяет несколько методов разработки ПО SOLID, которые вы можете прочитать здесь, если вам интересно: http://www.blackwasp.co.uk/SOLID.aspx

Эта конструкция позволяет добавлять новые типы домашних животных в любой момент без внесения изменений в человека или других животных. и вы можете добавлять методы к человеку, чтобы взаимодействовать с ним домашними животными, не изменяя фактическую природу того, что есть у человека (так как мы обычно не лаем;)).

Ещё вопросы

Сообщество Overcoder
Наверх
Меню