Наследование: берём существующий класс и создаём на его основе новый класс, добавляя новые поля и методы, заменяя методы исходного (родительского) класса собственным кодом. Длинные цепочки наследования создают большую головную боль (хрупкий код, который легко сломать и сложно читать), создавая куда больше проблем, чем решая. И при наличии в языке интерфейсов наследование не имеет смысла.
Инкапсуляция: изоляция компонентов программы (классов) друг от друга. Класс не может залезть внутрь другого класса и что-то там поменять. Каждый класс - чёрный ящик, реализующий замкнутый функционал и взаимодействующий с другими классами через вызовы методов. Мы можем как угодно менять код внутри класса, но пока сигнатуры публичных методов этого класса остаются неизменными, это никак не отразится на остальном коде программы.
Полиморфизм: когда один и тот же метод (определённый либо в интерфейсе, реализуемом классом, либо в родительском классе) в разных классах реализует разный функционал. Чтобы нарисовать фигуру, мы просто вызываем метод Draw класса, реализующего фигуру. И не важно, будет это класс Triangle или класс Square. Важно лишь то, что класс имеет метод Draw. А как именно будет нарисована фигура - это внутреннее дело класса (инкапсуляция), нас не касающееся.