Точка инициализации класса?

Я читаю книгу о С# для новичков, и я нахожусь в разделе "Понимание ценностей и ссылок", но я кое-что не понимаю. То, что я вижу, это то, что книги пытаются объяснить это мне (и я видел, как это происходит в нескольких обучающих видео на Youtube), что класс используется для создания... объекта (??) класса. Я прочитал всю предыдущую главу, где это произошло, и я не совсем понял это, полагая, что это станет более понятным в следующей главе. Это не стало более ясным, поэтому я не думаю, что это хорошая идея для продолжения, пока я не пойму концепцию того, что я объяснил ранее.

Следующая часть является частью книги:

Помните, что для инициализации ссылочной переменной, такой как класс, вы может создать новый экземпляр класса и назначить ссылку переменная к новому объекту, например:

Circle c = new Circle(42);
Circle copy = new Circle(99);
//Circle refc = c;
...
copy = c;

Что я могу сделать с кодом в этом примере и почему он удобен? Примеры + объяснение было бы более чем приятным. Спасибо заранее!

Ответ 1

По звукам этого, вы совершенно не поняли, что книга объяснила:

Следующее к глазу читает сделать 2 круга размером 3 и 4 и взять копию первого и сделать его 5.. кроме случаев, когда вы распечатываете его, это не так, как это работает.

class Program
{
    static void Main(string[] args)
    {

        circle a = new circle(3);
        circle b = new circle(4);
        circle d = a;
        d.Diameter = 5;

        Console.WriteLine("a is {0}", a.Diameter); // shows 5
        Console.WriteLine("b is {0}", b.Diameter); // shows 4
        Console.WriteLine("d is {0}", d.Diameter); // shows 5
    }
}

class circle
{
    public int Diameter;
    public circle(int d)
    {
        Diameter = d;
    }
}

потому что вы не создали новый круг для d, на самом деле d является псевдонимом для a, поэтому, как и имя someones, это Peter, его также можно назвать Pete.

Ответ 2

Помните, что для инициализации ссылочной переменной, такой как класс, , вы можете создать новый экземпляр класса и присвоить ссылочную переменную новому объекту, [sic]

Он показывает разницу между ссылочными и значениями. С типом значения он уже инициализирован.

double d;

Вам больше нечего делать. С классом или ссылочным типом вы должны предоставить ему экземпляр объекта.

Circle c; Пока еще не назначен объект.

d = c.Radius Ошибка. Ссылка не указывает на объект. Нарушение доступа к памяти.

Circle c = new Circle(); Теперь он делает.

Ответ 3

Ну, это может быть удобно и не обязательно всегда полезно иметь возможность назначить вашему типу ссылку на новое местоположение объекта. В этом случае, в последней строке copy = c;, вы говорите, что копия теперь указывает на ячейку памяти, выделенную c раньше, другими словами, после этой строки они оба указывают на ячейку той же,

Ответ 4

Это довольно сложно дать вам крутой курс в объектно-ориентированном программировании, но это то, что вам нужно на данный момент: вам в настоящее время необходимо понимание OO-программирования, которое является парадигмой программирования, что многие языки программирования имеют, как правило, и С#.

Проблема, которую вы описываете в приведенном выше сообщении, следующая:

В oo-prgramming вы пишете классы, которые состоят из (грубо) полей и методов. Эти классы имеют статический характер и существуют в течение времени разработки вашего приложения (не путайте со статикой, которую я использую здесь, и ключевым словом static). Во время выполнения вашего приложения вы можете использовать эти статические * классы * для создания объектов этих классов, что означает, что определенный класс служит планом здания для произвольного количества объектов, которые все одинаковы. В отличие от классов эти объекты также называются экземплярами класса и существуют только во время выполнения вашего приложения. Объекты являются динамическими.

Просто очень короткий: когда у вас есть класс

class House {

// ...
}

у вас есть статическое описание дома, которое вы можете использовать для создания динамических * объектов *, т.е. домов. Вы делаете это (в С# и других современных языках, таких как Java) с так называемым новым оператором:

House house = new House();

Что вы здесь делаете, это объявить переменную типа House. Тип, который вы нарушили самостоятельно с классом House. Это эта часть:

House house;

Пока это только переменная типа House, которая ничего не делает. Термин, который важен здесь, состоит в том, что он указывает на ничего, и это ничто не называется null.

Затем вы можете создать экземпляр этого класса (динамический объект) со следующим синтаксисом:

house = new House();

Теперь вы создали объект и указали свой объект переменной на этот объект. С этого момента вы можете ссылаться на этот объект с переменной дом.

Я говорю вам это, чтобы указать на один важный вопрос, который вы упомянули в своем сообщении выше: Разница типов значений и типов ссылок.

Что вы делали в предыдущих строках, так это создание новой переменной, указывающей на объект. Это (грубо снова) называется ссылочным типом. В отличие от этого у вас есть, например, примитивные типы, такие как int, байт, короткий и т.д.

С

int i = 4;

вы снова объявляете переменную. Но на этот раз переменная прямо удерживает ее, а не указывает на нее. Это называется значением типа.

Разница между типами значений и ссылочными типами очень важна, например, когда вы передаете такие переменные, как параметр, в методы.

Ответ 5

Я попытаюсь исправить эту цитату, потому что это просто ужасно.

Оригинал:

Помните, что для инициализации ссылочной переменной, такой как класс, вы можете создать новый экземпляр класса и назначить ссылочную переменную новому объекту, например:

Fixed

Помните, что для инициализации переменной ссылочного типа вы можете создать новый экземпляр типа этой переменной и изменить переменную, чтобы указать на новый объект, например:

Хотя это должно быть то, что вы должны помнить, я не знаю. Да, вы можете создать несколько ссылок на один и тот же объект, и это может быть полезно само по себе, но это не делает меня особенно полезной стратегией инициализации.

Исправлено еще лучше:

Вы можете сделать, чтобы переменные ссылочных типов ссылались на один и тот же экземпляр, но помните, что сами переменные не являются псевдонимами, поэтому перезапись одна не меняет другую.

Ответ 6

Вы можете рассматривать класс как схему для данных, например, спецификацию или схему. Когда вы используете ключевое слово "новое", вы говорите компьютеру использовать этот проект, чтобы сделать объект для вас. Объект является конкретным экземпляром этого класса.

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

Итак:

Circle c = new Circle(42);
Circle copy = new Circle(99);

Сообщает компьютеру использовать определение класса Circle и экземпляр двух объектов (так что у вас есть два круга, которые существуют в памяти вашего компьютера). Это разные объекты с разными свойствами (один имеет радиус 42, а другой 99). Они присваиваются переменным c и копируются.

Последняя строка вашего кода, где вы копируете = c; помещает круг, на который указывает переменная с в переменную копию.

Ответ 7

Определение класса - это синяя печать. Подумайте об этом, как о доме. Каждый раз, когда вы создаете объект Circle c = new Circle(42), вы строите дом с этим синим шрифтом. Каждый дом имеет адрес на улице (адрес в памяти).

Каждая переменная, которая у вас есть, похожа на лист бумаги, в котором указан адрес дома. Итак, вы строите синий двухэтажный дом на главной улице 123 и напишите 123 главную улицу на листе бумаги и назовите эту бумагу "А". Затем вы построите красный 4-этажный дом на улице Кинг-стрит 456 и напишите этот адрес на бумаге и назовите эту бумагу "B". Затем вы получите лист бумаги и запишите адрес первого дома, который вы сделали (123 Main Street), и назовите эту бумагу "C".

Затем перейдите к художнику и попросите его нарисовать дом желтым. Вы даете ему лист бумаги "C".

В нашем примере есть только два дома. Поскольку C и A "указывают" на тот же адрес, они теперь указывают на желтый дом.

House a = new House( blue, 2 );
House b = new House( red, 4 );
House c = a;
c.Color = yellow;
//Now a.Color is yellow as well

Ответ 8

Переменная не является объектом, она является только ссылкой на объект. Так, например, в следующем примере есть две переменные, которые ссылаются на один и тот же объект:

Label label1 = new Label();
Label label2 = label1;
label1.Text = "1";
label2.Text = "2";

После выполнения этого кода вы увидите, что label1.Text равно "2", а не "1". Это связано с тем, что они ссылаются на один и тот же объект Label, поэтому, когда вы устанавливаете label2.Text, он изменится для обеих переменных. Если, однако, вы создали два отдельных объекта метки, результат будет иным, например:

Label label1 = new Label();
Label label2 = new Label();
label1.Text = "1";
label2.Text = "2";

В этом втором примере каждая переменная указывает на другой объект Label (т.е. другой экземпляр класса Label). Поэтому после запуска этого кода label1.Text будет равняться "1", а label2.Text будет равно "2", как и следовало ожидать.

Есть веские причины, по которым оба этих параметра важны и доступны вам. Например, скажем, вы хотите создать метод, который устанавливает свойство Text для Label, например:

void SetLabelText(Label labelToSet)
{
    labelToSet.Text = "text";
}

И вы можете вызвать метод следующим образом:

Label label1 = new Label();
SetLabelText(label1);

В этом случае переменная labelToSet в методе SetLabelText будет ссылаться на тот же объект, что и переменная label1, поэтому, когда 'SetLabelText устанавливает labelToSet.Text в "текст", это не создает новый Label, он просто устанавливает текст существующего объекта Label, который был передан в качестве параметра для метода, и это именно то, что вы хотели бы сделать.

Так как любая переменная может быть установлена ​​как на новый объект, так и на существующий объект, он считается "null" до тех пор, пока он не будет назначен объекту. Как я уже сказал, переменная не является объектом, а просто ссылкой на объект. Если переменная не ссылается на какой-либо объект вообще (это начальное состояние), оно null и генерирует исключение, если вы пытаетесь его использовать. Например:

Label label1; 
label1.Text = "1";  // Throws a null reference exception

Вы можете объявить столько переменных, сколько хотите, но все они будут null, пока вы на самом деле не создадите экземпляр хотя бы одного объекта и не установите для него его. Чтобы создать экземпляр объекта (т.е. Создать новый экземпляр класса), вы должны использовать ключевое слово new (например, new Label()).

Однако все, что я сказал до сих пор, относится только к "Reference Types" (класс). Это не относится к "типам значений" (struct). Когда вы объявляете переменную как тип значения, для всех практических целей это фактически объект. Многие простые типы данных, такие как int, являются типами значений. Так, например:

int x;
int y;
x = 1;
y = x;
y = 2;

После выполнения вышеуказанного кода x будет равно 1, а y будет равно 2. Установка y = x не приводит к тому, что y ссылается на тот же объект, что и x. Скорее, он копирует значение от x до y, тем самым создавая новый объект типа значения.

Ответ 9

Если мы говорим о человеке, в этом контексте класс определяет, что такое человек и что он может делать (его члены, такие как высота, ширина и т.д., и его методы eat(), drink() и т.д.), а объект представляет фактический человек (человек по имени Андрей, который имеет высоту ширины, может есть и пить)

Ответ 10

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

Копия = c; строка просто скажет, что объект-копия не будет указывать расположение памяти объекта c, а не тот, на который он был впервые установлен.

Ответ 11

В приведенном вами примере, как и в случае со многими примерами, представленными в книгах, вы видите самый простой случай. Трудно понять, как лучше использовать такую ​​функцию, пока вы не углубитесь в код.

Я не знаю, правильно ли это, но способ, которым я буду использовать что-то вроде этого:

private double GetArea(Circle c)
{
     //this will be a default circle should the passed in circle be invalid
     Circle toCalc = new Circle(5);

     //check to make sure c is valid
     if(c != null)
          toCalc = c;

     return Math.pow(toCalc.Radius, 2) * Math.Pi;
}

Так как toCalc - это класс, а не примитивный тип данных, он должен быть инициализирован для компиляции кода. Если он не инициализирован, компилятор даст вам некоторую ошибку, например: "toCalc не может быть инициализирован".