我从来没有在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
}
}
?>
答案 0 :(得分:1)
我相信在你的情况下,抽象类是要走的路。原因是:
您的子类与父类
您的孩子班级有相似的概念。
关于第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类继续工作。