Динамические языки имеют тип Duck
Если он ходит как утка и крякает
как утка, это должна быть утка
http://en.wikipedia.org/wiki/Duck_typing
Другими словами, если вы подставляете объект для поддержки метода Delete (), вы можете просто использовать
obj.Delete()
, но если объект не поддерживает Delete (), вы получите ошибку времени выполнения. Языки со статической типизацией не позволят этого и выдадут ошибку времени компиляции. Таким образом, вы в основном торгуете типом safty против более быстрого времени разработки и гибкости.
Без интерфейсов вы можете сделать что-то подобное на статических языках:
void Save(MyBaseClass item)
{
if (item.HasChanges)
item.Save()
}
но для этого потребуется, чтобы каждый объект, который вы передаете этому методу, наследовал от MyBaseClass. Поскольку Java или C # не поддерживают муль-наследование, которое не очень гибкое, потому что, если ваш класс уже наследует другой класс, он также не может наследовать от MyBaseClass. Поэтому лучшим выбором было бы создать интерфейс ISavable и принять его в качестве входного параметра, чтобы гарантировать возможность сохранения элемента. Тогда у вас есть все лучшее: безопасность и гибкость.
public interface ISavable
{
bool HasChanges {get;set;}
void Save();
}
void Save(ISavable item)
{
if (item.HasChanges)
item.Save()
}
Последний бэкдор - использовать объект в качестве параметра, если вы не можете ожидать, что каждый элемент, который будет использовать ваш метод сохранения для реализации интерфейса.
void Save(object item)
{
if (item.HasChanges)
item.Save()
}
Но опять же, у вас нет проверки времени компиляции и, возможно, вы получите ошибку времени выполнения, если кто-то использует ваш метод с несовместимым классом.