SanchelliosProg
@SanchelliosProg
Java, Android, Software Testing

Почему не стоит вызывать методы в конструкторе?

Привет!
Много раз слышал о том, что не рекомендуется вызывать методы класса в конструкторе. Но почему?
  • Вопрос задан
  • 5812 просмотров
Решения вопроса 1
@smozhaykin
На самом деле вызывать не стоит только виртуальные методы. Т.к. если класс наследник его переопределит, то возникнет ситуация, когда метод работает до вызова конструктора класса-наследника. И если в этом методе используются какие-нибудь поля класса-наследника, они могут быть еще непроинициализированы.

А так как в Java

In Java, all non-static methods are by default "virtual functions." Only methods marked with the keyword final, which cannot be overridden, along with private methods, which are not inherited, are non-virtual.


то в конструкторе не стоит вызывать любые публичные не final методы.

Ниже C# код (т.к. работаю в основном с этим языком), иллюстрирующий это.

void Main()
{
	new B("name");
}

class A
{
    public A()
	{
	     Method();
	}
	
	protected virtual void Method()
	{
	}
}

class B : A
{
    private string Property { get; set; }
	
	public B(string value)
	{
	    Property = value;
	}
	
    protected override void Method()
	{
	    Console.WriteLine(Property.Length);
	}
}


Результат: Object reference not set to an instance of an object.

StackTrace
at UserQuery.B.Method()
at UserQuery.A..ctor()
at UserQuery.B..ctor(String value)
at UserQuery.Main()
Ответ написан
Комментировать
Пригласить эксперта
Ответы на вопрос 3
@protven
Ну например потому что у вас на момент вызова конструктора объект вашего класса еще не создан окончательно (внезапно!). И только находится в процессе создания. Поэтому объект может быть в неконсистентном состоянии на момент вызова своего метода.
Ответ написан
Комментировать
EugeneP2
@EugeneP2
Java Dev
Почему нельзя? очень даже можно, только этот метод должен быть private. Не рекомендуют вызывать public и protected методы. Если класс не финальный, открытые методы могут быть переопределены в подклассе, и тогда в вашем конструкторе будут вызываться не ваши методы, а переопределенные, что может сломать логику работы вашего класса и привести к ошибке.
Ответ написан
Комментировать
sivabur
@sivabur
Заблокировали просто так!
первая задача конструктора — перевести поля объекта в допустимое состояние.
Вторая задача — упростить пользование объектом.

Например конструктор класа для работы с файлом

File file("in.txt", File::omRead);

И почему бы не вызывать какието дополнительныи методы для чтения с файла или валидации данных. И тому подобное.

Тока как сказали уже више виртуальныи методы вызывать нельзя.
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы