Php переменная static: Странные они, статические переменные в PHP / Хабр
Содержание
PHP – статические свойства | CoderNet
У меня есть два фрагмента кода, которые, как я ожидаю, будут иметь одинаковый результат, но на самом деле результаты разные.
Вопрос в том, почему?
Фрагмент 1
class base {
public static $var = 1;
}
class sub extends base {
public static $var = 2;
}
echo base::$var; // Выводит 1
Фрагмент 2
class base2 {
public static $var2 = 1;
}
class sub2 extends base2 {
}
sub2::$var2 = 2;
echo base2::$var2; // Выводит 2
Ответ 1
Переменные STATIC не связаны с каким-либо конкретным экземпляром/объектом класса. Следовательно, если вы изменяете переменную по ссылке родительского класса или по ссылке дочернего класса, изменяется одна и та же переменная.
Следовательно, надо понимать, что свойства Public Static, как и глобальные, не связаны с конкретным экземпляром объекта, поэтому по любой ссылке на иерархию класса вы обновляете статическую переменную и обновляется одна и та же область памяти.
Ответ 2
Публичная статическая переменная действует подобно глобальной переменной.
Поскольку область видимости публичной статической переменной определяется глобально, можно гарантировать, что любые изменения глобальной переменной будут видны во всей программе. Эту концепцию вы можете проанализировать в вашем примере программы…..
Ответ 3
Если вы передаете статическую переменную подклассу, то эта переменная является общей (она всегда имеет одно и то же значение в обоих классах). Если вы перегружаете статическую переменную в подклассе, то это новая статическая переменная, не зависящая от статической переменной родителя.
В фрагменте 1 base::var и sub::var имеют разное распределение памяти, потому что вы перегрузили $var = 2; в классе sub.
В фрагменте 2 base::var и sub::var имеют одинаковое распределение памяти, потому что вы не указали $var2 в классе sub2.
Поэтому base:var не изменяется. Он также не изменится, если вы позже измените $var из класса sub следующим образом:
class base {
public static $var = 1;
}
class sub extends base {
public static $var = 2;
}
sub::var = 3;
echo base::var; // Выводится 1
Ответ 4
Поскольку класс sub2 не имеет var2, он принимает значение класса base2. Поэтому, когда вы присвоили новое значение, используя этот sub2::$var2 = 2; оно изменилось на новое значение.
В первом коде вы переопределили ее в своем расширенном классе. Обе переменные имеют область видимости, в соответствии с тем, где они определены в иерархии наследования.
[Вопрос] Использование static, const [Архив] — Pro Pawn
Видимо, тема еще актуальна, раз конечного ответа автор публично так и не получил.
Коль уж вопросы начали затрагивать маркеры, а значит и виды памяти, наверное, было бы неплохо переименовать эту тему… Вообще, хотел узнать за декларирование функций (forward), потому что в интернете это расписано крайне… Даже не знаю как сказать, не то что бы сложно, просто непонятно зачем оно надо.
По поводу forward: объявление forward для всех паблик-функций является обязательным условием. Это, своего рода, одно из правил языка.
Вдаваться в подробности не имеет смысла, однако, если любопытство не перестает угнетать — можно прочитать подробности в P.I.G.
Функцию следует делать публичной, в случае, если серверу требуется вызвать её во время выполнения. То бишь, далеко ходить не будем, это та же самая функция для таймеров, к примеру.
Вот public делает переменную или функцию (дословно) общественной. Ну, будет к ней возможность обратиться из другого файла (ведь верно?).
Это обращение осуществляется через CallRemoteFunction (для функций) и никак (серьезно? :sad:) (для переменных). Я бы понял, если бы forward был нужен для того, чтобы в другом файле эта функция не была неизвестной. Но ведь forward суется не в этот файл, а в мод. А значит смысл от него каков?
Верно.
CallRemoteFunction получает адрес для вызова нужной функции по индексу, посредством двоичного поиска в таблице паблик-функций, который, в свою очередь, хранится в префиксном сегменте памяти. Данный сегмент входит в конечно скомпилированный amx файл.
Проспойлерю: forward как раз таки и связан с получением функцией определенного индекса.
Мы не можем обратиться к определенной переменной из другого скрипта потому, что переменные находятся совершенно в других секрециях памяти (в стеке и куче), которые, в свою очередь, не включены в конечный файл.
В одной из тем шла речь про суть public-функций. Мол, они дают о себе знать в некой хеш-таблице. А что это за таблица и где можно про нее получить конкретную информацию? В официальной документации есть об этом речь. Единственное полезное, что я понял оттуда — нежелательно создание «лишних» public-функций (не нужна — не делай), мол, большая хэш-таблица ухудшается в производительности, а потому работа с public-функциями будет уже медленнее. А вот, например, тот факт, что размер хэш-таблицы ограничен и при его исчерпании нужно увеличить этот самый размер, мне уже непонятен. Каким образом его можно менять и как получить общее представление о том, чему равен максимальный размер хэш-таблицы? Или он вообще в процессе работы сервера увеличивается сам, в зависимости от частоты вызова тех или иных функций. Была информация про функции, которые должны влиять на эту таблицу, но сами функции в игровом моде не работают (якобы символ не объявлен).
Как я уже писал выше, эта таблица называется таблицей паблик-функций.
Ограничений по кол-ву созданных функций публичного типа, как таковых, не предусмотрено, ибо секреция префиксов на свой макс.размер лимитов не имеет (в отличие от стеко-кучевого блока).
Получение как таковых адресов тебе ничего не даст, ибо резервация в таблице паблик-функций происходит автоматически, посредством смещения к CIP от адреса последней функции (чтобы понять, что это такое, тебе стоит также почитать документацию к языку), а манипулировать адресами (то бишь делать переадресацию, либо дублировать функции, как в более расширенных языках), мы не можем.
Насчёт скорости — да, это логично. Чем больше функций, тем дольше будет осуществляться двоичный поиск в их таблице.
ЖК «Реут»: ипотека и выгодные цены на квартиры в новостройке от застройщика
Окружение
А что вокруг?
Жилой комплекс «Реут» находится в окружении уже сложившейся инфраструктуры: школ и детских садов, поликлиник и аптек, торговых и фитнес-центров, магазинов, спортивных объектов, ресторанов и кафе. Все это создаст широкие возможности для комфортной жизни, отдыха, образования и работы.
‘
},
{
cords: ‘55.752016,37.88629’,
pin: ‘
Аптека
36,6
‘
},
],
2: [
{
cords: ‘55.752248,37.887566’,
pin: ‘
ТРЦ
Реутов Парк
‘
},
{
cords: ‘55.756407,37.885357’,
pin: ‘
Зоомагазин
Генерал мяу
‘
},
],
4: [
{
cords: ‘55.751787,37.880875’,
pin: ‘
МАОУ
СОШ № 10
‘
},
{
cords: ‘55.75163,37.887473’,
pin: ‘
Школа танцев
Todes
‘
},
{
cords: ‘55.753667,37.882953’,
pin: ‘
Школа танцев
Ласточка
‘
},
],
5: [
{
cords: ‘55.75313,37.895396’,
pin: ‘
Частный детский сад
Бэби Бум
‘
},
{
cords: ‘55.756377,37.886176’,
pin: ‘
Детский клуб
Данилка
‘
},
{
cords: ‘55.755064,37.879264’,
pin: ‘
Детский клуб
Бусинка
‘
},
{
cords: ‘55.754401,37.879173’,
pin: ‘
МАДОУ № 8
Планета детства
‘
},
{
cords: ‘55.752304,37.884444’,
pin: ‘
МАДОУ № 13
Веснушки
‘
},
],
6: [
{
cords: ‘55.759936,37.867223’,
pin: ‘
Кафе
Старый город
‘
},
{
cords: ‘55.755696,37.881931’,
pin: ‘
Пиццерия
Запекали
‘
},
{
cords: ‘55.753499,37.881632’,
pin: ‘
Ресторан
Макдоналдс
‘
},
{
cords: ‘55.75155,37.886882’,
pin: ‘
Ресторан
Нияма
‘
},
{
cords: ‘55.751304,37.888632’,
pin: ‘
Кафе
Никольское
‘
},
{
cords: ‘55.764069,37.895983’,
pin: ‘
Суши-бар
Mr. Sushi Pizza
‘
},
],
7: [
{
cords: ‘55.752561,37.876404’,
pin: ‘
Магазин продуктов
ВкусВилл
‘
},
{
cords: ‘55.752287,37.888103’,
pin: ‘
Продуктовый гипермаркет
Ашан Сити
‘
},
{
cords: ‘55.753626,37.878857’,
pin: ‘
Супермаркет
Пятёрочка
‘
},
{
cords: ‘55.753752,37.881746’,
pin: ‘
Супермаркет
Виктория
‘
},
{
cords: ‘55.750353,37.887938’,
pin: ‘
Супермаркет
Верный
‘
},
],
13: [
{
cords: ‘55.752201, 37.887986’,
pin: ‘
Батутный центр
Прыжок
‘
},
{
cords: ‘55.755591, 37.881569’,
pin: ‘
Бассейн
Китёнок
‘
},
],
}
;
Медицина
Торговые центры
Школы
Детям
Рестораны и кафе
Магазины
Спорт
ЖК «Императорские Мытищи»: ипотека и выгодные цены на квартиры в новостройке от застройщика
Окружение
Уют близко к Москве
Жилой комплекс «Императорские Мытищи» расположен на юге Мытищинского района в 7 км от МКАД по Осташковскому шоссе. Добраться до жилого комплекса можно как на общественном транспорте (автобусы и маршрутные такси отправляются от станции метро «Медведково», по железной дороге — с Ярославского вокзала до станции «Мытищи»), так и на автомобиле по Осташковскому или Ярославскому шоссе.
Аптека
ГорЗдрав
‘
},
{
cords: ‘55.962673,37.666497’,
pin: ‘
Аптека
36,6
‘
},
{
cords: ‘55.965285,37.673367’,
pin: ‘
Диагностический центр
Гемотест
‘
},
{
cords: ‘55.957825,37.683694’,
pin: ‘
Аптека
Трифарма
‘
},
],
4: [
{
cords: ‘55.947207,37.647694’,
pin: ‘
МБОУ
СОШ № 29
‘
},
],
5: [
{
cords: ‘55.962766,37.669647’,
pin: ‘
Детский сад
Маленькая страна
‘
},
{
cords: ‘55.960796,37.654433’,
pin: ‘
Детский сад
Островок фантазий
‘
},
],
6: [
{
cords: ‘55.957761,37.68385’,
pin: ‘
Паб
Sofys Pub
‘
},
{
cords: ‘55.965597,37.673744’,
pin: ‘
Пиццерия
Cheel Pizza
‘
},
{
cords: ‘55.962362,37.66618’,
pin: ‘
Паб
Пивотека 777
‘
},
],
7: [
{
cords: ‘55.957544,37.68392’,
pin: ‘
Магазин продуктов
Верный
‘
},
{
cords: ‘55.957471,37.684008’,
pin: ‘
Магазин продуктов
Лавка Вкуса
‘
},
{
cords: ‘55.962361,37.665842’,
pin: ‘
Супермаркет
Перекрёсток
‘
},
{
cords: ‘55.963416,37.668883’,
pin: ‘
Супермаркет
Пятёрочка
‘
},
{
cords: ‘55.965668,37.673584’,
pin: ‘
Супермаркет
Магнит
‘
},
],
}
;
Медицина
Школы
Детям
Рестораны и кафе
Магазины
статических переменных в унаследованных методах — Дерик Ретанс
Привет, я Дерик! Добро пожаловать в подкаст внутренних новостей PHP, посвященный последним разработкам в языке PHP. Это серия 80. В этой серии я снова говорю с Никитой Поповым о другом RFC, который он предлагает. Никита, как у тебя дела сегодня?
У меня все еще все хорошо.
Что ж, рад это слышать. Итак, причина, по которой вы говорите: «Я все еще в порядке», конечно же, потому, что мы в основном записываем два эпизода подкаста, идущие друг за другом.
Это правда.
Если 30 минут назад у вас все было хорошо, а сейчас — плохо, должно быть, случилось что-то плохое, и это, конечно, неинтересно.В любом случае, возьмем ли мы тогда второй RFC, который в унаследованных методах называется статическими переменными. Можете ли вы объяснить, что RFC призван улучшить?
Я не уверен, что это значит для улучшения, я скажу, что это больше похоже на попытку исправить ошибку. Это действительно технический RFC для крайнего случая крайнего случая, поэтому я должен сначала сказать, когда я говорю о статических переменных, я не говорю о статических свойствах, которые использует большинство людей, а о статических. переменные внутри функций.Что статические переменные делают в отличие от обычных переменных, так это то, что они сохраняются при вызове функций. Например, вы можете иметь статический счетчик $ i равным нулю, а затем увеличивать его, а затем каждый раз, когда мы вызываем функцию, он увеличивается каждый раз, и значение из предыдущего вызова сохраняется. Так что это просто контекст того, о чем мы говорим.
Зачем людям использовать статические переменные?
Я думаю, что одним из наиболее распространенных вариантов использования является мемоизация.
Вы можете объяснить, что это такое?
Если у вас есть функция, которая вычисляет какой-то дорогостоящий результат, но всегда один и тот же, то вы можете вычислить ее только один раз и сохранить внутри статической переменной, а затем вернуть. Возможно, это зависит от аргументов функции, но это общая идея.И это также работает, если это отдельная функция. Так что, если он не находится в методе, где вы можете сохранить состояние внутри статического свойства или аналогичного, но также работает внутри функции, не являющейся методом.
Я полагаю, что ключевое слово в его заголовке RFC — это унаследованные методы. Что там сейчас происходит?
В этой области есть несколько проблем.Ключевой момент — это первое: как статические переменные вообще взаимодействуют с методами? И вторая часть — как это взаимодействует с наследованием. Итак, сначала, если у вас есть метод экземпляра со статической переменной, тогда некоторые люди ожидают, что на самом деле каждый экземпляр объекта получит отдельную статическую переменную. Это не тот случай. Статические переменные действительно привязаны к функциям или методам, они не зависят от экземпляра объекта. Вторая проблема: что происходит с наследованием? Итак, у вас есть родительский класс с методом, использующим статические переменные, а затем у вас есть дочерний класс, наследующий этот метод.Есть два способа интерпретировать это: либо это все тот же метод, поэтому он должен использовать те же переменные, либо вы можете сказать, что унаследованный метод на самом деле является отдельным методом и должен использовать отдельные переменные. В настоящее время PHP следует второй интерпретации.
И так ли это, если оно переопределено, или только тогда, когда оно унаследовано? Потому что там тоже есть разница.
Да, это основная модель, которой пытается следовать PHP, но есть довольно много крайних случаев. Тот, который вы упомянули, если вы переопределяете метод, тогда, конечно, вы вызываете переопределенный метод, поэтому статические переменные даже не поступают. Но если вы затем вызываете родительский метод, то обычно вы ожидаете, если вы выполняете переопределение и просто вызываете родителя, что поведение точно такое же, как если бы вы его вообще не переопределяли.Здесь дело обстоит не так, потому что теперь вы вызываете родительский метод. Итак, проблема в том, что если вы не переопределите метод, то дочерний метод и родительский метод будут иметь разные статические переменные. Теперь, если вы вызываете parent, то вы просто вызываете родительский метод, поэтому вы возвращаетесь к одному набору статических переменных, которые одинаковы для обоих методов. Вы можете видеть, что они одинаковы для обоих методов, но, скорее, поскольку вы вызываете родительский метод, задействован только один метод, задействован только один набор статических переменных.Вы не можете просто расширить метод, использующий статические переменные, без случайного изменения поведения.
Звучит очень сложно.
Да, я сказал, я предупреждал вас, что это крайний случай крайнего случая.
Но я думаю, что вся идея RFC состоит в том, чтобы сделать его менее сложным.
Да, это вроде не единственная проблема, с которой можно столкнуться. Есть еще один, который мы фактически рассмотрели отдельно, но который все еще существует в более ранних версиях PHP, а именно, что значение статических переменных зависит от времени наследования. Позвольте мне быть здесь более определенным. Что у нас было в предыдущих версиях, так это то, что половина вашего родительского метода была статическими переменными, затем вы вызываете этот родительский метод, статические переменные меняются, а затем вы наследуете его.И снова вызовите унаследованный метод. В таком порядке: сначала объявите родителей, позвоните, объявите ребенка, позвоните ему. В этом случае мы фактически возьмем статические переменные в то время, когда фактически происходит наследование. Первый вызов родительского метода изменяет статические переменные, затем мы будем использовать некоторые измененные переменные. С этого момента у него будет отдельная копия, дочерний метод, но он захочет забрать эти оригинальные модификации до того, как произойдет наследование. Теперь в PHP 8.1 мы уже исправили это, поэтому мы всегда используем исходные значения, но это похоже на еще одну вещь в списке странных вещей, которые происходят, если вы используете статические переменные внутри методов и наследуете их.
Думаю, теперь я понимаю это больше.
Думаю, вы понимаете больше, чем когда-либо хотели.
Вы упомянули крайние случаи. Каков будет результат, когда этот RFC будет принят, что, по моему мнению, вполне вероятно,
Результат, надеюсь, проще, чем у нас, а именно: статические переменные действительно привязаны к определенной функции или объявлению метода.Если у вас есть один метод, использующий статические переменные, то у вас всегда будет только один набор статических переменных. Если он унаследован, вы все равно повторно используете те же статические переменные, потому что нет отдельного унаследованного метода. Это тот же метод в дочернем классе. Это концепция.
А если переопределить в унаследованном классе?
Если вы переопределите его и вызовете родительский метод, то поведение не изменится, потому что у вас все еще есть только один набор статических переменных, поэтому здесь больше нет граничного случая, потому что дочерний, дочерний метод никогда не имел отдельного задавать.
Но если переопределенный метод также определяет свою собственную статическую переменную с тем же именем?
Это возможно. В этом случае еще раз это правило состоит в том, что каждый метод имеет свои собственные статические переменные, а методы могут иметь статические переменные, и дочерний метод также может иметь их, если они переопределены и между ними нет конфликтов имен.
Поскольку они будут полностью разделены, это означает, что любой код, который вы запускаете в унаследованных методах, будет влиять только на его статические переменные, а любой код, который выполняется в исходных методах, влияет только на статические переменные, привязанные к этому конкретному методу.
Совершенно верно. Я имею в виду, что в конечном итоге статические переменные действительно являются типом глобального состояния, просто типом, который как бы изолирован от определенного пространства имен и не вызывает конфликтов, поэтому в этом смысле важно, чтобы эти вещи были изолированы.
И это также сделало бы поведение намного более легким для объяснения, чем сейчас. Потому что у каждого метода есть свой набор статических переменных.
Да.
Или, я бы сказал, каждый объявленный метод имеет свой собственный набор статических переменных.
Думаю, это важное различие. Если вы видите методы внутри своего кода и статическую переменную внутри него, то это особенный метод. Если игнорировать исключение черт.
Тебе придется объяснить и это.
Ну черты всегда особенная снежинка.Наша общая модель для трейтов состоит в том, что они копируются и вставляются с помощью компилятора. Таким образом, черта должна вести себя примерно так, как если бы вы просто скопировали все методы в класс, который ее использует. И в этом смысле, если вы фактически копируете код своего метода со статическими переменными, тогда он также должен использовать отдельный набор статических переменных для каждого использования. И так же и предполагается вести себя. Это похоже на одно исключение, когда у вас есть одно объявление метода в вашем коде, но каждый использующий класс получит отдельный набор статических переменных.
Потому что код копируется на место, а не связан или используется на месте. Это также относится ко всем методам, объявленным в трейтах, они также копируются в ту же таблицу символов, что и методы, принадлежащие классу.
Да, верно.
Следует каким-то образом подсчитывать ссылки, потому что вы, вероятно, не будете дублировать точные данные.
Мы, конечно, на самом деле не копируем методы или, по крайней мере, большинство методов, но с точки зрения программиста это работает именно так.
Почему вы говорите большинство методов, а не все методы?
Мы разделяем там две вещи.Есть сам метод. Итак, op-array, а затем есть все, что он использует, например, коды операций, информацию об аналогичных аргументах и так далее. Что они делают для трейтов, так это то, что мы разделяем все данные и создаем только отдельный операционный массив. Причина в том, что есть некоторые отличия. Например, нам нужно настроить область видимости, мы должны изменить, возможно, имя функции, если задействованы псевдонимы, и мы должны настроить статические переменные. Так что это похоже на частичную копию, которую мы делаем.
Какой, вероятно, наиболее эффективный способ сделать это?
Да.
Поскольку этот RFC меняет поведение из-за исправлений ошибок, я бы, вероятно, возразил, какие существуют проблемы с обратной совместимостью? А вы смотрели, сколько кода на самом деле влияет?
Я не смотрел, на сколько кода это влияет, потому что это кажется довольно сложным для анализа.Я имею в виду, что мы могли бы легко проверить, сколько статических переменных вообще используется в методах. Но будет сложно отличить, изменится ли это. Я имею в виду, как различать полностью автоматизированным способом. Влияет ли это изменение на поведение для конкретного варианта использования или нет. Поэтому я не могу дать информацию по этому поводу, хотя я ожидал, что влияние будет относительно низким, потому что распространенные варианты использования, такие как мемоизация, они не затронуты, или они затронуты им только в том смысле, что: Затем вы запомните значение только один раз для всей иерархии классов вместо того, чтобы запоминать его один раз для каждого подобного унаследованного класса.
Значит, там ситуация улучшится, в значительной степени то, о чем вы говорите?
Да, но я уверен, что бывают случаи, когда предыдущее поведение использовалось намеренно. Я имею в виду, что это никогда не было задокументировано, но вы знаете, что если какое-то поведение существует, люди всегда будут использовать его в конце, но я не могу точно сказать, какое влияние это окажет.
Вам есть что добавить при обсуждении этого RFC?
Нет, думаю, все.
Тогда я хотел бы поблагодарить вас за то, что вы снова нашли время поговорить со мной о статических переменных в унаследованных методах.
Спасибо, что снова пригласили меня.
Благодарим вас за то, что вы слушали этот выпуск внутренних новостей PHP, подкаст, посвященный демистификации разработки языка PHP. У меня есть учетная запись Patreon для сторонников этого подкаста, а также инструмента отладки Xdebug. Вы можете подписаться на Patreon по адресу https: // drck.я / патреон. Если у вас есть комментарии или предложения, присылайте их по адресу [email protected]. Спасибо за внимание, увидимся в следующий раз.
4759 сообщений, страница за страницей Ссылка на страницу… 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96 по 50 сообщений на странице Это это страница из архива «Horse’s Mouth» на Ссылка на домашнюю страницу Ezine (для чтения).
Вы можете Добавить комментарий или рейтинг к этой странице |
Разница между статическим, конечным, интерфейсным и абстрактным в PHP
Эта статья в основном знакомит с статическим, конечным, интерфейсом, аннотацией разницы в PHP, имеет определенное эталонное значение, теперь поделитесь со всеми, потребность в друзьях можно сослаться на
Финал
Если метод в родительском классе объявлен окончательным, дочерний класс не может перезаписать метод.Если класс объявлен окончательным, он не может быть унаследован.
Примечание: атрибуты не могут быть определены как окончательные, только классы и методы могут быть определены как окончательные.
Статический
Статическая переменная может быть локальной или глобальной переменной, когда сегмент программы завершен, статическая переменная не исчезает, она все еще существует в памяти, в следующий раз в определении или предыдущем значении, часто используется в рекурсивной или подфункция для сохранения предыдущего значения, может использоваться для определения переменных и методов, также используется одноэлементный режим;
1.Общие статические свойства используются для хранения общедоступных данных класса
2, статические методы могут обращаться только к статическим свойствам, включая класс и родительский класс
3, статические члены не нуждаются в создании экземпляра объекта, можно получить доступ
4. Доступ к статическим свойствам Внутри этого класса осуществляется доступ с помощью ключевого слова self или static, а переменные на задней стороне включают $, например: self: $ a или static :: $ a
5. Получите доступ к статическому свойству родительского класса с помощью parent, например: Parent :: $ name
6.Получите доступ к статическим переменным или методам вне класса, используя имя класса напрямую, без создания экземпляра. например: Me :: $ pan и Me :: abc ()
Аннотация
Абстрактный класс
1. Абстрактный класс — это класс, у которого есть ключевое слово abstract перед классом и метод абстракции (который добавляет ключевое слово abstract перед ключевым словом функции метода класса).
2. Абстрактные классы не могут быть созданы напрямую. Только методы, необходимые для определения (или частичной реализации) подклассов в абстрактном классе.Подклассы могут материализовать абстрактные классы, наследуя абстрактные классы и реализуя все абстрактные методы в абстрактном классе.
3. Если необходимо создать экземпляр подкласса, он реализует все абстрактные методы абстрактного класса. Если подкласс не полностью реализует все абстрактные методы в абстрактном классе, тогда подкласс является абстрактным классом, который должен предшествовать классу с ключевым словом abstract и не может быть создан.
4.Если подкласс реализует абстрактный метод, контроль доступа абстрактного метода в подклассе не может быть более строгим, чем контроль доступа абстрактного метода в родительском классе, то есть (родительский класс, подкласс B)
(1) если Abstract_func () в A объявлен общедоступным, то объявление Abstract_func () в B может быть только общедоступным, незащищенным или частным
(2) если Abstract_func () в A объявлен как защищенный, тогда объявление Abstract_func () в B может быть открытым или защищенным, но не закрытым.
(3) если Abstract_func () в A объявлен закрытым, он не может быть определен как закрытый! ( Неустранимая ошибка : абстрактная функция A :: abstract_func () не может быть объявлена частной)
Интерфейс
1.Абстрактные классы обеспечивают конкретную реализацию стандарта, а интерфейс является чисто шаблоном. Интерфейс определяет только функциональность, а не содержание реализации. Интерфейс объявлен с помощью ключевого слова interface.
2. Интерфейс полностью абстрактный, может только объявлять методы и может только объявлять методы общедоступного типа, не может объявлять частные и защищенные методы, не может определять тела методов и не может объявлять переменные экземпляра.
3.Интерфейс может объявлять постоянные переменные. Но размещение постоянной переменной в интерфейсе нарушает его цель быть интерфейсом и сбивает с толку разные значения интерфейса и класса. Если он вам действительно нужен, вы можете поместить его в соответствующий абстрактный класс или класс.
4. Любой класс, реализующий интерфейс, реализует все методы, определенные в интерфейсе, в противном случае класс должен быть объявлен абстрактным.
5. Класс может использовать ключевое слово Implements в объявлении для реализации интерфейса.После этого точный процесс реализации интерфейса будет таким же, как при наследовании абстрактного класса, который содержит только абстрактные методы.
6. Класс может наследовать родительский класс и одновременно реализовывать любое количество интерфейсов. Предложение extends должно предшествовать предложению Implements. PHP поддерживает наследование только от родительского класса, поэтому за ключевым словом extends может следовать только имя класса.
7. Интерфейсы не могут реализовать другой интерфейс, но могут наследовать несколько
Iii.сходства и различия абстрактных классов и интерфейсов
1. Там же:
(1) Оба являются абстрактными классами и не могут быть созданы.
(2) Подкласс класса реализации интерфейса и абстрактный класс должен реализовывать абстрактный метод, который уже был объявлен.
2. Различных точек:
Интерфейс
(1) необходимо реализовать, чтобы использовать инструменты, а абстрактный класс необходимо наследовать, чтобы использовать расширения.
(2) Класс может реализовывать несколько интерфейсов, но класс может наследовать только один абстрактный класс.
Интерфейс
(3) подчеркивает реализацию конкретной функции, в то время как абстрактный класс подчеркивает ее принадлежность.
(4) Хотя подкласс класса реализации интерфейса и абстрактный класс должны реализовывать соответствующий абстрактный метод, реализация отличается по форме. Каждый метод в интерфейсе является абстрактным методом, все только что объявленным (объявление, без тела метода), класс реализации должен быть реализован. Подкласс абстрактного класса может быть реализован выборочно.
Этот вариант подразумевает две точки:
A) Не все методы в абстрактном классе являются абстрактными, абстрагируются только те, в короне которых есть абстрактный, и должны быть реализованы подклассы. Те методы, которые не являются абстрактными, должны определять тело метода в абстрактном классе;
b) Когда подкласс абстрактного класса наследуется от него, неабстрактный метод может быть унаследован напрямую или перезаписан, тогда как для абстрактного метода вы можете реализовать его или оставить его подклассам, но этот класс должен также быть объявленным как абстрактный класс.Абстрактные классы и, конечно же, не могут быть созданы.
(5) Абстрактный класс является посредником между интерфейсом и классом. Абстрактный класс играет связующую роль в интерфейсе и классе.
С одной стороны, абстрактный класс является абстрактным и может использоваться для объявления методов абстракции для стандартизации функций, которые должны реализовывать подклассы;
С другой стороны, он может определять тело метода по умолчанию для подкласса, которое будет использовать или перезаписывать напрямую. Кроме того, он может определять свои собственные переменные экземпляра для использования подклассами посредством наследования.
(6) До того, как абстрактный метод в интерфейсе не может добавить ключевое слово abstract, по умолчанию неявный метод является абстрактным и не может добавлять ключевое слово final для предотвращения наследования абстрактных методов. Абстрактным методам в абстрактных классах должно предшествовать абстрактное представление, чтобы объявление отображалось как абстракция.
(7) Абстрактный метод в интерфейсе по умолчанию является общедоступным и может быть только общедоступным и не может быть украшен модификатором private, protected.Абстрактные методы в абстрактных классах могут быть изменены на общедоступные, защищенные, но не закрытые.
3. Интерфейсные приложения
(1) Классы и классы требуют определенного интерфейса для согласования, независимо от того, как они реализованы.
(2) как идентификатор, способный выполнять определенную функцию, он также может быть чистым идентификатором того, какой метод интерфейса не существует.
(3) Набор классов должен рассматриваться как один класс, и вызывающая сторона подключается к этому набору классов только через интерфейс.
(4) Необходимо реализовать определенное количество функций, и между этими функциями может вообще не быть связи.
4. Применение абстрактного класса
Одним словом, его можно использовать в ситуациях, когда требуется как единый интерфейс, так и переменная экземпляра или метод по умолчанию. Наиболее распространены:
(1) Определяет набор интерфейсов, но не хочет, чтобы каждый класс реализации реализовывал все интерфейсы. Вы можете использовать абстрактный класс для определения набора тел методов, даже пустого тела метода, а затем выбрать методы, которые вас интересуют для перезаписи подклассами.
(2) В некоторых случаях чисто интерфейсы не удовлетворяют координации между классами и классами, и переменные, которые представляют состояния в классе, должны различать разные отношения. Абстрактное посредничество может быть хорошим способом решить эту проблему.
(3) стандартизирует набор взаимно скоординированных методов, некоторые из которых являются общими, независимыми от состояния, совместно используемыми, без подклассов, а другие требуют отдельных подклассов для реализации определенных функций в соответствии с их конкретным состоянием.
Выше приведено все содержание этой статьи, я надеюсь, что обучение помогло всем, более релевантный контент, пожалуйста, обратите внимание на topic.