Это означает, что вы либо используете одно и то же имя функции / класса дважды, и вам нужно переименовать один из них, или это потому, что вы использовали require
или include
, где вы должны использовать require_once
или include_once
.
Когда класс или функция объявляется в PHP, он неизменен и не может быть позже объявлен с новым значением.
Рассмотрим следующий код:
class.php
<?php
class MyClass
{
public function doSomething()
{
// do stuff here
}
}
index.php
<?php
function do_stuff()
{
require 'class.php';
$obj = new MyClass;
$obj->doSomething();
}
do_stuff();
do_stuff();
Второй вызов do_stuff()
приведет к получению ошибка выше. Изменяя require
на require_once
, мы можем быть уверены, что файл, содержащий определение MyClass
, будет загружен только один раз, и ошибка будет устранена.
Полезно, когда Вы хотите иметь доступ к некоторым членам базового класса, но не выставляя их в Вашем интерфейсе класса. Частное наследование может также рассматриваться как некоторый состав: C++, облегченный часто задаваемыми вопросами , дает следующий пример для иллюстрирования этого оператора
class Engine {
public:
Engine(int numCylinders);
void start(); // Starts this Engine
};
class Car {
public:
Car() : e_(8) { } // Initializes this Car with 8 cylinders
void start() { e_.start(); } // Start this Car by starting its Engine
private:
Engine e_; // Car has-a Engine
};
Для получения семантического того же, Вы могли также записать автомобильный Класс следующим образом:
class Car : private Engine { // Car has-a Engine
public:
Car() : Engine(8) { } // Initializes this Car with 8 cylinders
using Engine::start; // Start this Car by starting its Engine
};
Однако этот способ сделать имеет несколько недостатков:
Частный может быть полезным при довольно многих обстоятельствах. Только один из них является политиками:
частичная специализация шаблона класса ответ на эту проблему проектирования? .
Другой случай, где это полезно, состоит в том, чтобы запретить копирование и присвоение:
struct noncopyable {
private:
noncopyable(noncopyable const&);
noncopyable & operator=(noncopyable const&);
};
class my_noncopyable_type : noncopyable {
// ...
};
, поскольку мы не хотим это, у пользователя есть указатель типа noncopyable*
к нашему объекту, мы происходим конфиденциально. Это рассчитывает не только для noncopyable, но и многих других таких классов также (политики, являющиеся наиболее распространенным).
Общедоступные модели IS-A наследования.
Непубличные модели IS-IMPLEMENTED-IN-TERMS-OF наследования.
модели Containment ИМЕЮТ - A, который эквивалентен IS-IMPLEMENTED-IN-TERMS-OF.
Sutter по теме . Он объясняет, когда Вы предпочли бы непубличное наследование включению для деталей реализации.
Например, когда Вы хотите снова использовать реализацию, но не интерфейс класса И переопределить его виртуальные функции.
Частное наследование главным образом используется по неправильной причине. Люди используют его для IS-IMPLEMENTED-IN-TERMS-OF, как обозначено в более раннем ответе, но по моему опыту это всегда более чисто, чтобы сохранить копию, а не наследоваться классу. Другой более ранний ответ, тот о CBigArray, обеспечивает идеальный пример этого антишаблона.
я понимаю, что могут быть случаи, когда имеет - не работает из-за фанатичного использования "защищенных", но лучше зафиксировать поврежденный класс, чем повредить новый класс.
Я использовал и частное и защищенное наследование однажды или другой.
Частное наследование полезно, когда Вы хотите, чтобы что-то имело поведение базового класса и затем смогло переопределить ту функциональность, но Вы не хотите, чтобы целый мир знал о нем, и используете его. Можно все еще использовать интерфейс конфиденциально производный класс при наличии функционального возврата тот интерфейс. Также полезно, когда у Вас могут быть вещи, регистрируют себя для прислушиваний к обратным вызовам, как они могут зарегистрировать себя с помощью закрытого интерфейса.
Защищенное наследование особенно полезно, когда у Вас есть базовый класс, который получает полезную функциональность из другого класса, но Вы только хотите, чтобы его производные классы смогли использовать его.
Я когда-то реализовал эти структуры данных как классы:
интерфейс большого массива заставил бы его быть похожим на массив, однако, это был на самом деле связанный список простых массивов фиксированного размера. Таким образом, я объявил это как это:
template <typename T>
class CBigArray : public IArray, private CLnkList {
// ...