Класс вызывает функцию в другом классе

У меня есть класс вроде:

<?PHP abstract class dbCon { public function OpenConnection() { // Do Something; // On error: $this->ShowError(); } abstract function ShowError(); } class ErrorHandling extends dbCon { public function ShowError() { // Show error } } ?> 

В приведенном выше коде есть недостаток. Я хочу вызвать ShowError () из абстрактного класса, но именно там определяется интерфейс. Как бороться с этим?

Вы путаете наследство с делегацией. ErrorHandler действительно должен быть делегатом dbCon.

Одним из полезных способов определить, должен ли класс A быть подкласс B, – спросить себя, если сказать: «A – более конкретный вид, чем B». То есть, имеет ли A по крайней мере все основные атрибуты и поведение B. Пример того, где это верно, а также нет:

  1. ИСТИННО: пума – это тип кошачьих.

    • ЛОЖЬ: багажник – это тип автомобиля.
    • ЛОЖЬ: Адвокат является типом исполнителей лейбла.

В случае 2 грузовик является частью автомобиля, поэтому правильный способ моделировать это по составу; иметь объект Car, который затем может содержать ссылку на объект Trunk.

В случае 3 адвокат является делегатом исполнительного органа звукозаписывающей компании; правильный способ моделирования этого заключается в том, что ваш RLExective объект содержит ссылку на одного или нескольких юристов, которых он знает, и иметь RLExecutive вызов метода SueCollegeStudentOrGrandmother () для любого из Адвокатов, когда возникнет такая необходимость.

В вашей иерархии здесь вы говорите, что ErrorHandler – это тип dbCon. Это не имеет никакого смысла. Было бы более правильным сказать, что ErrorHandler является делегатом dbCon, которому поручено обрабатывать ошибки. В этом случае вам, вероятно, понадобится бесплатный объект ErrorHandler, или, возможно, один с конкретными знаниями о ошибках БД. Всякий раз, когда dbCon получает ошибку, которую он хочет отобразить, он выдает ошибку ErrorHandler с помощью метода ShowError ().

Основываясь на вашем комментарии, кажется, что ваше замешательство заключается в значении расширений . Говоря, что ErrorHandler расширяет dbCon, вы сказали, что ErrorHandler является подклассом dbCon, а не тем, что ErrorHandler добавляет дополнительные функции для dbCon. Это означает, что вам нужно создать экземпляр ErrorHandler, который будет иметь как функциональные возможности dbCon, так и ErrorHandler. Это, вероятно, не то, что вы хотите.

Надеюсь, это имело какой-то смысл.

Вы можете реализовать свой собственный обработчик исключений :

 class Exception_Handler extends Exception { ... } class DB_Connection { try { throw new Exception_Handler('Cannot connect to DB: ' . $exception->getMessage() . '.'); } catch (Exception_Handler $exception) { $exception->show(); } } 

Подробнее об этом: http://www.w3schools.com/php/php_exception.asp

Я предлагаю вам прочитать о полиморфизме .

Вызов ShowError() из родительского класса будет определяться классом экземпляра, и это выполняется во время выполнения.

Чтобы продемонстрировать, рассмотрите этот код:

 <?PHP abstract class dbCon { public function OpenConnection() { // Do Something; // On error: $this->ShowError(); } abstract function ShowError(); } class ErrorHandling extends dbCon { public function ShowError() { // Show error echo "Error is here\n"; } } class WarningHandling extends dbCon { public function ShowError() { // Show waring echo "Warning is here\n"; } } $ErrorHandling = new ErrorHandling(); $ErrorHandling->OpenConnection(); $WarningHandling = new WarningHandling(); $WarningHandling->OpenConnection(); ?> 

При запуске вы получите:

 Error is here Warning is here 

Зачем?

Потому что первый ShowError() является объектом типа ErrorHandling . PHP видит, что объект имеет конкретный тип ErrorHandling поэтому, когда ShowError() вызывается из OpenConnection , php использует функцию из типа объекта ( ErrorHandling ).

Второй ShowError() – из объекта WarningHandling поэтому PHP использует ShowError() для WarningHandling .

Внимательно посмотрите на Полиморфизм . Полиморфизм является одним из наиболее важных понятий ООП (так как он отсутствует только для объектно-ориентированных).

Надеюсь это поможет.