Форум программистов, компьютерный форум, киберфорум
ООП и паттерны
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск  
 
 
Рейтинг 4.92/84: Рейтинг темы: голосов - 84, средняя оценка - 4.92
0 / 0 / 0
Регистрация: 02.10.2019
Сообщений: 20

Объясните понятие ООП

13.02.2020, 23:25. Показов 21465. Ответов 242

Студворк — интернет-сервис помощи студентам
Скажите пожалуйста понятным языком, что такое объектно-ориентированное программирование ?
0
Programming
Эксперт
39485 / 9562 / 3019
Регистрация: 12.04.2006
Сообщений: 41,671
Блог
13.02.2020, 23:25
Ответы с готовыми решениями:

Понятие ООП
Доброго времени суток! Пытаюсь вникнуть в ООП после длительного написания кода в процедурном стиле, и это не так просто =( Хочу...

Объясните понятие изоморфизма двух алгебр (на примере)
Кто нибудь, объясните мне понятие изоморфизма двух алгебр на примере. Или дайте источник информации (я искал -- толкового ничего не нашёл)....

Дать понятие понятие НОК в кольце целых чисел
Дать понятие понятие НОК в кольце целых чисел.

242
Эксперт функциональных языков программированияЭксперт Java
 Аватар для korvin_
4576 / 2775 / 491
Регистрация: 28.04.2012
Сообщений: 8,782
05.09.2020, 13:58
Студворк — интернет-сервис помощи студентам
vantfiles, у тебя методы класса не виртуальные, vmt для них не строится, вызов не косвенный, что с чем ты пытаешься сравнить?

Добавлено через 1 час 28 минут
vantfiles, вот правильный пример:

C++
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
#include <chrono>
#include <stdio.h>
 
long f1(size_t i)
{
    return i * i;
}
 
void f3(long* arr, size_t size)
{
    for (size_t i = 0; i < size; i++) {
         arr[i] = f1(i);
    }
}
 
class Static
{
public:
    long f1(size_t i)
    {
        return i * i;
    }
 
    void f3(long* arr, size_t size)
    {
        for (size_t i = 0; i < size; i++) {
             arr[i] = f1(i);
        }
    }
};
 
class Dynamic
{
public:
    virtual long f1(size_t i)
    {
        return i * i;
    }
 
    virtual void f3(long* arr, size_t size)
    {
        for (size_t i = 0; i < size; i++) {
             arr[i] = f1(i);
        }
    }
};
 
const size_t SZ = 10000;
 
int main()
{
    long arr[SZ];
    Static s;
    Dynamic* d = new Dynamic();
 
    // Test 1 ------------------------------------------------------
 
    auto start = std::chrono::high_resolution_clock::now();
    for (int i = 0; i < 1000; i++) {
        f3(arr, SZ);
    }
    auto finish = std::chrono::high_resolution_clock::now();
    std::chrono::duration<double> elapsed = finish - start;
 
    double base_elapsed = elapsed.count();
 
    printf("T1: %.6f    %7.3f%%    arr[last] = %ld\n", elapsed.count(), 100.0, arr[SZ-1]);
 
    // Test 2 ------------------------------------------------------
 
    start = std::chrono::high_resolution_clock::now();
    for (int i = 0; i < 1000; i++) {
        s.f3(arr, SZ);
    }
    finish = std::chrono::high_resolution_clock::now();
    elapsed = finish - start;
 
    printf("T2: %.6f    %7.3f%%    arr[last] = %ld\n", elapsed.count(), elapsed.count()/base_elapsed*100, arr[SZ-1]);
 
    // Test 3 ------------------------------------------------------
 
    start = std::chrono::high_resolution_clock::now();
    for (int i = 0; i < 1000; i++) {
        d->f3(arr, SZ);
    }
    finish = std::chrono::high_resolution_clock::now();
    elapsed = finish - start;
 
    printf("T3: %.6f    %7.3f%%    arr[last] = %ld\n", elapsed.count(), elapsed.count()/base_elapsed*100, arr[SZ-1]);
 
    return 0;
}
Code
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
$ g++ -o methodcall -O0 -std=c++2a methodcall.cpp
 
❯❯❯ ./methodcall
T1: 0.023052    100.000%    arr[last] = 99980001
T2: 0.022681     98.389%    arr[last] = 99980001
T3: 0.025849    112.132%    arr[last] = 99980001
 
❯❯❯ ./methodcall
T1: 0.026103    100.000%    arr[last] = 99980001
T2: 0.026463    101.382%    arr[last] = 99980001
T3: 0.025587     98.024%    arr[last] = 99980001
 
❯❯❯ ./methodcall
T1: 0.027083    100.000%    arr[last] = 99980001
T2: 0.026986     99.642%    arr[last] = 99980001
T3: 0.027195    100.414%    arr[last] = 99980001
 
❯❯❯ ./methodcall
T1: 0.027602    100.000%    arr[last] = 99980001
T2: 0.028086    101.756%    arr[last] = 99980001
T3: 0.027857    100.926%    arr[last] = 99980001
 
❯❯❯ ./methodcall
T1: 0.025233    100.000%    arr[last] = 99980001
T2: 0.026486    104.964%    arr[last] = 99980001
T3: 0.025583    101.387%    arr[last] = 99980001
 
❯❯❯ ./methodcall
T1: 0.027030    100.000%    arr[last] = 99980001
T2: 0.026915     99.573%    arr[last] = 99980001
T3: 0.025586     94.656%    arr[last] = 99980001
как видишь, результаты примерно одинаковый, различия в рамках погрешности (даже не всегда в пользу свободной функции, лол)

Вот вариант с использованием полей объекта:

C++
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
97
98
99
100
#include <chrono>
#include <stdio.h>
 
long f1(size_t i)
{
    return i * i;
}
 
void f3(long* arr, size_t size)
{
    for (size_t i = 0; i < size; i++) {
         arr[i] = f1(i);
    }
}
 
class Static
{
private:
    long *arr;
    size_t size;
public:
    Static(long *arr, size_t size) : arr(arr), size(size) {}
    long f1(size_t i)
    {
        return i * i;
    }
 
    void f3()
    {
        for (size_t i = 0; i < size; i++) {
             this->arr[i] = f1(i);
        }
    }
};
 
class Dynamic
{
private:
    long *arr;
    size_t size;
public:
    Dynamic(long *arr, size_t size) : arr(arr), size(size) {}
    virtual long f1(size_t i)
    {
        return i * i;
    }
 
    virtual void f3()
    {
        for (size_t i = 0; i < size; i++) {
             this->arr[i] = f1(i);
        }
    }
};
 
const size_t SZ = 10000;
 
int main()
{
    long arr[SZ];
    Static s(arr, SZ);
    Dynamic* d = new Dynamic(arr, SZ);
 
    // Test 1 ------------------------------------------------------
 
    auto start = std::chrono::high_resolution_clock::now();
    for (int i = 0; i < 1000; i++) {
        f3(arr, SZ);
    }
    auto finish = std::chrono::high_resolution_clock::now();
    std::chrono::duration<double> elapsed = finish - start;
 
    double base_elapsed = elapsed.count();
 
    printf("T1: %.6f    %7.3f%%    arr[last] = %ld\n", elapsed.count(), 100.0, arr[SZ-1]);
 
    // Test 2 ------------------------------------------------------
 
    start = std::chrono::high_resolution_clock::now();
    for (int i = 0; i < 1000; i++) {
        s.f3();
    }
    finish = std::chrono::high_resolution_clock::now();
    elapsed = finish - start;
 
    printf("T2: %.6f    %7.3f%%    arr[last] = %ld\n", elapsed.count(), elapsed.count()/base_elapsed*100, arr[SZ-1]);
 
    // Test 3 ------------------------------------------------------
 
    start = std::chrono::high_resolution_clock::now();
    for (int i = 0; i < 1000; i++) {
        d->f3();
    }
    finish = std::chrono::high_resolution_clock::now();
    elapsed = finish - start;
 
    printf("T3: %.6f    %7.3f%%    arr[last] = %ld\n", elapsed.count(), elapsed.count()/base_elapsed*100, arr[SZ-1]);
 
    return 0;
}
Code
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
❯❯❯ ./methodcall
T1: 0.023823    100.000%    arr[last] = 99980001
T2: 0.025361    106.456%    arr[last] = 99980001
T3: 0.029231    122.702%    arr[last] = 99980001
 
❯❯❯ ./methodcall
T1: 0.026517    100.000%    arr[last] = 99980001
T2: 0.030707    115.798%    arr[last] = 99980001
T3: 0.028318    106.790%    arr[last] = 99980001
 
❯❯❯ ./methodcall
T1: 0.026821    100.000%    arr[last] = 99980001
T2: 0.030251    112.791%    arr[last] = 99980001
T3: 0.028290    105.476%    arr[last] = 99980001
 
❯❯❯ ./methodcall
T1: 0.026909    100.000%    arr[last] = 99980001
T2: 0.030269    112.488%    arr[last] = 99980001
T3: 0.028222    104.880%    arr[last] = 99980001
 
❯❯❯ ./methodcall
T1: 0.026950    100.000%    arr[last] = 99980001
T2: 0.030540    113.319%    arr[last] = 99980001
T3: 0.029061    107.830%    arr[last] = 99980001
 
❯❯❯ ./methodcall
T1: 0.026921    100.000%    arr[last] = 99980001
T2: 0.030649    113.849%    arr[last] = 99980001
T3: 0.029804    110.708%    arr[last] = 99980001
 
❯❯❯ ./methodcall
T1: 0.026011    100.000%    arr[last] = 99980001
T2: 0.030298    116.479%    arr[last] = 99980001
T3: 0.029780    114.487%    arr[last] = 99980001
 
❯❯❯ ./methodcall
T1: 0.026207    100.000%    arr[last] = 99980001
T2: 0.030322    115.703%    arr[last] = 99980001
T3: 0.029556    112.780%    arr[last] = 99980001
На этот раз обращение к this внесло дополнительный уровень адресации и свободная функция вырвалась вперёд.
Однако вызов виртуальной функции показал лучшие результаты, чем вызов невиртуальной, кроме первого запуска, в чём причина другого поведения запусков — не знаю. Если удалить исполняемый файл, снова скомпилировать и запустить, поведение повторяется.

Добавлено через 1 час 0 минут
vantfiles, и ещё, похоже 1000 итераций — маловато, чтобы заметить какую-то разницу

C++
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
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
#include <chrono>
#include <string>
#include <stdexcept>
#include <stdio.h>
 
long f1(size_t i)
{
    return i * i;
}
 
void f3(long* arr, size_t size)
{
    for (size_t i = 0; i < size; i++) {
         arr[i] = f1(i);
    }
}
 
class StaticArgs
{
public:
    long f1(size_t i)
    {
        return i * i;
    }
 
    void f3(long *arr, size_t size)
    {
        for (size_t i = 0; i < size; i++) {
             arr[i] = f1(i);
        }
    }
};
 
class DynamicArgs
{
public:
    virtual long f1(size_t i)
    {
        return i * i;
    }
 
    virtual void f3(long *arr, size_t size)
    {
        for (size_t i = 0; i < size; i++) {
             arr[i] = f1(i);
        }
    }
};
 
class StaticFields
{
private:
    long *arr;
    size_t size;
public:
    StaticFields(long *arr, size_t size) : arr(arr), size(size) {}
    long f1(size_t i)
    {
        return i * i;
    }
 
    void f3()
    {
        for (size_t i = 0; i < size; i++) {
             arr[i] = f1(i);
        }
    }
};
 
class DynamicFields
{
private:
    long *arr;
    size_t size;
public:
    DynamicFields(long *arr, size_t size) : arr(arr), size(size) {}
    virtual long f1(size_t i)
    {
        return i * i;
    }
 
    virtual void f3()
    {
        for (size_t i = 0; i < size; i++) {
             arr[i] = f1(i);
        }
    }
};
 
const size_t SZ = 10000;
 
int main(int argc, char** argv)
{
    if (argc != 3) {
        printf("Usage: %s <array-size> <runs-count>\n", argv[0]);
        return 1;
    }
 
    size_t size = 10000;
    int runs = 10000;
 
    try {
        size = std::stoi(argv[1]);
        runs = std::stoi(argv[2]);
    } catch (std::invalid_argument e) {
        printf("Invalid argument format\n");
        return 1;
    } catch (std::out_of_range e) {
        printf("Argument out of range\n");
        return 2;
    }
    if ((size < 1) || (runs < 1)) {
        printf("Argument out of range\n");
        return 2;
    }
 
    printf("Array size = %ld\n", size);
    printf("Runs count = %d\n", runs);
 
    long* arr = new long[size];
    StaticArgs staargs;
    DynamicArgs* dynargs = new DynamicArgs();
    StaticFields stafields(arr, size);
    DynamicFields* dynfields = new DynamicFields(arr, size);
 
    // Test free func ------------------------------------------------------
 
    auto start = std::chrono::high_resolution_clock::now();
    for (int i = 0; i < runs; i++) {
        f3(arr, size);
    }
    auto finish = std::chrono::high_resolution_clock::now();
    std::chrono::duration<double> elapsed = finish - start;
 
    double base_elapsed = elapsed.count();
 
    printf("Free function:  %.6f    %7.3f%%     arr[last] = %ld\n",
        base_elapsed, 100.0, arr[size-1]);
 
    // Test static args ------------------------------------------------------
 
    start = std::chrono::high_resolution_clock::now();
    for (int i = 0; i < runs; i++) {
        staargs.f3(arr, size);
    }
    finish = std::chrono::high_resolution_clock::now();
    elapsed = finish - start;
 
    double sargs_elapsed = elapsed.count();
 
    printf("Static args:    %.6f    %7.3f%%    arr[last] = %ld\n",
        sargs_elapsed, sargs_elapsed/base_elapsed*100, arr[size-1]);
 
    // Test dynamic args ------------------------------------------------------
 
    start = std::chrono::high_resolution_clock::now();
    for (int i = 0; i < runs; i++) {
        dynargs->f3(arr, SZ);
    }
    finish = std::chrono::high_resolution_clock::now();
    elapsed = finish - start;
 
    double dargs_elapsed = elapsed.count();
 
    printf("Dynamic args:   %.6f    %7.3f%%    arr[last] = %ld\n",
        dargs_elapsed, dargs_elapsed/base_elapsed*100, arr[size-1]);
 
    // Test static fields ------------------------------------------------------
 
    start = std::chrono::high_resolution_clock::now();
    for (int i = 0; i < runs; i++) {
        stafields.f3();
    }
    finish = std::chrono::high_resolution_clock::now();
    elapsed = finish - start;
 
    double sfields_elapsed = elapsed.count();
 
    printf("Static fields:  %.6f    %7.3f%%    arr[last] = %ld\n",
        sfields_elapsed, sfields_elapsed/base_elapsed*100, arr[size-1]);
 
    // Test dynamic fields ------------------------------------------------------
 
    start = std::chrono::high_resolution_clock::now();
    for (int i = 0; i < runs; i++) {
        dynfields->f3();
    }
    finish = std::chrono::high_resolution_clock::now();
    elapsed = finish - start;
 
    double dfields_elapsed = elapsed.count();
 
    printf("Dynamic fields: %.6f    %7.3f%%    arr[last] = %ld\n",
        dfields_elapsed, dfields_elapsed/base_elapsed*100, arr[size-1]);
 
    return 0;
}
вот на 10000 результат уже более заметен и стабилен:
Code
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
❯❯❯ ./methodcall 10000 1000
Array size = 10000
Runs count = 1000
Free function:  0.023852    100.000%    arr[last] = 99980001
Static args:    0.023553     98.746%    arr[last] = 99980001
Dynamic args:   0.025602    107.337%    arr[last] = 99980001
Static fields:  0.026791    112.323%    arr[last] = 99980001
Dynamic fields: 0.028071    117.690%    arr[last] = 99980001
 
❯❯❯ ./methodcall 10000 1000
Array size = 10000
Runs count = 1000
Free function:  0.025828    100.000%    arr[last] = 99980001
Static args:    0.026147    101.238%    arr[last] = 99980001
Dynamic args:   0.025122     97.269%    arr[last] = 99980001
Static fields:  0.026146    101.234%    arr[last] = 99980001
Dynamic fields: 0.027677    107.161%    arr[last] = 99980001
 
❯❯❯ ./methodcall 10000 10000
Array size = 10000
Runs count = 10000
Free function:  0.214029    100.000%    arr[last] = 99980001
Static args:    0.224531    104.907%    arr[last] = 99980001
Dynamic args:   0.250485    117.033%    arr[last] = 99980001
Static fields:  0.254884    119.088%    arr[last] = 99980001
Dynamic fields: 0.276227    129.060%    arr[last] = 99980001
 
❯❯❯ ./methodcall 10000 10000
Array size = 10000
Runs count = 10000
Free function:  0.206832    100.000%    arr[last] = 99980001
Static args:    0.222640    107.643%    arr[last] = 99980001
Dynamic args:   0.250767    121.242%    arr[last] = 99980001
Static fields:  0.254198    122.901%    arr[last] = 99980001
Dynamic fields: 0.281396    136.051%    arr[last] = 99980001
 
❯❯❯ ./methodcall 10000 10000
Array size = 10000
Runs count = 10000
Free function:  0.213943    100.000%    arr[last] = 99980001
Static args:    0.222208    103.863%    arr[last] = 99980001
Dynamic args:   0.252490    118.017%    arr[last] = 99980001
Static fields:  0.256496    119.889%    arr[last] = 99980001
Dynamic fields: 0.275529    128.786%    arr[last] = 99980001
2
 Аватар для neya
4 / 3 / 1
Регистрация: 30.08.2019
Сообщений: 37
13.10.2020, 12:40
По-моему, основа ООП - абстрагирование. Это может быть подъём по уровням абстракций - от языка решения задачи - к языку самой задачи.
В философском смысле, объект это субстанция – носитель своих собственных свойств (и методов), не зависящий (и не зависящих) от иного. А принцип устройства объекта – это класс.

Переход от конкретного объекта - к принципам устройства группы объектов – это абстрагирование. Чем, собственно, и занимается программист, приступая к объектно-ориентированному проектированию.
Здесь и оправданность применения ООП: если задача не помещается в голову, её можно попробовать описать в таких сущностях, которые в голову поместятся.

Полиморфизм. Один метод "добавь" - к числу или к строке; или число к строке. В зависимости от того, с чем будет иметься дело: с числом или строкой - будет разная реализация метода, но он всегда будет назваться одинаково, одинаково вызываться - имея при этом разное содержание. Так решение задачи сводится к языку высокого уровня: "здесь объекты складываются" (неважно как), это определяет реализация метода для конкретного случая.
Это позволяет разделить задачу по уровням сложности - или специализации программистов. То есть, ещё и форма разделения задач.

Правильный идеальный объект - предмет целостный, вещь-в-себе, действующая за счёт собственных ресурсов - данных и методов. Это даёт чёткость структуры и защиту от случайных влияний.
Правильный объект сам обеспечивает протоколы своего взаимодействия с внешним миром – таки образом, чтобы это взаимодействие было предсказуемым и безопасным.

Суть наследования – использование части уже проделанной работы.
0
Заблокирован
13.10.2020, 12:55
Цитата Сообщение от neya Посмотреть сообщение
Переход от конкретного объекта - к принципам устройства группы объектов – это абстрагирование.
Я не специалист в ООП, но на базе "общей эрудиции", замечу, что и сам объект - это тоже абстракция. А класс данного объекта - тем паче абстракция. В программировании всё абстракция (как и в математике). А абстракция, есественно, является результатом абстрагирования (метода человеческого мышления).
0
 Аватар для neya
4 / 3 / 1
Регистрация: 30.08.2019
Сообщений: 37
13.10.2020, 14:15
Абстракция, о которой имеет смысл говорить, это всегда абстракция над чем-то. Поэтому упомянуты уровни абстракции.
В том смысле, о котором я говорил, класс - абстракция над объектом, который относительно класса - конкретика: конкретные значения свойств, конкретные методы, и они все запакованы в конкретный объект, экземпляр класса.

Вот класс:

Python
1
2
3
4
5
6
7
class C:
    def meth(self):
        print('hello1')
x = C()
y = C()
print(x)
print(y)
Результат выполнения:

<__main__.C object at 0x000001508C94EE20>
<__main__.C object at 0x000001508C9E27F0>

Видите в конце идентификаторы объектов?
Они уникальны, это и есть конкретика.

А если распечатать сам класс, будет:

<class '__main__.C'>

Это абстракция.
0
Заблокирован
13.10.2020, 14:45
Википедия:
Абстра́кция (лат. abstractio — отвлечение[1]) — теоретическое обобщение как результат абстрагирования.
Абстрагирование — отвлечение в процессе познания от несущественных сторон, свойств, связей объекта (предмета или явления) с целью выделения их существенных, закономерных признаков.
В этом смысле не только класс, но и экземпляр класса - абстракция. Это всё абстрактные понятия, являющиеся применением метода абстрагирования к некой предметной области.
При этом, уровни абстракции, разумеется, можно выделять.
Если теоретизировать (я-то точно этим заниматься не буду), то нужно точно определять понятия и, при этом, следовать канве общепринятых в некой области знания смыслов.
В том числе - понятия абстрактного и конкретного.
Да, экземпляр класса по отношению к классу конкретен. Но он же абстрактен по отношению к сущностям предметной области.
Я отреагировал вот на это:
Цитата Сообщение от neya Посмотреть сообщение
Переход от конкретного объекта - к принципам устройства группы объектов – это абстрагирование. Чем, собственно, и занимается программист, приступая к объектно-ориентированному проектированию.
Здесь и оправданность применения ООП: если задача не помещается в голову, её можно попробовать описать в таких сущностях, которые в голову поместятся.
Вот тут, как мне кажется, ошибка.
Абстракция класса рождается не при переходе от экземпляра класса к более высокому уровню абстрагирования (классу), а при анализе и применении метода абстрагирования к предметной области.
То есть, тут цепочка такая: "предметная область" - "система классов" - "экземпляры классов".
Классы, как объекты абстрактного появляются при анализе предметной области. А не при переходе от экземпляра класса к классу.
Возможно, что именно это Вы и имели ввиду. Но тогда нужно было сразу точно определить что такое объект. Если речь в рамках ООП, то объект - это экземпляр класса). И тогда абстрагирвание от объекта к классу - это вырожденное, умозрительное абстрагирование, а не метод мышления, как метод познания.
Абстрагирование как метод познания, на мой взгляд, идёт по другой цепочке, я выше написал как.
Однако, во втором сообщении вы написали:
Цитата Сообщение от neya Посмотреть сообщение
В том смысле, о котором я говорил, класс - абстракция над объектом, который относительно класса - конкретика: конкретные значения свойств, конкретные методы, и они все запакованы в конкретный объект, экземпляр класса.
Из этого следует, что вы понимаете под объектом именно экземпляр класса или нет?)
Я, с вашего позволения, откланяюсь, предоставлю право продолжения диалога более осведомленным в ООП участникам.
0
 Аватар для neya
4 / 3 / 1
Регистрация: 30.08.2019
Сообщений: 37
13.10.2020, 15:13
Правильная работа с объектной моделью приближает язык решения задачи - к языку самой задачи. Такое продвижение языка - и есть абстрагирование.
0
 Аватар для vantfiles
1018 / 1921 / 177
Регистрация: 07.05.2013
Сообщений: 3,931
Записей в блоге: 12
13.10.2020, 15:29
"Прототипное программирование — стиль объектно-ориентированного программирования, при котором отсутствует понятие класса, а наследование производится путём клонирования существующего экземпляра объекта — прототипа. Каноническим примером прототип-ориентированного языка является язык Self."

Более того, сам объект может быть собран динамически, в зависимости от текущей задачи - то есть даже прототипа не иметь.

Единственное, что во всех моделях ооп можно имхо выделить - это структура.

"Структура - это расположение и организация взаимосвязанных элементов в материальном объекте или системе или объекте или системе, организованной таким образом."
0
Модератор
Эксперт функциональных языков программирования
3140 / 2288 / 469
Регистрация: 26.03.2015
Сообщений: 8,898
13.10.2020, 15:51
Цитата Сообщение от neya Посмотреть сообщение
По-моему, основа ООП - абстрагирование.
Абстрагирование - основа любой (или почти любой?) парадигмы программирования.
"Собака - это млекопитающее с четрымя лапами и хвостом". С одной стороны - верно, с другой стороны - бесполезно, так как не вносит ясности (большинство млекопитающих имеют четрые лапы и хвост).

Цитата Сообщение от neya Посмотреть сообщение
Полиморфизм. Один метод "добавь" - к числу или к строке; или число к строке. В зависимости от того, с чем будет иметься дело: с числом или строкой - будет разная реализация метода, но он всегда будет назваться одинаково, одинаково вызываться - имея при этом разное содержание.
Старый добрый Си и перегрузка функций. Причём тут ООП?
Полиморфизм бывает разный. В ООП используется полиморфизм подтипов.
0
Эксперт функциональных языков программированияЭксперт Java
 Аватар для korvin_
4576 / 2775 / 491
Регистрация: 28.04.2012
Сообщений: 8,782
13.10.2020, 16:46
Цитата Сообщение от Shamil1 Посмотреть сообщение
Старый добрый Си и перегрузка функций
В Си нет перегрузки функций, ЕМНИП. Может, в последних версиях появилась? Но в «старом добром» точно нет. )
1
 Аватар для neya
4 / 3 / 1
Регистрация: 30.08.2019
Сообщений: 37
13.10.2020, 17:02
Цитата Сообщение от Shamil1 Посмотреть сообщение
Абстрагирование - основа любой (или почти любой?) парадигмы программирования.
В чём заключается объектно-ориентированное проектирование в случаях императивной и функциональной парадигмы?
0
Эксперт функциональных языков программированияЭксперт Java
 Аватар для korvin_
4576 / 2775 / 491
Регистрация: 28.04.2012
Сообщений: 8,782
13.10.2020, 17:24
Цитата Сообщение от neya Посмотреть сообщение
В чём заключается объектно-ориентированное проектирование в случаях императивной и функциональной парадигмы?
При чём тут объектно-ориентированное проектирование? Абстрагирование — общее понятие, не привязанное к ООП.
1
 Аватар для neya
4 / 3 / 1
Регистрация: 30.08.2019
Сообщений: 37
13.10.2020, 18:50
Цитата Сообщение от korvin_ Посмотреть сообщение
Абстрагирование — общее понятие, не привязанное к ООП
Чем абстрагирование в императивной и функциональной парадигме отличается от объектно-ориентированного подхода?

Добавлено через 19 минут
В чём заключается абстрагирование, не привязанное к объектно-ориентированному проектированию?
0
Заблокирован
13.10.2020, 19:02
Википедия
Абстрагирование — отвлечение в процессе познания от несущественных сторон, свойств, связей объекта (предмета или явления) с целью выделения их существенных, закономерных признаков.
0
 Аватар для vantfiles
1018 / 1921 / 177
Регистрация: 07.05.2013
Сообщений: 3,931
Записей в блоге: 12
13.10.2020, 19:12
Цитата Сообщение от neya Посмотреть сообщение
В чём заключается абстрагирование, не привязанное к объектно-ориентированному проектированию?
Процедурная абстракция
Абстракция через параметризацию
Абстракция через спецификацию
Абстракция данных
0
 Аватар для neya
4 / 3 / 1
Регистрация: 30.08.2019
Сообщений: 37
13.10.2020, 20:47
Постулируете абстрагирование, не связанное с объектно-ориентированным мышлением?
0
Эксперт функциональных языков программированияЭксперт Java
 Аватар для korvin_
4576 / 2775 / 491
Регистрация: 28.04.2012
Сообщений: 8,782
13.10.2020, 23:25
Цитата Сообщение от neya Посмотреть сообщение
Чем абстрагирование в императивной и функциональной парадигме отличается от объектно-ориентированного подхода?
Концепциями и инструментами. // К. О.
1
820 / 579 / 75
Регистрация: 20.09.2014
Сообщений: 3,814
14.10.2020, 07:42
Цитата Сообщение от neya Посмотреть сообщение
Постулируете абстрагирование, не связанное с объектно-ориентированным мышлением?
Абстрагирование - это замена некоторой (как правило, сложной) программной конструкции на одно простое имя.

1. В императивной парадигме нет другого абстрагирования, кроме именования переменных.
2. В процедурной парадигме ряд инструкций заменяется на процедуру (функцию) и ей дается имя. Это абстрагирование!
3. Структурное программирование (как я понимаю) - это то же самое процедурное программирование, в котором не используется goto.
4. В ООП функциям и переменным дается общее имя и это называется объектом.

То есть фактически абстрагированием является:
1. Присвоение имени ячейкам памяти (имена переменных)
2. Присвоение имени набору последовательных инструкций (имена функций) - при этом допускается вложение в одну функции других функций
3. Присвоение имени группе переменных (имена структур) - при этом допускается вложение в одну структуру других структур
4. Присвоение имени переменным и функциям (имена объектов)

Просто ООП замкнул все необходимые виды абстрагирования (с 1-го по 4-й), на самом деле его нет смысла сравнивать со структурным программированием, в котором нет п.4.

Добавлено через 16 минут
Забыл подписать, что объекты могут включать себя другие объекты.

Далее пошли:
Для п.2 и 4 имеет смысл полиморфизма.
Для п.3 и 4 появляется смысл наследования.
Для п.4 появляется смысл инкапсуляции.

Как видно, ООП просто взял в себя все рюшечки для абстрактного программирования, однако, вы можете их не использовать.
1
Эксперт функциональных языков программированияЭксперт Java
 Аватар для korvin_
4576 / 2775 / 491
Регистрация: 28.04.2012
Сообщений: 8,782
14.10.2020, 10:02
Цитата Сообщение от Mikhaylo Посмотреть сообщение
4. В ООП функциям и переменным дается общее имя и это называется объектом.
А если я даю общее имя переменным и функциям, объединённым в виде модуля, а не объекта, это какой пункт?
0
 Аватар для neya
4 / 3 / 1
Регистрация: 30.08.2019
Сообщений: 37
14.10.2020, 10:38
Простите если усмотрите офтоп, но не удержался, принёс с Хабра:
"Каждое интервью я начинаю с очень простого и основного вопроса:

— Что такое класс в Ruby, что такое модуль, в чем их отличия и для чего они нужны?

Вы бы удивились, узнав, как много людей на самом деле не знает ответа на этот вопрос! И это люди, которые хотят стать разработчиками программного обеспечения. Все они могут создать блог с постами и комментариями в считанные минуты — и на этом все. Был у меня один кандидат, на должность mid разработчика, который утверждал, что работал в течение года над клиентским приложением в качестве руководителя команды — так он до сих пор не знает, что такое модуль Ruby.
"
0
Модератор
Эксперт функциональных языков программирования
3140 / 2288 / 469
Регистрация: 26.03.2015
Сообщений: 8,898
14.10.2020, 11:04
Цитата Сообщение от neya Посмотреть сообщение
Постулируете абстрагирование, не связанное с объектно-ориентированным мышлением?
Абстрагирование не является чем-то специфичным для ООП.
1
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
inter-admin
Эксперт
29715 / 6470 / 2152
Регистрация: 06.03.2009
Сообщений: 28,500
Блог
14.10.2020, 11:04

Объясните кое что по ООП
Не дает мне покоя очень важный момент, пример: System.IO.File.Open() System.IO - пространство имен File - класс Open() -...

ООП в паскале. Объясните что к чему
Проблема в следующем, хотелось бы понять как подключать дополнительные файлы исходных текстов к основному. не через uses же это делается...

Объясните некоторые принципы ООП в конкретной реализации
Доброго дня! У меня есть пользователи, которые делятся на зарегистрированных (User) и незарегистрированных (Person) и создаются...

Наследование ООП, объясните примитивную ситуацию, пож
Добрый. Всё никак не могу взять в толк: как это должно работать (точнее - почему не работает так, как я ожидаю). Примитивная наколенка: ...

Начинаю изучать ООП. Объясните, что такое интерфейс?
Всем привет. Начинаю изучать ООП. Объясните,что такое интерфейс?для чего он нужен и чем он отличается от класса?


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

Или воспользуйтесь поиском по форуму:
120
Ответ Создать тему
Новые блоги и статьи
сукцессия 33. открытые вопросы от клауде
anaschu 19.07.2026
"Что накопилось за эту часть А — тринадцать правок, из которых шесть пришли из ваших вопросов и каждая оказалась реальной ошибкой, а не калибровкой: односторонний симбиоз, отсутствующий листопад,. . .
32 сукцессия
anaschu 19.07.2026
сукцессия 28‑мерное ядро стабилизировано Коллеги, фиксирую разбор инженерных правок и их изоморфную проекцию на экономику, меметику и половой отбор. Модель теперь не «подкручивает» сходимость —. . .
сукцессия 31: модель микоризы - это модель ещё нескольких явлений, социальных и экономических
anaschu 18.07.2026
Теория «Всего»: апдейт v1. 1. 2 — 28‑мерное ядро стабилизировано Коллеги, фиксирую разбор инженерных правок и их изоморфную проекцию на экономику, меметику и половой отбор. Модель теперь не. . .
сукцессия 30. Массив проверяющих друг друга моделей
anaschu 18.07.2026
Архитектура сети взаимопроверяющих моделей микоризной сукцессии (v2. 0) Развитие тензорного ОДУ-ядра и создание кросс-платформенного калибровочного полигона Уважаемые коллеги! В продолжение. . .
Грибы - это женщины, деревья - это мужчины. Анти инь янь для союза мужчины и женщины.
anaschu 18.07.2026
ГЛАВНЫЙ НАУЧНО-ФИЛОСОФСКИЙ ВЫВОД: Сексуально-Репродуктивный Капитализм против Государства Моногамии Коллеги, мы вышли на финишную прямую 20-мерного ОДУ-моделирования вековой сукцессии (ветка. . .
Текстовый слайдер с нумерацией страниц и кроссбраузерность.
russiannick 18.07.2026
Один мой друг написал текстовый слайдер с нумерацией страниц. Сегодня я расскажу как он умудрился подружить его с кроссбраузерностью. Очевидно сложно угодить с шириной каждому браузеру. Один крадет. . .
Грибы - это мемы, дерево - это человек. Применение микоризной модели к теории меметики Докинза.
anaschu 18.07.2026
Меметический изоморфизм теории «всего»: Грибная сукцессия как модель эволюции идей Докинза Базовый код системы ОДУ микоризной сукцессии описывает не просто биологию, а универсальную. . .
Грибы - это корпорации, деревья - это государства. Механизм массонского захвата власти
anaschu 18.07.2026
Макроэкономический изоморфизм теории «всего»: Грибная сукцессия как модель транснационального капитализма Базовый код системы ОДУ микоризной сукцессии описывает не просто биологию, а. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru