Реализация немногих методов интерфейса class-C#

Swift 3 или 4

Если вы не заботитесь о [заказах], используйте ответ @ paulvs , он отлично работает.

else на всякий случай, если кто-то хочет получить результат в порядке, а не стрелять одновременно, здесь - это код.

let dispatchGroup = DispatchGroup()
let dispatchQueue = DispatchQueue(label: "taskQueue")
let dispatchSemaphore = DispatchSemaphore(value: 0)

dispatchQueue.async {

    // use array categories as an example.
    for c in self.categories {

        if let id = c.categoryId {

            dispatchGroup.enter()

            self.downloadProductsByCategory(categoryId: id) { success, data in

                if success, let products = data {

                    self.products.append(products)
                }

                dispatchSemaphore.signal()
                dispatchGroup.leave()
            }

            dispatchSemaphore.wait()
        }
    }
}

dispatchGroup.notify(queue: dispatchQueue) {

    DispatchQueue.main.async {

        self.refreshOrderTable { _ in

            self.productCollectionView.reloadData()
        }
    }
}

25
задан Jankhana 27 April 2010 в 13:30
поделиться

10 ответов

Вы можете сделать его абстрактным классом и добавить методы, которые вы не хотите реализовывать, как абстрактные методы.

Другими словами:

public interface IMyInterface
{
    void SomeMethod();
    void SomeOtherMethod();
}

public abstract class MyClass : IMyInterface
{
    // Really implementing this
    public void SomeMethod()
    {
        // ...
    }

    // Derived class must implement this
    public abstract void SomeOtherMethod();
}

Если все эти классы должны быть конкретными, а не абстрактными, тогда вам придется выбросить исключение NotImplementedException / NotSupportedException изнутри методов. Но гораздо лучше было бы разделить интерфейс, чтобы классы реализации не делали этого.

Имейте в виду, что классы могут реализовывать несколько интерфейсов, поэтому, если некоторые классы обладают некоторыми функциями, но не всеми, тогда вы захотите иметь более детализированные интерфейсы:

public interface IFoo
{
    void FooMethod();
}

public interface IBar()
{
    void BarMethod();
}

public class SmallClass : IFoo
{
    public void FooMethod() { ... }
}

public class BigClass : IFoo, IBar
{
    public void FooMethod() { ... }
    public void BarMethod() { ... }
}

Вероятно, это тот дизайн, который вам действительно нужен.

26
ответ дан 28 November 2019 в 18:31
поделиться

Это невозможно. Но вы можете бросить NotSupportedException или NotImplementedException для методов, которые вы не хотите реализовывать. Или вы можете использовать абстрактный класс вместо интерфейса. Таким образом, вы можете обеспечить реализацию по умолчанию для методов, которые вы не хотите переопределять.

public interface IMyInterface
{
  void Foo();

  void Bar();
}

public class MyClass : IMyInterface
{
  public void Foo()
  {
    Console.WriteLine("Foo");
  }

  public void Bar()
  {
    throw new NotSupportedException();
  }
}

Или ...

public abstract class MyBaseClass
{
  public virtual void Foo()
  {
    Console.WriteLine("MyBaseClass.Foo");
  }

  public virtual void Bar()
  {
    throw new NotImplementedException();
  }
}

public class MyClass : MyBaseClass
{
  public override void Foo()
  {
    Console.WriteLine("MyClass.Foo");
  }
}
5
ответ дан Brian Gideon 28 November 2019 в 18:31
поделиться

Вот простой глупый пример того, что я имел в виду под разными интерфейсами для разных целей. Нет интерфейса для общих свойств, поскольку это усложнит пример. Также этому коду не хватает многих других полезных вещей (например, макета приостановки), чтобы сделать его более понятным. Я не пытался скомпилировать этот код, поэтому может быть много опечаток, но я надеюсь, что идея ясна.

interface IConfigurableVisibilityControl
{
    //check box that controls whether current control is visible
    CheckBox VisibleCheckBox {get;}
}


class MySuperDuperUserControl : UserControl, IConfigurableVisibilityControl
{
    private readonly CheckBox _visibleCheckBox = new CheckBox();

    public CheckBox VisibleCheckBox 
    {
        get { return _visibleCheckBox; }
    }
    //other important stuff
}

//somewhere else
void BuildSomeUi(Form f, ICollection<UserControl> controls)
{
    //Add "configuration" controls to special panel somewhere on the form
    Panel configurationPanel = new Panel();
    Panel mainPanel = new Panel();
    //do some other lay out stuff
    f.Add(configurationPanel);
    f.Add(mainPanel);

    foreach(UserControl c in controls) 
    {
        //check whether control is configurable
        IConfigurableOptionalControl configurableControl = c as IConfigurableVisibilityControl;
        if(null != configurableControl) 
        {
            CheckBox visibleConfigCB = configurableControl.VisibleCheckBox;
            //do some other lay out stuff
            configurationPanel.Add(visibleConfigCB);
        }
        //do some other lay out stuff
        mainPanel.Add(c);
    }
}
1
ответ дан SergGr 28 November 2019 в 18:31
поделиться

Я хочу динамически добавить элемент управления в мою форму, поскольку у меня есть это как мое требование. Я нашел код из здесь . Я отредактировал это, как мне было нужно. Итак, у меня есть класс IService, который имеет общие свойства. Это реализовано пользовательскими элементами управления. Которые показываются во время выполнения в другом проекте. Хм, для этого у меня есть другой общий интерфейс, который имеет свойства, которые используются проектом для отображения элементов управления. Немногим элементам управления требуются дополнительные методы или функции, например, для реализации контекстного меню, основанного на выборе пользователя во время выполнения. т.е. в проекте есть значения, которые будут переданы в качестве свойств элементу управления, и он будет отображен. Теперь это меню доступно только для одного элемента управления, остальные не имеют этого. Поэтому я подумал, есть ли способ не использовать эти методы во всех классах, а не в одном классе. Но звучит так, что мне нужно либо использовать фиктивные методы, либо абстрактный класс. хм, фиктивные методы были бы более предпочтительны для меня, чем абстрактный класс: - (

0
ответ дан Jankhana 28 November 2019 в 18:31
поделиться

Помимо вышеупомянутых отличных предложений по проектированию интерфейсов, если вам действительно необходимо реализовать некоторые методы, можно использовать «методы расширения». Переместите методы, которые требуют реализации, за пределы вашего интерфейса. Создайте другой статический класс, который реализует их как статические методы с первым параметром как this interfaceObject. Это похоже на методы расширения, используемые в LINQ для интерфейса IEnumerable.

public static class myExtension {
    public static void myMethod( this ImyInterface obj, ... ) { .. }
...
}
0
ответ дан shr 28 November 2019 в 18:31
поделиться

Вы нарушаете использование интерфейсов. У вас должен быть отдельный интерфейс для каждого обычного поведения.

18
ответ дан 28 November 2019 в 18:31
поделиться

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

1
ответ дан 28 November 2019 в 18:31
поделиться

Пусть ваш интерфейс будет реализован в абстрактном классе. Абстрактный класс будет реализовывать 5 методов, а остальные методы останутся виртуальными. Затем все ваши 3 класса должны унаследоваться от абстрактного класса. Это был ваш клиентский код, который использует 3 класса, и менять его не нужно.

0
ответ дан 28 November 2019 в 18:31
поделиться

Хотя я согласен с @PoweRoy, вам, вероятно, потребуется разбить интерфейс на более мелкие части. реализации интерфейса.

Например:

public interface IPet
{
   void Scratch();
   void Bark();
   void Meow();
}

public class Cat : IPet
{
    public void Scratch()
    {
        Console.WriteLine("Wreck furniture!");
    }

    public void Meow()
    {
       Console.WriteLine("Mew mew mew!");
    }

    void IPet.Bark()
    {
        throw NotSupportedException("Cats don't bark!");
    }
}

public class Dog : IPet
{
    public void Scratch()
    {
        Console.WriteLine("Wreck furniture!");
    }

    void IPet.Meow()
    {
       throw new NotSupportedException("Dogs don't meow!");
    }

    public void Bark()
    {
        Console.WriteLine("Woof! Woof!");
    }
}

С классами, определенными выше:

var cat = new Cat();
cat.Scrach();
cat.Meow();
cat.Bark(); // Does not compile


var dog = new Dog();
dog.Scratch();
dog.Bark();
dog.Meow(); // Does not compile.


IPet pet = new Dog();
pet.Scratch();
pet.Bark();
pet.Meow(); // Compiles but throws a NotSupportedException at runtime.

// Note that the following also compiles but will
// throw NotSupportedException at runtime.
((IPet)cat).Bark();
((IPet)dog).Meow();
4
ответ дан 28 November 2019 в 18:31
поделиться

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

3
ответ дан 28 November 2019 в 18:31
поделиться
Другие вопросы по тегам:

Похожие вопросы: