Невозможно объявить метод дочернего класса, объявленный в интерфейсе суперкласса - PullRequest
3 голосов
/ 27 мая 2011

Это должен быть довольно простой вопрос о классах и интерфейсах, но, пожалуйста, оставьте меня в покое, пока я выкладываю свой пример.

В библиотеке Propel ORM все таблицы базы данных абстрагируются как классы, называемые BaseTablename,Различные методы взаимодействия с базой данных определены в базовом объекте.Затем библиотека также генерирует классы, названные в честь таблиц, таких как Tablename, которые очень удобны для переопределения базовых методов и добавления пользовательских методов.

Я просто пытаюсь переопределить метод delete() по умолчаниючтобы иметь возможность удалить некоторые зависимые данные.Но когда я объявляю метод переопределения, я получаю следующую ошибку:

Неустранимая ошибка: объявление Tablename :: delete () должно быть совместимо с таковым для Persistent :: delete ()

Итак, учитывая следующие основные определения, почему я не могу переопределить метод delete()?

/**
 * Part of the Propel library
 */
interface Persistent {
    public function delete (PropelPDO $con = null);
}

/**
 * Generated by Propel
 */
class BaseTablename extends BaseObject implements Persistent {
    public function delete (PropelPDO $con = null) {
        doesImportantStuff();
    }
}

/**
 * Skeleton class is generated by Propel
 */
class Tablename extends BaseTablename {
    /**
     * MY OWN BEAUTIFUL [BUT BROKEN] CODE
     */
    public function delete (PropelPDO $con = null) {
        doMyOwnStuff();

        // Added this 2011-05-30 -- As it happens, this IS the Problem!
        // I needed to add the $con parameter to the call to preserve
        // the "chain of compatibility", so to speak.
        parent::delete();
    }
}

Обновление: Iя добавил вызов parent :: delete (), который мне не удалось включить в исходный пример кода.Это действительно имело бы значение.Извините, ребята, и большое спасибо тем, кто подтвердил рабочий код

Ответ состоял в том, что мне нужно было сохранить параметр во всех объявлениях и вызовах.Моя перегруженная функция должна была прочитать:

    public function delete (PropelPDO $con = null) {
        doMyOwnStuff();

        parent::delete($con);
    }

Ответы [ 2 ]

1 голос
/ 30 мая 2011

Ну, я провел еще один простой тест. Используя ваш код, но с двумя эхо, и он работает как ожидалось. Как и в C, в этом случае интерфейс действует как прототип, так что, как вы говорите, он должен иметь те же параметры и видимость для классов, которые он реализует.

1 голос
/ 30 мая 2011

Этот код работает.Проблема должна быть в копии сервера или версии PHP.(Я запустил тесты через PHP версии 5.3.3-7 + squeeze1 без проблем)

...