В общем, я немного знаком со структурным программированием и старым добрым Паскалем. Сейчас начал учить ООП вообще и C# в частности. Возникло два вопроса, наверно, тупых)
Во-первых, для чего конкретно программисту нужен конструктор?
Ну, например...
...
class Class1
{
static void Main()
{
double a;
...
И
...
class Class1
{
static void Main()
{
double a = new double;
...
Это же как бы одно и тоже, в первом случае транслятор неявно использует конструктор, а во во втором программист описывает его явно, в обоих случаях у нас появится переменная a типа double со значением 0, так? И на практике получается, что явное описание конструктора нужно только для создания, например, объекта класса (напр. Class1 Obj1 = new Class1), а переменные проще описывать "как раньше"? Я правильно понимаю?
Во-вторых. Что делают Set и Get? Если можно, на простых примерах...
Другие языки программирования и технологии
Тупые вопросы по C#) Конструкторы, set, get.
Базовые типы можно прямо так использовать, с классами такое не пройдёт.
Рекомендую прочитать про ссылочные типы и типы значения:
metanit.com/sharp/tutorial/2.16.php
Вероятно set и get имеются в виду в контексте свойств.
Свойства придумали для контроля за значением переменной.
Например, свойство для месяца:
private int month; // Закрытая переменная, недоступная вне класса.
public int Month // Открытое свойство, для работы с закрытой переменной.
{
get // Получить
{
return month; // Возвращает текущее значение переменной.
}
set // Задать
{
// value - значение, которое пытаются задать переменной.
if ((value > 0) && (value < 13)) // Только если месяц от 1 до 12
{
month = value; // Задать новое значение
}
// По хорошему в противном случае нужно выбросить исключение, но это совсем другая история.
}
}
Если не указать, к примеру, set свойству нельзя будет задать значение, только получить его.
Рекомендую прочитать про ссылочные типы и типы значения:
metanit.com/sharp/tutorial/2.16.php
Вероятно set и get имеются в виду в контексте свойств.
Свойства придумали для контроля за значением переменной.
Например, свойство для месяца:
private int month; // Закрытая переменная, недоступная вне класса.
public int Month // Открытое свойство, для работы с закрытой переменной.
{
get // Получить
{
return month; // Возвращает текущее значение переменной.
}
set // Задать
{
// value - значение, которое пытаются задать переменной.
if ((value > 0) && (value < 13)) // Только если месяц от 1 до 12
{
month = value; // Задать новое значение
}
// По хорошему в противном случае нужно выбросить исключение, но это совсем другая история.
}
}
Если не указать, к примеру, set свойству нельзя будет задать значение, только получить его.
Сергей Архимандриков
То есть, если очень грубо, get и set позволяют работать с эээ некой "копией" закрытой переменной, не трогая и не изменяя её саму, а также, позволяя, контролировать корректность значения?
Пример неправильный. У тебя тут нет конструктора. Это - создание объекта в куче, которое вызывает констуктор.
Double a = new Double;
создает ссылку a, а не объект. Объект находится в куче.
И да, переменные обычных типов создаются, как раньше.
Все это нужно для инкапсуляции. С таким простым типом это особо не нужно, а вот создание объекта, скажем, типа File может одновременно требовать некоторых действий (проверки существования этого файла на диске, например), которые очень нежелательно отделять от создания объекта. Вот такие действия и заносятся в конструктор. То же самое относится к геттерам и сеттерам - если доступ к данным привязан к какому-то действию, то геттеры и сеттеры гарантируют, что мимо этих действий не пройдут.
Double a = new Double;
создает ссылку a, а не объект. Объект находится в куче.
И да, переменные обычных типов создаются, как раньше.
Все это нужно для инкапсуляции. С таким простым типом это особо не нужно, а вот создание объекта, скажем, типа File может одновременно требовать некоторых действий (проверки существования этого файла на диске, например), которые очень нежелательно отделять от создания объекта. Вот такие действия и заносятся в конструктор. То же самое относится к геттерам и сеттерам - если доступ к данным привязан к какому-то действию, то геттеры и сеттеры гарантируют, что мимо этих действий не пройдут.
Конструктор нужен чтобы инициализировать поля, принять параметры для базового к-ра или задать значения для ридонли.
Конструктора не вижу :(
Конструктора не вижу :(
Вопросы не тупые, а весьма важные и частые. Поэтому напишу подробно - этот ответ пригодится не только вам, а почти что любому разработчику под .NET и не только.
Если вы пишете только консольные хелловорлды с 1 классом с функцией Main и всё, то вам, конечно, не понадобятся ни конструкторы, ни свойства - так как вы не создаете объекты каких-либо классов.
Если пишете хотя бы приложения с GUI, например, приложения Winforms, то свойства уже приходится использовать, и без них ничего не получилось бы.
Возьмем хотя бы встроенный класс Form (или любой класс, на его основе - какой-нибудь Form1) и подумаем, как такой класс может быть реализован разработчиками фреймворка.
В этом классе, свойство Text (заголовок окна) реализовано именно в виде свойства, с get и set, а не в виде поля.
Зачем?
Дело в том, что Winforms - это лишь обертка для API операционной системы (на винде это WinAPI), и когда вы задаете этот самый Text, должна вызываться специальная функция из WinAPI - SetWindowText, которая и задаст заголовок окну. Это обеспечивает сеттер - он своего рода "событие" на изменение свойства. Так же и чтоб получить заголовок окна, необходимо дернуть функцию WinAPI GetWindowText (хранить текст заголовка на уровне приложения - нельзя, ведь заголовок может изменить не только сеттер, но и сама система и приложение об этом не узнает, поэтому и получать его нужно на уровне системы - т. е. через WinAPI), и это обеспечивает геттер.
Могли бы сделать проще - просто 2 метода - GetText() и SetText() - получится то же самое, но это менее удобно для использования, загромождает код, не дает быстро скопипастить кусок года (приходится "G" менять на "S" и наоборот). Так делают в более старых языках, таких, как С++ и Java - где свойств толком нет. И это неудобно.
Свойства смотрятся стройнее. Но есть и недостаток - они могут плохо влиять на производительность, в том случае, когда программист забывает, что в этих самых геттерах и сеттерах могут происходить довольно трудоемкие операции, путает свойства с полями, и делает, например, вот так:
for (int i = 0; i < 100; i++)
{
this.Text += i.ToString();
}
Здесь функции WinAPI будут вызвана 200 раз - 100 раз будет вызвана GetWindowText и 100 раз - SetWindowText.
Лучше делать так:
var temp = this.Text;
for (int i = 0; i < 100; i++)
{
temp += i.ToString();
}
this.Text = temp;
Здесь функции WinAPI вызываются только 2 раза - 1 раз GetWindowText (перед манипуляциями в цикле со временной переменной) и 1 раз - SetWindowText (после).
Что же до конструктора, то его можно рассматривать как обработчик события создания объекта класса (через new).
То есть в конструкторе пишутся те действия, которые должны происходить при создании объекта класса.
В случае с той же Form, - при создании новой формы (new Form()) опять-таки вызывается несколько функций WinAPI, которые на уровне системы создают пока еще невидимое окно, которое затем делается видимым через метод Show().
Если бы не было конструкторов, то после new() еще пришлось бы вызывать специальный метод из объекта класса Form, в котором уже создалось бы окно с помощью WinAPI, что загромождало бы код.
Если вы пишете только консольные хелловорлды с 1 классом с функцией Main и всё, то вам, конечно, не понадобятся ни конструкторы, ни свойства - так как вы не создаете объекты каких-либо классов.
Если пишете хотя бы приложения с GUI, например, приложения Winforms, то свойства уже приходится использовать, и без них ничего не получилось бы.
Возьмем хотя бы встроенный класс Form (или любой класс, на его основе - какой-нибудь Form1) и подумаем, как такой класс может быть реализован разработчиками фреймворка.
В этом классе, свойство Text (заголовок окна) реализовано именно в виде свойства, с get и set, а не в виде поля.
Зачем?
Дело в том, что Winforms - это лишь обертка для API операционной системы (на винде это WinAPI), и когда вы задаете этот самый Text, должна вызываться специальная функция из WinAPI - SetWindowText, которая и задаст заголовок окну. Это обеспечивает сеттер - он своего рода "событие" на изменение свойства. Так же и чтоб получить заголовок окна, необходимо дернуть функцию WinAPI GetWindowText (хранить текст заголовка на уровне приложения - нельзя, ведь заголовок может изменить не только сеттер, но и сама система и приложение об этом не узнает, поэтому и получать его нужно на уровне системы - т. е. через WinAPI), и это обеспечивает геттер.
Могли бы сделать проще - просто 2 метода - GetText() и SetText() - получится то же самое, но это менее удобно для использования, загромождает код, не дает быстро скопипастить кусок года (приходится "G" менять на "S" и наоборот). Так делают в более старых языках, таких, как С++ и Java - где свойств толком нет. И это неудобно.
Свойства смотрятся стройнее. Но есть и недостаток - они могут плохо влиять на производительность, в том случае, когда программист забывает, что в этих самых геттерах и сеттерах могут происходить довольно трудоемкие операции, путает свойства с полями, и делает, например, вот так:
for (int i = 0; i < 100; i++)
{
this.Text += i.ToString();
}
Здесь функции WinAPI будут вызвана 200 раз - 100 раз будет вызвана GetWindowText и 100 раз - SetWindowText.
Лучше делать так:
var temp = this.Text;
for (int i = 0; i < 100; i++)
{
temp += i.ToString();
}
this.Text = temp;
Здесь функции WinAPI вызываются только 2 раза - 1 раз GetWindowText (перед манипуляциями в цикле со временной переменной) и 1 раз - SetWindowText (после).
Что же до конструктора, то его можно рассматривать как обработчик события создания объекта класса (через new).
То есть в конструкторе пишутся те действия, которые должны происходить при создании объекта класса.
В случае с той же Form, - при создании новой формы (new Form()) опять-таки вызывается несколько функций WinAPI, которые на уровне системы создают пока еще невидимое окно, которое затем делается видимым через метод Show().
Если бы не было конструкторов, то после new() еще пришлось бы вызывать специальный метод из объекта класса Form, в котором уже создалось бы окно с помощью WinAPI, что загромождало бы код.
Похожие вопросы
- Ещё тупой вопрос по C++ :)
- Извините за тупой вопрос, но для чего в c++ нужны классы? Для того что бы было легко отсортировать код или ещё зачем?
- Вопрос по c++ )
- Вопрос по C++
- Не знаю, тупой вопрос или нет. Но всё же задам вопрос на тему "Программирование". Помогите определиться.
- вопрос по C++ как работать с заголовками? компилятор ругается, непойму как связать 3 файла. исходники внутри.
- помогите!!! вопрос по C++ нужно написать программку "заполните массив так, чтобы все его элементы были различны.
- Очень важный вопрос по C++
- вопрос на C++
- Парочка вопросов по C++