OOP

Orientação à Objetos, tido por muitos o Santo Graal da computação. Eu não diria isso, é só mais uma complicação feita em cima da programação estruturada.

Classes são basicamente estruturas contendo dados e código (através dos métodos, que são basicamente uma função). Juntar dados e código em uma coisa só repetidamente foi mostrado que não é uma boa ideia. Primeiro que você está fazendo justamente o contrário do que um sistema faz, que é separar a memória do código da memória dos dados, o que quebra completamente a visão do que o seu computador está fazendo de fato (lembre-se que o código não é o que o computador executa, e sim o binário gerado por esse código). Outro problema é a performance, como você não tem uma boa visão do que vai ser feito na máquina, você não consegue fazer, por exemplo, otimizações de memória cache, ou alinhamento de memória pra processos acelerados por SIMD (Single Instruction Multiple Data). Lembre-se que a arrumação dos dados em memória é tão importante para a performance quanto o próprio algorítmo.

Por algum motivo, as pessoas acham que encapsulamento ajuda em alguma coisa. Encapsulamento não ajuda, ele apenas cria estados invisíveis e "protege" (???) o acesso a memória.
Ou seja, ao invés de você ter isso:

pessoa.nome = "Maria";
return pessoa.nome;

Você tem isso:

pessoa.setNome("Maria");
return pessoa.getNome();

"Mas você pode ter coisas a mais que você vai querer fazer no setNome e no getNome!" Sim, e posso fazer uma função pra fazer isso ao invés de "me preparar" e fazer um método, pra ter mais overhead de call? (Tá, aqui acho que já to puxando de mais). Enfim, não é algo que ajuda e só dá mais trabalho, pois é mais uma coisa que você vai escrever, é mais uma coisa que o compilador vai ter que se preocupar e é mais uma coisa que pode ser causa de bugs (o programador pode fazer um return de um valor errado, por exemplo). E vamos ser sinceros: estados invisíveis é uma coisa que você não quer nem fodendo.

Aqui é onde a merda começa a feder. O objetivo da hierarquia era pra melhorar a arquitetura dos dados, mas ele adiciona tantas regras e problemas que você realmente se pergunta se isso realmente ajuda (spoiler alert: hierarquia pode ser substituido por simples composição de estruturas). A hierarquia pode ser tão problemático que as próprias linguagens fazem contornos. Por exemplo, o Java não deixa você fazer uma classe filha de duas classes para evitar o problema do Diamante, então o contorno é você fazer uma classe pai e depois várias interfaces, para depois implementar as interfaces em cada uma das classes filhas, e de fato, essa é a solução para o problema do diamante, ou seja, toda aquela coisa de "reaproveitamento de código" foi por água abaixo.