Разница между объектом и экземпляром, есть ли она вообще?
Думаю ни для кого не секрет, что в ООП (объектно-ориентированном программировании) основной акцент делается на объектах и их взаимодействии. Есть даже 6 основных законов, 6 парадигм ООП, которых, если мы хотим писать правильный ООП код, нужно придерживаться. Но, как правило, новички, пришедшие в ООП, зачастую вместе с понятием объект видят и понятие экземпляр. Это, конечно же, не удивительно, что два этих неразрывных слова употребляются в одном контексте даже в высококачественной литературе. Но из этого и исходит наибольшая проблема: путаница в понятиях экземпляра и объекта.
Что такое куча (heap)?
Для детального разбора сначала вспомним, что все ссылочные типы (классы, интерфейсы, делегаты, коллекции, массивы и т.п.) хранятся в области памяти под названием куча, а все значимые типы (int, float, double, перечисления, структуры и т.п.) и ссылки на адреса памяти ссылочных типов на куче хранятся в стеке. Куча — динамическая, неупорядоченная область памяти, она намного больше стека и с этого уже можно сделать логический вывод, почему все ссылочные «объемные» типы хранятся там.
Создание объекта и экземпляра
Для полной ясности картины и как доказательство, давайте создадим экземпляр каког-нибудь заранее описанного класса:
public class MyExample //класс-пример
{
public void Hi()
{
myHi();
}
private void myHi()
{
Console.WriteLine("Hi, man!!!");
}
}
class Program
{
static void Main(string[] args)
{
MyExample myExample = new MyExample(); //Тут я создаю переменную типа MyExample и
//присваиваю ей ссылку на экземпляр класcа MyExample
myExample.Hi(); // использую объект класа MyExample
}
}
Простенький пример, к которому нужно еще додать очень многое. Во-первых, само понятие экземпляр подразумевает под собой набор значений нестатически полей для данного объекта (кто знаком со статикой поймёт скорее), а сам объект хранит в себе все методы и статические поля. На куче это выглядит так:
Как видим экземпляров будет столько, сколько раз вы присвоите переменной ссылку через конструктор на данный экземпляр. И в конце мы пришли к тому, что «экземпляр 1» и объект реализовали первую парадигму ООП — инкапсуляцию и был создан «Объект 1».
Во-вторых, чтобы сложить этот пазл, давайте вспомним, для чего классу нужен конструктор: он нужен для того, чтобы проинициализировать все нестатические поля класса. Выходит благодаря конструктору мы и создаем каждый раз новый экземпляр.
Инкапсуляция
Выше я упомянул первую (важно, что именно первую) парадигму ООП — инкапсуляцию. Многие «новые» программисты путают инкапсуляцию со схожим явлением — сокрытием реализации. Эти неверные мысли идут из утверждения, что инкапсуляция — сокрытие реализации от пользователя благодаря модификаторам что доступа, что верно и в корне неверно одновременно. Если еще раз взглянуть на фото-пример и внимательно перечитать информацию, можно сделать вывод, что инкапсуляция это «некое объединение экземпляра и объекта в одну сущность». И в принципе — так и есть от части. Ведь правильное значение слова инкапсуляции в программировании будет звучать так: «Инкапсуляция — первая парадигма ООП, которая подразумевает, что данные и методы для работы с этими данными будут объединены в один объект [Объект 1(см. фото)], а реализация будет сокрыта от пользователя».
Надеюсь в дальнейшем вы уже не будете путать значение слов экземпляр и объект, а инкапсуляция наконец обрела новый и правильный смысл в вашей голове.
Комментарии (16)
Klenov_s
22.10.2019 16:19+2Это сейчас стало модным, придумать какое-то бредовое высказывание, а потом писать целую статью, опровергающую его, но так и не родить ничего осмысленного?
Ascar
22.10.2019 16:39+1Мне кажется автор пытает рассказать что то про объект-тип… Кстати если упаковать данные значимого типа, то они окажутся «на куче». Так же если они в классе.
ZXZs
22.10.2019 20:33+1Я, вроде, понял, про что статья, но тут то ли какая-то подмена понятий, то ли ещё чего, но меня всё ещё что-то смущает.
Klenov_s
22.10.2019 20:38Просто автор сам придумал некую свою формулировку инкапсуляции, а потом пытается ее опровергнуть придумывая разницу между объектом класса и экземпляром класса.
P.S. Это он еще не знает, что в TP объектом назывался класс )))ZXZs
22.10.2019 21:13Я так понял автор имел ввиду то, что экземпляр – это поля, а объект – методы для работы с ними, поэтому экземпляров много, а объект один…
Klenov_s
22.10.2019 21:16В тех языках, что я знаю, методы описываются исключительно в описании класса и никакой объект не может иметь отдельных методов не применяя композицию.
VolCh
23.10.2019 00:49Насколько я понимаю, формулировка автора гораздо ближе к оригинальной, чем имеющачся в виду в высказываниях типа "сделай все поля приватными, а то нарушаешь ООП инкапсуляцию"
Ryppka
22.10.2019 22:11Если еще раз взглянуть на фото-пример и внимательно перечитать информацию, можно сделать вывод, что инкапсуляция это «некое объединение экземпляра и объекта в одну сущность».
А все это объединение в одну сущность сводится к добавлению неявного аргумента-указателя))). В некоторых языках даже явного. А разговоров-то…
Orange11Sky
22.10.2019 22:52+2Как-то всё запуталось: где обьект, где экземпляр?
Кто на ком стоял? ©
C точки зрения языка есть класс как описание обьекта и экземпляр класса как обьект, созданный по его описанию.
shiotiny
23.10.2019 06:22Для детального разбора сначала вспомним, что все ссылочные типы (классы, интерфейсы, делегаты, коллекции, массивы и т.п.) хранятся в области памяти под названием куча, а все значимые типы (int, float, double, перечисления, структуры и т.п.) и ссылки на адреса памяти ссылочных типов на куче хранятся в стеке.
Простите, но это не так! Все зависит от того как и где создан экземпляр класса.
Скажем, на С++ описан класс. Он имеет поля (int, float, double).
Если экземпляр класса создан как глобальная переменная — то его поля (int, float, double) будут храниться вообще вообще в сегменте статической памяти.
Если экземпляр класса создан через new , то эти же поля будут храниться в куче.
И, наконец, если экземпляр класса создан как автоматическая переменная, то эти же поля будут храниться на стеке.
Поля и методы с модификатором static тоже хранятся в в сегменте статической памяти.
И так далее. В общем — все не так однозначно:)MaxKot
23.10.2019 20:17Просто в первом абзаце речь шла об ООП вообще, а во втором повествование перескочило на .NET.
sashocq
Сложилось ощущение, что автор не перечитал текст, который сам написал.
Какая-то мешанина из разных слов получилась.