Сам этим пользуюсь редко, но вот моё понимание:
Интерфейс - это прототип класса, в нем не может быть реализованых методов.
Абстрактный класс - класс в котором могут быть реализованы методы.
Нельзя создавать объекты таких классов.
Интерфейсы необходимы для того чтобы подогнать классы под один стандарт, т.е. если ты видешь что класс наследуется от определенного интерфейса, то ты со 100 процентной уверенность знаешь что он реализует методы этого интерфейса.
Абстрактный класс - это абстрактный класс

. Смысл говорит сам за себя. Вообще что такое класс? Класс это модель какого-то реального объекта. Абстрактый класс - это модель какого-то не реального объекта или объекта, создавать экземпляры которого нет смысла вообще или в данном контексте. Но его наследники будут полноценными
Исключения к ООП не имеют никакого отношения, применяются они не для отладки, а для отловки ошибок, причем не просто ошибок, а критических ошибок, когда программа явно не сможет выполнить свою задачу.
Для чего нужно ?
1. Ну, имхо, в основном для наглядности, например есть у тебя 1000 функций или классов, они там друг друга вызывают, и вдруг там где-то что-то не сработало и программа вылетает с ошибкой, потому что у тя там внутри куча if(!fopen(..)) exit('file not found'); тебе придётся рыться и искать. Если ты используешь исключения то в коде функций/классов ты можешь бросать исключения, потом заключить главный код (index.php напр) в try catch и в одном файле обрабатывать все исключительные ситуации.
2. Для работы с чужим кодом. Представь скачал ты допустим smarty и решил им пользоваться, но допустим у тебя под кеш всего 10 мегабайт, что явно будет иногда не хватать.
смарти заранее не знает как реагировать на ошибку out of space, ну и что ты будешь перекапывать все исходники smarty чтобы найти все места возможных ошибок чтобы правильно на них отреагировать ? я думаю нет. Вместо этого smarty кидает исключения, а ты их лови и обрабатывай как тебе угодно.