2015-02-10 2 views
5

Рассмотрим следующий фрагмент кода:Оператор присваивания и «это» ключевое слово

class Parent { 
    Parent() { 
     this = new Child(); 
    } 
} 
class Child extends Parent { } 

выше будет бросать синтаксическую ошибку: The left hand side of an assignment operator must be a variable

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

Однако, я хочу знать, почему Java не позволяет использовать эту функцию выше? Есть ли недостаток?

EDIT: Этот вопрос возник со ссылкой на контекст обработки естественного языка (NLP). Например, на французском языке каждый глагол должен заканчиваться словами «er», «ir» или «re». Все глаголы имеют некоторые общие черты. Однако каждый глагол должен быть либо одним из трех типов, упомянутых выше. Поэтому в конструкторе родительского класса «Глагол» я хочу классифицировать объект, созданный как «ErVerb», «IrVerb» или «ReVerb».

+3

Это не имеет смысла, и даже если этот конкретный код будет работать, он выкинет исключение StackOverflowException. –

+0

Как класс знает, что это подкласс? который еще предстоит родиться? : P – Anil

+0

Что именно вы хотите достичь? – MinecraftShamrock

ответ

7

Есть два сценария:

Если вы позволите this быть воплощенными в любом Object бы то ни было, не обязательно один в иерархии типов, то конкретизация не будет иметь никакой гарантии, о содержании его ссылки. Это ломает пару вещей, в первую очередь целую концепцию объектно-ориентированного программирования.

Если вы ограничиваете this экземпляром какого-либо подкласса родительского класса, то этот конструктор подкласса будет вызывать родительский конструктор бесконечно много раз, вызывая StackOverflowError.

+0

У меня был ваш второй сценарий, когда я задал вопрос. Если в Java для всех дочерних классов не было обязательного вызова конструктора родительского класса, можно ли использовать вышеприведенный фрагмент? Мне никогда не нравилось, что java делает обязательным для конструктора каждого дочернего класса вызов конструктора родительского класса. – user3182445

+0

Удаление потока дочернего конструктора приведет к тому, что другие вещи будут разбиты с объектно-ориентированной точки зрения. Состояние объекта должно быть жестко сохранено, и OO диктует, что каждый родительский объект должен нести ответственность за сохранение своего собственного состояния независимо от его дочерних классов. Вот о чем еще подумать - представьте себе класс A с детьми B и C. Предположим, что в конструкторе A вы перевернули монету и написали 'this = new B()' или 'this = new C()'. До запуска вы не можете быть уверены в типе, но * также не может JVM *. Так что же мог сделать компилятор? Какие методы могут быть доступны? Etc – Kon

2

Не имеет смысла создавать экземпляр подкласса внутри конструктора родителя и заменять фактический родительский экземпляр созданным дочерним экземпляром.

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

Рассмотрим следующие рассуждения:

Конкретный автомобиль находится в собранном виде на заводе. Процесс сборки конкретного автомобиля состоит из нескольких этапов.

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

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

Теперь конкретный автомобиль, который мы собирали, стал бы этим новым конкретным фургоном. Но невозможно, чтобы автомобиль был вагон =>ABSURD.

+0

Этот вопрос возник ко мне со ссылкой на контекст обработки естественного языка (NLP). Например, на французском языке каждый глагол должен заканчиваться словами «er», «ir» или «re». Все глаголы имеют некоторые общие черты. Однако каждый глагол должен быть либо одним из трех типов, упомянутых выше. Поэтому в конструкторе родительского класса «Глагол» я хочу классифицировать объект, созданный как «ErVerb», «IrVerb» или «ReVerb». Следовательно, эта функция показалась мне полезной. – user3182445

+1

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