
Прототипне програмування
Прототипне програмування, зберігши частину рис ООП, відмовилося від базових понять — класу і спадкоємства.
Замість механізму опису класів і породження екземплярів мову надає механізм створення об'єкту (шляхом завдання набору полів і методів, які об'єкт повинен мати) і механізм клонування об'єктів.
Кожен знов створений об'єкт є «екземпляром без класу». Кожен об'єкт може стати прототипом — бути використаний для створення нового об'єкту за допомогою операції клонування. Після клонування новий об'єкт може бути змінений, зокрема, доповнений новими полями і методами.
Клонований об'єкт або стає повною копією прототипу, що зберігає всі значення його полів і дублюючою його методи, або зберігає посилання на прототип, не включаючи клонованих полів і методів до тих пір, поки вони не будуть змінені. У останньому випадку середовище виконання забезпечує механізм делегування — якщо при зверненні до об'єкту він сам не містить потрібного методу або поля даних, виклик передається прототипу, від нього, при необхідності — далі по ланцюжку.
Класс-орієнтірованноє програмування
Класс-орієнтірованноє програмування — це програмування, сфокусоване на даних, причому дані і поведінка нерозривно зв'язані між собою. Разом дані і поведінка є класом. Відповідно в мовах, заснованих на понятті «клас», всі об'єкти розділені на два основні типи — класи і екземпляри. Клас визначає структуру і функціональність (поведінка), однакову для всіх екземплярів даного класу. Екземпляр є носієм даних — тобто володіє станом, змінним відповідно до поведінки, заданого класу. У класс-ориентированных мовах новий екземпляр створюється через виклик конструктора класу (можливо, з набором параметрів). Екземпляр, що вийшов, має структуру і поведінку, жорстко задані його класом.
Продуктивність об'єктних програм
Граді Буч указує[7] на наступні причини, що призводять до зниження продуктивності програм із-за використання об'єктно-орієнтованих засобів:
Динамічне скріплення методів.
Забезпечення поліморфної поведінки об'єктів приводить до необхідності зв'язувати методи, що викликаються програмою (тобто визначати, який конкретно метод викликатиметься) не на етапі компіляції, а в процесі виконання програми, на що витрачається додатковий час. При цьому реальне динамічне скріплення потрібний не більше ніж для 20 % викликів, але деякі ООП-3 використовують його постійно.
Значна глибина абстракції.
ООП-розробка часто приводить до створення «багатошарових» застосувань, де виконання об'єктом необхідної дії зводиться до безлічі звернень до об'єктів нижчого рівня. У такому застосуванні відбувається дуже багато викликів методів і повернень з методів, що, природно, позначається на продуктивності.
Спадкоємство «розмиває» код.
Код, що відноситься до «крайових» класів ієрархії спадкоємства (які зазвичай і використовуються програмою безпосередньо), — знаходиться не тільки в самих цих класах, але і в їх класах-предках. Методи, що відносяться до одного класу, фактично описуються в різних класах. Це приводить до двох неприємних моментів:
Знижується продуктивність програми в системі із сторінковою пам'яттю — оскільки методи одного класу фізично знаходяться в різних місцях коди, далеко один від одного, при роботі фрагментів програми, що активно звертаються до успадкованих методів, система вимушена проводити часті перемикання сторінок.
Інкапсуляція знижує швидкість доступу до даних.
Заборона на прямий доступ до полів класу ззовні приводить до необхідності створення і використання методів доступу. І написання, і компіляція, і виконання методів доступу зв'язане з додатковими витратами.
Динамічне створення і знищення об'єктів.
Динамічно створювані об'єкти, як правило, розміщуються в купі, що менш ефективно, чим розміщення їх на стеку і, тим більше, статичне виділення пам'яті під них на етапі компіляції.
Не дивлячись на відмічені недоліки, Буч стверджує, що вигоди від використання ООП вагоміші. Крім того, підвищення продуктивності за рахунок кращої організації ООП-коди, за його словами, в деяких випадках компенсує додаткові накладні витрати на організацію функціонування програми. Можна також відмітити, що багато ефектів зниження продуктивності можуть згладжуватися або навіть повністю усуватися за рахунок якісної оптимізації коди компілятором. Наприклад, згадане вище зниження швидкості доступу до полів класу із-за використання методів доступу усувається, якщо компілятор замість виклику методу доступу використовує инлайн-подстановку (сучасні компілятори роблять це цілком упевнено).