Почему бы не сделать все 'виртуальным'? [дубликат]

Swift 4

Подписка по диапазону и частичному диапазону с использованием свойства String indices

Как вариант @LeoDabus хороший ответ , мы можем добавить дополнительное расширение к DefaultBidirectionalIndices с целью позволить нам использовать свойство indices String при реализации пользовательских подписок (с помощью Int специализированных диапазонов и частичные диапазоны) для последнего.

extension DefaultBidirectionalIndices {
    subscript(at: Int) -> Elements.Index {
        return index(startIndex, offsetBy: at)
    }
}

// Moving the index(_:offsetBy:) to an extension yields slightly
// briefer implementations for these String extensions.
extension String {
    subscript(r: CountableClosedRange) -> SubSequence {
        return self[indices[r.lowerBound]...indices[r.upperBound]]
    }
    subscript(r: CountablePartialRangeFrom) -> SubSequence {
        return self[indices[r.lowerBound]...]
    }
    subscript(r: PartialRangeThrough) -> SubSequence {
        return self[...indices[r.upperBound]]
    }
    subscript(r: PartialRangeUpTo) -> SubSequence {
        return self[..

Спасибо @LeoDabus за то, что он указал мне на направление использования свойства indices в качестве (другой) альтернативы подписке String!

Swift 4.2.

В Swift 4.2, DefaultBidirectionalIndices устарела в пользу DefaultIndices .

18
задан 3 revs 23 May 2017 в 12:26
поделиться

6 ответов

Могу посочувствовать. К счастью, мы re разрешено отключать чувствительность к регистру в нашем инструменте контроля версий!

Кажется, что автоматическая коррекция регистра VB6 IDE иногда меняет регистр в объявлениях переменных и ссылках, возможно, в зависимости от порядка, в котором модули перечислены в файле VBP? Но IDE не сообщает вам, что файл необходимо сохранить. Таким образом, проблема появляется только тогда, когда вы сохранили файл из-за другого редактирования. Мы кратко пытались предотвратить это, проверив все файлы в проекте и тщательно настроив случай, но это не исчезло.

Я полагаю, вы могли бы перечислить имена переменных, которые затронуты - обычно подозреваемыми являются однобуквенные имена, такие как «I», «X» и «Y», возможно, потому, что они используются в стандартных обработчиках событий, таких как MouseDown. Затем напишите надстройку, которая будет искать все объявления "

9
ответ дан 30 November 2019 в 08:53
поделиться

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

3
ответ дан 30 November 2019 в 08:53
поделиться

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

0
ответ дан 30 November 2019 в 08:53
поделиться

Simple: The entire point in a class is to encapsulate some kind of abstraction. For example, we want an object that behaves as a text string.

Now, if everything had been virtual, I would be able to do this:

class MessedUpString : String{
   override void Trim() { throw new Exception(); }
}

and then pass this to some function that expects a string. And the moment they try to trim that string, it explodes.

The string no longer behaves as a string. How is that ever a good thing?

If everything is made virtual, you're going to have a hard time enforcing class invariants. You allow the class abstraction to be broken.

By default, a class should encapsulate the rules and behaviors that it is expected to follow. Everything you make virtual is in principle an extensibility hook, the function can be changed to do anything whatsoever. That only makes sense in a few cases, when we have behavior that is actually user-defined.

The reason classes are useful is that they allow us to ignore the implementation details. We can simply say "this is a string object, I know it is going to behave as a string. I know it will never violate any of these guarantees". If that guarantee can not be maintained, the class is useless. You might as well just make all data members public and move the member methods outside the class.

Do you know the Liskov Substitution Principle? Везде, где ожидается объект базового класса B, вы должны иметь возможность передать объект производного класса D. Это одно из самых фундаментальных правил объектно-ориентированного программирования. Нам необходимо знать, что производные классы по-прежнему будут работать, когда мы приведем их к базовому классу и передадим их функции, которая ожидает базовый класс. Это означает, что мы должны сделать некоторое поведение фиксированным и неизменным.

2
ответ дан 30 November 2019 в 08:53
поделиться

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

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

0
ответ дан 30 November 2019 в 08:53
поделиться
Другие вопросы по тегам:

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