Я изучал C # в течение последних шести месяцев или около того и сейчас углубляюсь в Java. Мой вопрос касается создания экземпляров (на любом языке, на самом деле), и это больше: интересно, почему они сделали это таким образом. Возьми этот пример
Person Bob = new Person();
Есть ли причина, по которой объект указан дважды? Будет ли когда-нибудь something_else Bob = new Person()
?
Казалось бы, если бы я следовал из конвенции, это было бы больше похоже на:
int XIsAnInt;
Person BobIsAPerson;
Или, возможно, один из них:
Person() Bob;
new Person Bob;
new Person() Bob;
Bob = new Person();
Полагаю, мне любопытно, есть ли лучший ответ, чем «это просто так».
java
c#
object-oriented
Джейсон Уолгемут
источник
источник
LivingThing
? Вы могли бы написатьLivingThing lt = new Person()
. Ищите наследование и интерфейсы.Person Bob
объявляет переменную типа "ссылка наPerson
" вызываетсяBob
.new Person()
создаетPerson
объект. Ссылки, переменные и объекты - это три разные вещи!var bob = new Person();
?Person Bob();
возможно в C ++ и означает почти то же самое, что иPerson Bob = Person();
Ответы:
Да, по наследству. Если:
Потом:
Боб тоже человек, и, черт возьми, он не хочет, чтобы с ним обращались иначе, чем с кем-либо еще.
Кроме того, мы могли бы наделить Боба сверхспособностями:
И поэтому, ей-богу, он не потерпит никакого отношения к нему иначе, чем любой другой модератор. И он любит красться по форуму, чтобы держать всех в очереди, пока инкогнито
Затем, когда он находит какой-то плохой 1-й плакат, он сбрасывает свой плащ-невидимку и набрасывается на него.
И тогда он может действовать невинно и все остальное потом:
источник
enum
.Давайте возьмем вашу первую строку кода и рассмотрим ее.
Первый
Person
- это спецификация типа. В C # мы можем обойтись без этого, просто сказави компилятор определит тип переменной Bob из вызова конструктора
Person()
.Но вы можете написать что-то вроде этого:
Где вы не выполняете весь API-контракт Person, а только контракт, указанный в интерфейсе
IPerson
.источник
IPerson
пример в своем коде, чтобы убедиться, что я случайно не использую какие-либо частные методы, когда пишу код, который должен быть скопирован / вставлен в другуюIPerson
реализацию.internal
?private
имеет смысл: фабричные методы, которые являются частью создаваемого класса. В моей ситуации доступ к частным ценностям должен быть исключением, а не нормой. Я работаю над кодом, который надолго переживет меня. Если я делаю это таким образом, я не только сам не буду использовать какие-либо частные методы, но когда следующий разработчик копирует / вставляет это несколько десятков мест, а разработчик копирует их, это уменьшает вероятность того, что кто-то увидит возможность используйте приватные методы как "нормальное" поведение.Этот синтаксис в значительной степени унаследован от C ++, который, кстати, имеет оба:
и
Первый для создания объекта в текущей области, второй для создания указателя на динамический объект.
Вы определенно можете иметь
something_else Bob = new Person()
Здесь вы делаете две разные вещи, указывая тип локальной переменной
nums
и говорите, что хотите создать новый объект типа «Список» и поместить его туда.C # вроде с вами согласен, потому что большую часть времени тип переменной идентичен тому, что вы в нее вставили, следовательно:
В некоторых языках вы стараетесь не указывать типы переменных, как в F # :
источник
new std::pair<int, char>()
, то у членовfirst
иsecond
пары будет автоматическая продолжительность хранения, но они, вероятно, будут распределены в куче (как члены объекта dynamic-storage-durationpair
).Существует огромная разница между
int x
иPerson bob
.int
Этоint
являетсяint
и он всегда должен бытьint
и не может быть ничем иным, какint
. Даже если вы не инициализируете,int
когда объявляете его (int x;
), он все равноint
установлен на значение по умолчанию.Однако, когда вы объявляете
Person bob
, существует большая гибкость в отношении того, к чему наbob
самом деле может относиться имя в любой момент времени. Он может ссылаться на aPerson
или ссылаться на некоторый другой класс, напримерProgrammer
, производный отPerson
; это может даже бытьnull
, не ссылаясь ни на какой объект вообще.Например:
Разработчики языка, безусловно, могли бы создать альтернативный синтаксис, который выполнял бы то же самое, что и
Person carol = new Person()
в меньшем количестве символов, но они все равно должны были бы разрешитьPerson carol = new Person()
(или сделать какое-то странное правило, делающее этот конкретный один из четырех примеров выше недопустимым). Их больше заботило сохранение языка «простым», чем написание чрезвычайно лаконичного кода. Это, возможно, повлияло на их решение не предоставлять более короткий альтернативный синтаксис, но в любом случае это не было необходимо, и они не предоставили его.источник
Эти две декларации могут быть разными, но часто одинаковыми. Общий рекомендуемый шаблон в Java выглядит следующим образом:
Эти переменные
list
иmap
объявляются с использованием интерфейсовList
и вMap
то время как код создает конкретные реализации. Таким образом, остальная часть кода зависит только от интерфейсов, и легко выбрать другие классы реализации для создания экземпляров, напримерTreeMap
, так как остальная часть кода не может зависеть от какой-либо частиHashMap
API, которая находится за пределамиMap
интерфейса.Другой пример, в котором два типа различаются, - это метод фабрики, который выбирает конкретный подкласс для создания экземпляра, а затем возвращает его в качестве базового типа, так что вызывающей стороне не нужно знать подробности реализации, например, выбор «политики».
Вывод типа может исправить избыточность исходного кода. Например, на Яве
создаст правильный вид List благодаря выводу типа и объявлению
В некоторых языках вывод типов идет дальше, например, в C ++
источник
bob
, нетBob
. Это позволяет избежать большой неоднозначности, например, package.Class vs. Class.variable.clazz
.clazz
используется потому, чтоclass
является ключевым словом, поэтому его нельзя использовать в качестве идентификатора.Class
это совершенно правильный идентификатор.cLaSs
,cLASS
иcLASs
.По словам непрофессионала:
var = new Process()
не объявляя переменную первой.источник
Это также об уровне контроля над тем, что происходит. Если объявление объекта / переменной автоматически вызывает конструктор, например, если
был автоматически такой же, как
тогда вы никогда не сможете использовать (например) статические фабричные методы для создания экземпляров объектов, а не конструкторов по умолчанию, то есть бывают ситуации, когда вы не хотите вызывать конструктор для нового экземпляра объекта.
Этот пример объясняется в книге « Эффективная Java» Джошуа Блоха (пункт 1 достаточно иронически!)
источник