Vale lembrar que não existe uma definição única, canônica e universal sobre Orientação a Objetos. A definição dada acima é uma das existentes, mas na realidade o buraco é mais embaixo.
Sugiro ler os 2 links indicados no parágrafo anterior, só para começar. Depois, pode ler esse (uma análise bem detalhada sobre as "escolas de orientação a objeto existentes"), e por fim leia o que Alan Kay (o sujeito da esquerda na imagem abaixo, considerado o criador do termo "Orientação a Objeto") disse sobre isso: aqui e aqui.
E tem também este artigo que faz uma comparação mais detalhada sobre as duas "escolas" da imagem acima.
De qualquer forma, usar classes não é a única forma de "fazer código OO". Claro que hoje em dia é a mais usada por muitas linguagens que se dizem orientadas a objetos, mas existem outras. JavaScript, por exemplo: como já citado, ela usa protótipos (no caso do JS, a palavra-chave class
é meio que um syntatic sugar, pois por baixo dos panos continuam sendo protótipos e funções construtoras).
E claro, é possível ter todas as características citadas (polimorfismo, modularidade, encapsulamento, etc) sem classes (até em C, por exemplo, dá pra ter tudo isso). O mecanismo de classes pode facilitar, é verdade, mas não quer dizer que é o único jeito.