Абстрактные классы по сравнению с интерфейсами по сравнению с mixins

Свифт 2,2 на основе ответа Мрунала :

let notAllowedCharacters = " ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789_.";
func textField(
    textField: UITextField,
    shouldChangeCharactersInRange range: NSRange,
    replacementString string: String)
    -> Bool
{
    let set = NSCharacterSet(charactersInString: notAllowedCharacters);
    let inverted = set.invertedSet;

    let filtered = string
        .componentsSeparatedByCharactersInSet(inverted)
        .joinWithSeparator("");
    return filtered == string;

}

68
задан Sasha Chedygov 25 September 2013 в 17:16
поделиться

4 ответа

В основном абстрактный класс - это интерфейс с некоторой конкретной реализацией. Интерфейс - это просто контракт, в котором нет деталей реализации.

Вы должны использовать абстрактный класс, если хотите создать общую функциональность среди всех объектов, реализующих абстрактный класс. Соблюдение принципа DRY (Don't Repeat Yourself) ООП.

3
ответ дан 24 November 2019 в 14:17
поделиться

Абстрактный класс - это класс, в котором реализованы не все члены, они оставлены для реализации наследникам. Он заставляет его наследников реализовывать свои абстрактные члены. Абстрактные классы не могут быть созданы, поэтому их конструкторы не должны быть общедоступными.]

Вот пример на C #:

    public abstract class Employee
    {
        protected Employee(){} 
        public abstract double CalculateSalary(WorkingInfo workingInfo);//no implementation each type of employee should define its salary calculation method.
    }

   public class PartTimeEmployee:Employee
  {
    private double _workingRate;
    public Employee(double workingRate)
    {
     _workingRate=workingRate;
    }
    public override double CalculateSalary(WorkingInfo workingInfo)
    {
      return workingInfo.Hours*_workingRate;
    }

}

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

Вот пример на C #:

public interface IShape
{
int X{get;}
int Y{get;}
void Draw();
}

public class Circle:IShape
{
public int X{get;set;}
public int Y{get;set;}

public void Draw()
{
//Draw a circle
}
}

public class Rectangle:IShape
{
public int X{get;set;}
public int Y{get;set;}

public void Draw()
{
//Draw a rectangle
}
}
1
ответ дан 24 November 2019 в 14:17
поделиться

В общем:

Интерфейс - это контракт, определяющий операции, но без какой-либо реализации. Некоторые языки (Java, C #) имеют встроенную поддержку интерфейсов, а в других «интерфейс» описывает соглашение, подобное чистому виртуальному классу в C ++.

Абстрактный класс - это класс, который определяет хотя бы одна операция без реализации. Абстрактные классы также могут предоставлять некоторые части своей реализации. Опять же, в некоторых языках есть встроенная поддержка маркировки классов как абстрактных, а в других это неявно. Например, в C ++ класс, который определяет чистый виртуальный метод, является абстрактным.

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

interface RequestHandler {
  void handleRequest(Request request);
}

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

abstract class BufferedRequestHandlerMixin implements RequestHandler {
  List<Request> buffer = new List<Request>();

  void handleRequest(Request request) {
    buffer.add(request);

    if (buffer.size == BUFFER_FLUSH_SIZE) {
        flushBuffer(buffer);
        buffer.clear();
    }
  }

  abstract void flushBuffer(List<Request> buffer);
}

Таким образом, нам легко написать обработчик запросов, который записывает запросы на диск, вызывает веб-службу и т. Д. Без перезаписывая функциональность буферизации каждый раз. Эти обработчики запросов могут просто расширить BufferedRequestHandlerMixin и реализовать flushBuffer .

Еще один хороший пример миксина - это один из многих классов поддержки в Spring, а именно. HibernateDaoSupport .

abstract class BufferedRequestHandlerMixin implements RequestHandler {
  List<Request> buffer = new List<Request>();

  void handleRequest(Request request) {
    buffer.add(request);

    if (buffer.size == BUFFER_FLUSH_SIZE) {
        flushBuffer(buffer);
        buffer.clear();
    }
  }

  abstract void flushBuffer(List<Request> buffer);
}

Таким образом, нам легко написать обработчик запросов, который записывает запросы на диск, вызывает веб-службу и т. Д., Не переписывая каждый раз функции буферизации. Эти обработчики запросов могут просто расширить BufferedRequestHandlerMixin и реализовать flushBuffer .

Еще один хороший пример миксина - это один из многих классов поддержки в Spring, а именно. HibernateDaoSupport .

abstract class BufferedRequestHandlerMixin implements RequestHandler {
  List<Request> buffer = new List<Request>();

  void handleRequest(Request request) {
    buffer.add(request);

    if (buffer.size == BUFFER_FLUSH_SIZE) {
        flushBuffer(buffer);
        buffer.clear();
    }
  }

  abstract void flushBuffer(List<Request> buffer);
}

Таким образом, нам легко написать обработчик запросов, который записывает запросы на диск, вызывает веб-службу и т. Д., Не переписывая каждый раз функции буферизации. Эти обработчики запросов могут просто расширить BufferedRequestHandlerMixin и реализовать flushBuffer .

Еще один хороший пример миксина - это один из многих классов поддержки в Spring, а именно. HibernateDaoSupport .

21
ответ дан 24 November 2019 в 14:17
поделиться

Ссылка на Java и приведенный пример абстрактного класса для обеспечения миксина вводят в заблуждение. Во-первых, Java по умолчанию не поддерживает «миксины». В терминах Java абстрактный класс и миксины сбивают с толку

. Миксин - это тип, который класс может реализовать в дополнение к своему «первичному типу», чтобы указать, что он обеспечивает некоторое дополнительное поведение. Говоря языком Java, одним из примеров может быть объект бизнес-ценности, реализующий Serializable.

Джош Блох говорит: «Абстрактные классы нельзя использовать для определения миксинов, поскольку у класса не может быть более одного родителя» (помните, что Java допускает только один «расширяет» кандидат)

Поищите такие языки, как Scala и Ruby, для соответствующей реализации понятия «миксин»

6
ответ дан 24 November 2019 в 14:17
поделиться