Типизация
Типизация – это способ защититься от использования объектов одного класса вместо другого или, по крайней мере, управлять таким использованием.
Конкретный язык программирования может иметь сильный или слабый механизм типизации, и даже не иметь вообще никакого, оставаясь объектно-ориентированным. В сильно типизированных языках нарушение согласования типов может быть обнаружено во время трансляции программы. С другой стороны, в Smalltalk типов нет: во время исполнения любое сообщение можно послать любому объекту, и если класс объекта (или его надкласс) не понимает сообщение, то генерируется сообщение об ошибке. Нарушение согласования типов может не обнаружиться во время трансляции и обычно проявляется как ошибка исполнения.
Языки, в которых типизация отсутствует, обладают большей гибкостью (например, можно создавать наборы из разнородных объектов), но даже в таких языках программисты обычно знают, какие объекты ожидаются в качестве аргументов и какие будут возвращаться. На практике при разработке сложных систем надежность языков со строгой типизацией с лихвой компенсирует некоторую потерю в гибкости по сравнению с нетипизированными языками.
Строго типизированные языки имеют следующие преимущества:
- Все выражения будут согласованы по типу.
- Отсутствие контроля типов может приводить к загадочным сбоям в программах во время их выполнения.
- В большинстве систем процесс редактирование-компиляция-отладка утомителен, и раннее обнаружение ошибок просто незаменимо.
- Объявление типов улучшает документирование программ.
- Многие компиляторы генерируют более эффективный объектный код, если им явно известны типы.
По времени связывания имен объектов с их типами выделяют также статическое связывание (раннее связывание, во время компиляции) и динамическое связывание (позднее связывание, в момент выполнения программы). Концепции типизации и связывания являются независимыми, поэтому в языке программирования может использоваться разная стратегия связывания и типизации.
Одно и то же имя может означать объекты разных типов, но, имея общего предка, все они имеют и общее подмножество операций, которые можно над ними выполнять. Это особенность называется полиморфизмом. Полиморфизм возникает там, где взаимодействуют наследование и динамическое связывание.
Полиморфизм наиболее целесообразен в тех случаях, когда несколько классов имеют одинаковые протоколы. Полиморфизм позволяет обойтись без операторов выбора, поскольку объекты сами знают свой тип.
Наследование без полиморфизма возможно, но не очень полезно. Это видно на примере Ada, где можно объявлять производные типы, но из-за мономорфизма языка операции жестко задаются на стадии компиляции.
При полиморфизме связь метода и имени определяется только в процессе выполнения программ. В C++ программист имеет возможность выбирать между ранним и поздним связыванием имени с операцией. Если функция виртуальная, связывание будет поздним и, следовательно, функция полиморфна. Если нет, то связывание происходит при компиляции и ничего изменить потом нельзя.