为什么我们不能在实现类中重新定义接口上声明的方法的可见性?

时间:2019-02-20 10:22:21

标签: php oop interface

据我了解,这些接口是所有实现它们的类都必须遵守的构造计划。

如果我想创建多个数据库类,比如说一个类管理mySQL,另一个类管理PostgreSQL,则我将创建一个接口,在其中将放置网站正常工作所需的所有方法以及两个类model.mysqlManager.phpmodel.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 :(得分:1)

  

接口如何影响实现它的类?它不是仅用于定义必须具有的方法吗?

接口定义了实现类必须遵守的合同。

它必定定义了一个公共接口。为了使该合同对其他类有用,在接口上定义的方法必须是公开的。私有/受保护的方法不是合同的一部分,而是内部实现的一部分,并且从逻辑上讲不是接口的一部分。类A所具有的任何私有/受保护方法都与类B无关,因为它们仍然无法使用。

如果一个类可以更改在接口中声明的方法的可见性,则它不符合合同

  

我还可以使用其他什么方法来强制我的类实现此方法?

常见的模式是具有可用于满足接口要求的特征。显然,该特征提供的方法也必须是公开的。


如果要定义一类类的内部,则接口不是您应该寻找的语言功能,而是继承。您可以在父类中完全或部分定义这些方法,并在子类中使用这些方法。

请注意,继承和接口是非常不同的动物,适用于非常不同的目的,并且继承带有权衡之类的问题,例如接口之间没有耦合的增加。

但是如果您想那样做,可以创建类似以下内容的

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

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

通过声明类abstract,不能直接实例化它,而必须对其进行扩展。通过将方法声明为protected abstract,您是说继承类必须实现该方法才能正常工作。

答案 1 :(得分:1)

  

我的问题是:

     

接口如何影响实现它的类?才不是   它仅用于定义必须具有的方法吗?什么   我可以用其他方式强迫我的班实施这种方法吗?

接口仅定义公共方法。实现目标的另一种方法是使用抽象connectDatabase方法而不是接口定义一个抽象类。只需在实现中扩展该抽象类即可。

抽象方法必须在子类中实现,因此这对于您来说就像接口协定。