繁体   English   中英

了解接口和抽象类

[英]Understanding Interfaces and Abstract Classes

我从未在PHP中使用过Interfaces或Abstract Classes,但是到了我想要支持相似但不同类型的同一对象(在这种情况下为Network Switches)的地步,并可能在将来添加更多对象。 我通过SSH(PHPSecLib)与他们进行通信,并且它们之间的交互是不同的,实际方法是相同的。

在我的特殊情况下,我认为实现常量,私有变量,连接函数和构造函数/析构函数的抽象类将是适当的,而保留扩展类仅用于实现功能,其中接口只是模板,而每个扩展类将仍然重新实现它们之间相同的方法。

我是否认为抽象类是这种情况下的正确做法? 您是否需要在被扩展类覆盖的抽象类中放置空方法,或者扩展类是否可以具有Abstract类中不存在的方法?

例:

<?php

    set_include_path(get_include_path() . PATH_SEPARATOR . '/home/devicepo/public_html/include/PHPSecLib');

    include('Net/SSH2.php');
    include('File/ANSI.php');

    abstract class Switch
    {
        const STATUS_UNKNOWN = "-1";
        const STATUS_OFFLINE = "0";
        const STATUS_ONLINE = "1";

        public $conn;

        private $_server;
        private $_username;
        private $_password;

        private $_bashshell;

        public function __construct($server, $username, $password)
        {
            if (!$server)
                die("Switch configuration not Defined");

            $this->_server = $server;
            $this->_username = $username;
            $this->_password = $password;
        }

        public function connect()
        {
            // Establish new SSH2 Connection
            $this->conn = new Net_SSH2($this->_server, 22);

            if(!$this->conn->login($this->_username, $this->_password))
            {
                die("Failed to connect to Switch: " . $this->_server);
            }
        }

        public function enable_port($port)
        {
            // Define in extended classes
        }

        public function disable_port($port)
        {
            // Define in extended classes
        }
    }

?>

我相信您的情况是要使用Abstract类。 原因是:

  1. 您的子类与父类共享大部分代码

  2. 您的子班有一个相似性的概念。

要针对点2更具体,请记住,实现同一接口的两个类不一定是相关的。 界面代表一种能力。 考虑例如飞机和鸟。 两者都可以实现可移植的接口,但是除了它们之间没有任何其他关联之外。 另一方面,您的子类具有类似的类型。 它们都是开关。 所以你的抽象类可能是

abstract class BasicSwitch { // You cannot use the name switch

    const STATUS_UNKNOWN = "-1";

    const STATUS_OFFLINE = "0";

    const STATUS_ONLINE = "1";

    public $conn;

    private $_server;

    private $_username;

    private $_password;

    private $_bashshell;

    public function __construct($server, $username, $password) {

        if (!$server) die("Switch configuration not Defined");

        $this->_server = $server;

        $this->_username = $username;

        $this->_password = $password;
    }

    public function connect() {

        // Establish new SSH2 Connection

        $this->conn = new Net_SSH2($this->_server, 22);

        if(!$this->conn->login($this->_username, $this->_password)) {

            die("Failed to connect to Switch: " . $this->_server);
        }
    }

    abstract public function enable_port($port);

    abstract public function disable_port($port);
}

一个具体的实现可能是

class CiscoSwitch extends BasicSwitch {

    public function __construct($server, $username, $password) {

        parent::__construct($server, $username, $password);
    }

    public function enable_port($port) {

        echo 'Port is enabled';
    }

    public function disable_port($port) {

        echo 'Port is disabled';
    }               
}

这里要记住的最重要的想法是CiscoSwitch也是BasicSwitch的一种。 这意味着可以在任何希望使用BasicSwitch的地方使用CiscoSwitch。 因此,请考虑您的机架中有许多交换机,并且您要为机架中的所有交换机启用同一端口。 这是您的机架类:

class Rack {

    protected $switches;

    public function addSwitch(BasicSwitch $switch) {

        $this->switches[] = $switch;
    }

    public function enable_ports($port) {

        foreach($this->switches as $switch) {

            $switch->enable_port($port);
        }
    }
}

如果您在Abstract类(BasicSwitch)上而不是在实现上键入提示,则可以确保机架内的任何开关都可以启用和禁用其端口。 您真的不在乎它是哪个开关。 您只知道它可以胜任。 这就是接口而不是实现上的代码。 这样,您的代码就可以扩展了,但是却可以修改。 您可以根据需要创建任意数量的交换机类型,但是可以确保Rack类将继续工作。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM