Почему мы не можем переопределить в реализующем классе видимость методов, объявленных в интерфейсе? - PullRequest
0 голосов
/ 20 февраля 2019

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

Если я хочу создать несколько классов базы данных, скажем, один класс для управления mySQL, а другой -управлять PostgreSQL, я бы создал интерфейс, в котором я поместил бы все методы, необходимые для работы моего сайта, и мои два класса model.mysqlManager.php и model.postgresqlManager.php будут реализовывать этот интерфейс.

То, что яне понимаю, почему мы не можем переопределить в нашем классе видимость методов, которые приходят из интерфейса.Я знаю, что они неявно общедоступны.

В моем случае мне бы хотелось иметь этот интерфейс:

interface.iDatabase.php

interface iDatabase {
    public function connectDatabase();
    // other functions
}

И тезисы классов:

model.mysqlManager.php

class mysqlManager implements iDatabase {

    protected $db;

    const HOST = '127.0.0.1';
    const DBNAME = 'dbname';
    const CHARSET = 'utf8';
    const USERNAME = 'username';
    const PASSWORD = 'password';


    protected function connectDatabase() {
        if(!isset($this->db)) {
            try {
                $this->db = new PDO('mysql:host='.self::HOST.'; dbname='.self::DBNAME.'; charset='.self::CHARSET.'', self::USERNAME, self::PASSWORD);
            } catch(Exception $e) {
                die('Erreur : '.$e->getMessage());
            }
        }

        return $this->db;
    }
}

model.postgresqlManager.php

<?php

class postgresqlManager implements iDatabase {

    protected $db;

    const HOST = '127.0.0.1';
    const DBNAME = 'dbname';
    const CHARSET = 'utf8';
    const USERNAME = 'username';
    const PASSWORD = 'password';

    protected function connectDatabase() {
        //function code
    }
}

Я не хочу иметь доступ к этому методу извне моего класса, но я хочу, чтобы все классы баз данных реализовали его.

Мои вопросы:

  1. Как интерфейс влияет на класс, который его реализует?Разве это не служит только для определения методов, которые обязательно иметь?
  2. Каким другим способом я могу воспользоваться, чтобы заставить мои классы реализовать этот метод?

Ответы [ 2 ]

0 голосов
/ 20 февраля 2019

Мои вопросы:

Как интерфейс влияет на класс, который его реализует?Разве это не служит только для определения методов, которые обязательно иметь?Какой другой способ я мог бы использовать, чтобы заставить мои классы реализовать этот метод?

Интерфейсы определяют только открытые методы.Другой способ достичь желаемого - определить класс abstract с абстрактным методом connectDatabase вместо интерфейса.Просто расширьте этот абстрактный класс своей реализацией.

Абстрактные методы должны быть реализованы в дочерних классах, так что это будет работать для вас как контракт интерфейса.

0 голосов
/ 20 февраля 2019

Как интерфейс влияет на класс, который его реализует?Разве он не служит только для определения методов, которые обязательно иметь?

Интерфейс определяет контракт, которому должен придерживаться реализующий класс.

Он определяет public интерфейс, обязательно.Чтобы этот контракт был полезным для других классов, методы, определенные в интерфейсе , должны быть общедоступными .Закрытые / защищенные методы не являются частью контракта, но являются частью внутренней реализации и логически не являются частью интерфейса.Какие бы частные / защищенные методы класс A не имел, они не представляют интереса для класса B, поскольку они все равно не могут быть использованы.

Если класс может изменить видимость метода, объявленного в интерфейсе, не будет соответствовать договору .

Каким другим способом я мог бы заставить свои классы реализовать этот метод?

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


Если вы хотите определить внутренние компоненты семейства классов, интерфейсы - это не та языковая функция, которую вы должны искать, нонаследование.Вы можете полностью или частично определить методы в родительских классах и использовать эти методы в дочерних классах.

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

Но если вы хотите пойти по этому пути, вы можете создать что-то вроде:

abstract class AbstractDatabase {
    protected abstract function connectDatabase();
}

class mysqlManager extends AbstractDatabase {
    protected function connectDatabase() {
       // do your thing
    }
}

Объявляя класс abstract, это не может бытьСоздан непосредственно, но должен быть расширен.И объявив метод как protected abstract, вы говорите, что наследующие классы ДОЛЖНЫ реализовывать метод, чтобы иметь возможность работать.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...