Форум программистов, компьютерный форум, киберфорум
PHP для начинающих
Войти
Регистрация
Восстановить пароль
Карта форума Темы раздела Блоги Сообщество Поиск Заказать работу  
 
34 / 10 / 2
Регистрация: 20.02.2016
Сообщений: 1,564
1

Когда в классе функция должна прописываться как static?

04.01.2020, 20:28. Показов 420. Ответов 2
Метки нет (Все метки)

Author24 — интернет-сервис помощи студентам
Добрых суток!
Ниже класс со статическим свойством. В каких случаях нужно прописывать функции в таких классах как статик?
Есть какие-то правила на этот счёт?
PHP
1
2
3
4
5
6
7
8
9
 class Counter
  {
      private static $count = 0;
public function __construct() { self::$count++; }
      
 //а тут можно ведь было прописать как public function getCount() без static 
    public static function getCount() { return self::$count; }
  
  }
0
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
04.01.2020, 20:28
Ответы с готовыми решениями:

Как работают static-переменные объявленные в в базовом классе?
Информации увидел много, но суть так и не могу уловить. Образовалась пара вопросов: 1. Если я...

Как объявить в классе static-массив, не используя cpp файлы
Есть шаблон. В шаблон в качестве аргумента надо передать массив. Именно в качестве аргумента...

Вывод static текста, когда курсор находится НАД контролом. как?
нужно научиться получать сообщения когда курсор находится над каком нибудь из контролов. пример во...

Когда запускаю и ввожу параметры, то, в момент когда программа должна выполнять действие, пишет ошибку
Недавно начали изучать c++. так как в школе не было программирования (преподу пофиг было) я в...

2
1992 / 1216 / 440
Регистрация: 13.06.2013
Сообщений: 4,115
04.01.2020, 21:12 2
Все просто: объект - много состояний, статика - одно состояние.
Например в вашем случае только один счетчик, а если понадобится несколько независимых?
0
2232 / 1278 / 611
Регистрация: 23.08.2015
Сообщений: 3,228
05.01.2020, 00:10 3
Fatmarmelad, Сейчас попытаюсь вас запутать) Как правило если метод не использует создаваемый объект, т.е. $this, то это кандидат на static. Правда нужно учитывать, что $this в какой-то момент времени может появиться, если мы захотим как-то конфигурировать наш объект.
Вообще каких-либо правил нет. Главное понимать как это работает, а как вы уже будете это использовать - ваше дело.

Конечно это слабо относится к вашему примеру, но раз уж мы заговорили о статике, то мне показалось необходимым разъяснить некоторый важный аспект, чтоб вы понимали)
Давайте рассмотрим на примере. Допустим у нас есть некий калькулятор.

PHP
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
class Calculator
{
    public function calculate(array $items) 
    {
        $sum = 0;
        foreach ($items as $item) {
            $sum += $item->getPrice() * $item->getQuantity();
        }
        
        if ($sum >= 1000) {
            $sum *= 0.95;
        }
        
        return $sum;
    }
}
Если сумма больше 1000, то делаем 5-ти процентную скидку. Он не использует $this, и метод вполне бы мог статическим.
Теперь мы бы хотели протестировать данный объект и понимаем, что значение скидки и порог может часто меняться. Сегодня 5 процентов, а завтра 3. Тогда нам нужно будет менять не только сам объект, но и его тесты. Чтоб этого избежать, допустим мы можем их вынести как параметры метода.

PHP
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
class Calculator
{
    public function calculate(array $items, int $limit, int $percent)
    {
        $sum = 0;
        foreach ($items as $item) {
            $sum += $item->getPrice() * $item->getQuantity();
        }
 
        if ($sum >= $limit) {
            $sum *= (100 - $percent)/100;
        }
 
        return $sum;
    }
}
Теперь мы можем протестировать данный объект и вроде бы все хорошо. Но тут возникает следующая ситуация.

PHP
1
2
3
4
5
6
7
8
9
10
class Cart
{
    private $items = [];
    
    public function getTotal()
    {
        $calculator = new Calculator();
        return $calculator->calculate($this->items, 1000, 5);
    }
}
Как видите, здесь метод calculate мог бы быть статическим, но это не суть, теперь у нас проблема с тестированием самого объекта Cart. Если меняются условия скидок, то мы должны изменять класс Cart и соответственно его тесты, что не очень то удобно. Какой выход из ситуации?

PHP
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
class Calculator
{
    private $limit;
    private $percent;
    
    public function __construct(int $limit, int $percent)
    {
        $this->limit = $limit;
        $this->percent = $percent;
    }
 
    public function calculate(array $items)
    {
        $sum = 0;
        foreach ($items as $item) {
            $sum += $item->getPrice() * $item->getQuantity();
        }
 
        if ($sum >= $this->limit) {
            $sum *= (100 - $this->percent)/100;
        }
 
        return $sum;
    }
}
 
class Cart
{
    private $items = [];
    private $calculator;
    
    public function __construct(Calculator $calculator)
    {
        $this->calculator = $calculator;
    }
 
    public function getTotal()
    {
        return $this->calculator->calculate($this->items);
    }
}
 
$cart = new Cart(new Calculator(1000, 5));
Теперь как видите, сам Cart ничего не знает, какие параметры требуется передать в калькулятор. Параметры для калькулятора передаются в одном месте, а вызываются совершенно в другом. И каждый из классов можно легко протестировать.

Более того, если абстрагироваться от конкретной реализации Калькулятора, и перейти на интерфейс, то тогда в класс Cart мы сможем подставлять любые калькуляторы, даже вложенные, так как мы захотим.

PHP
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
interface CalculatorInterface
{
    public function calculate(array $items): int;
}
 
class Cart
{
    private $items = [];
    private $calculator;
 
    public function __construct(CalculatorInterface $calculator)
    {
        $this->calculator = $calculator;
    }
 
    public function getTotal()
    {
        return $this->calculator->calculate($this->items);
    }
}
 
$cart = new Cart(
    new DeliveryCalculator(
        new BonusCalculator(
            new CouponCalculator(
                new SimpleCalculator()
            )
        )
    )
);
Как видите из изначального метода, который мог быть статическим, мы перешли к довольно гибкой системе благодаря возможности конфигурирования объектов. Зачастую статические методы не особо приветствуются и считаются анти паттернами (там всякие синглтоны и т.п.), но вполне могут использоваться во всяких хелперах, как правило это просто набор низкоуровневых функций, объединенные в статический класс, что к ООП не имеет никакого отношения.
0
05.01.2020, 00:10
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
05.01.2020, 00:10
Помогаю со студенческими работами здесь

У меня класс B в классе A, а в классе B рекурсивная функция переопределения оператора "()", как её вызвать, не создавая явно объект класса B?
#include <windows.h> #include <iostream> using namespace std; //Вот главный класс class A{...

Как прописываться в RUN реестра при запуске?
Помогите решить проблему, надо чтобы прога, при первом запуске, прописывалась в RUN реестра. Ответ...

Static переменная в классе
Не могу понять, как задавать статическую переменную в классе (и методы класса для ее обработки)....

MFC и static указатель в классе
Под него надо динамически выделить память но компилятор ругается class Kniga { private:...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
3
Ответ Создать тему
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2024, CyberForum.ru