了解接口和抽象类

时间:2014-10-01 00:40:45

标签: php oop interface abstract-class phpseclib

我从来没有在PHP中使用过接口或抽象类,但是我想要支持相同但不同类型的同一对象(在本例中为网络交换机),并且可能在将来添加更多。我通过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
        }
    }

?>

1 个答案:

答案 0 :(得分:1)

我相信在你的情况下,抽象类是要走的路。原因是:

  1. 您的子类与父类

  2. 共享很大一部分代码
  3. 您的孩子班级有相似的概念。

  4. 关于第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。这意味着CiscoSwitch可以在预期的BasicSwitch的任何地方使用。因此,请考虑您的机架上有许多交换机,并且您希望为机架中的所有交换机启用相同的端口。这是你的Rack类:

    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类继续工作。