Ћекции.ќрг


ѕоиск:




 атегории:

јстрономи€
Ѕиологи€
√еографи€
ƒругие €зыки
»нтернет
»нформатика
»стори€
 ультура
Ћитература
Ћогика
ћатематика
ћедицина
ћеханика
ќхрана труда
ѕедагогика
ѕолитика
ѕраво
ѕсихологи€
–елиги€
–иторика
—оциологи€
—порт
—троительство
“ехнологи€
“ранспорт
‘изика
‘илософи€
‘инансы
’ими€
Ёкологи€
Ёкономика
Ёлектроника

 

 

 

 


”даление неиспользуемых объектов и метод finalize. ѕроблема деструкторов дл€ сложно устроенных объектов




 ак мы знаем, конструктор занимаетс€ созданием и р€дом дополнительных действий, св€занных с инициализацией объекта. ”ничтожение объекта также может требовать дополнительных действий. ¬ таких €зыках программировани€ как C++ или Object PASCAL дл€ этих целей используют деструкторы Ц методы, которые уничтожают объект, и совершают все сопутствующие этому сопроводительные действи€.

Ќапример, у нас имеетс€ список фигур, отрисовываемых на экране, и мы хотим удалить из этого списка какую-нибудь фигуру. ѕеред уничтожением фигура должна исключить себ€ из списка, затем дать команду списку заново отрисовать содержащиес€ в нЄм фигуры, и только после этого УумеретьФ. »менно такого рода действи€ характерны дл€ деструкторов. «аметим, что возможна друга€ логика работы: дать списку команду исключить из него фигуру, после чего перерисовать фигуры, содержащиес€ в списке. Ќо желательно, чтобы €зык программировани€ поддерживал возможность реализации обоих подходов.

¬ Java имеетс€ метод finalize(). ≈сли в классе, который производит завершающие действи€ перед уничтожением объекта сборщиком мусора, переопределить этот метод, он, как может показатьс€, может служить некой заменой деструктора. Ќо так как момент уничтожени€ объекта неопределЄнен и может быть отнесЄн по времени очень далеко от момента потери ссылки на объект, метод finalize не может служить реальной заменой деструктору. ƒаже €вный вызов сборщика мусора System.gk() сразу после вызова метода finalize() не слишком удачное решение, так как и в этом случае нет гарантии правильности пор€дка высвобождени€ ресурсов.  роме того, сборщик мусора потребл€ет много ресурсов и в р€де случаев может приостановить работу программы на заметное врем€.

√ораздо более простым и правильным решением будет написать в базовом классе разрабатываемой вами иерархии метод destroy() - Ууничтожить, разрушитьФ, который будет заниматьс€ выполнением всех необходимых вспомогательных действий (можно назвать метод dispose() Ц Уизбавитьс€, отделатьс€Ф, можно free() Ц УосвободитьФ). ѕричЄм при необходимости надо будет переопредел€ть этот метод в классах-наследниках. ¬ случае, когда надо вызывать прародительский деструктор, следует делать вызов super.destroy(). ѕри этом желательно, чтобы он был последним оператором в деструкторе класса Ц в противном случае может оказатьс€ неправильной логика работы деструктора. Ќапример, произойдЄт попытка обращени€ к объекту, исключЄнному из списка, или попытка записи в уже закрытый файл.

Ћогика разрушени€ объектов €вл€етс€ обратной той, что используетс€ при их создании: сначала разрушаетс€ часть, относ€ща€с€ к самому классу. «атем разрушаетс€ часть, относ€ща€с€ к непосредственному прародителю, и далее по иерархии, заканчива€ частью, относ€щейс€ к базовому классу. ѕоэтому последним оператором деструктора бывает вызов прародительского деструктора super.destroy().

ѕерегрузка методов

Ќапомним, что им€ функции в сочетании с числом параметров и их типами называетс€ сигнатурой функции. “ип возвращаемого значени€ и имена параметров в сигнатуру не вход€т. ѕон€тие сигнатуры важно при задании подпрограмм с одинаковыми именами, но разными списками параметров Ц перегрузке (overloading) подпрограмм. ћетоды, имеющие одинаковое им€, но разные сигнатуры, разрешаетс€ перегружать. ≈сли же сигнатуры совпадают, перегрузка запрещена. ƒл€ задани€ перегруженных методов в Java не требуетс€ никаких дополнительных действий по сравнению с заданием обычных методов. ≈сли же перегрузка запрещена, компил€тор выдаст сообщение об ошибке.

„аще всего перегружают конструкторы при желании иметь разные их варианты, так как им€ конструктора определ€етс€ именем класса. Ќапример, рассмотренные ранее конструкторы

Circle(Graphics g, Color bgColor){

Е

}

и

 

Circle(Graphics g, Color bgColor, int r){

Е

}

 

 

отличаютс€ числом параметров, поэтому перегрузка разрешена.

¬ызов перегруженных методов синтаксически не отличаетс€ от вызова обычных методов, но всЄ-таки в р€де случаев возникает некотора€ специфика из-за неочевидности того, какой вариант метода будет вызван. ѕри разном числе параметров такой проблемы, очевидно, нет. ≈сли же два варианта методов имеют одинаковое число параметров, и отличие только в типе одного или более параметров, возможны логические ошибки.

Ќапишем класс Math1, в котором имеетс€ подпрограмма-функци€ product, вычисл€юща€ произведение двух чисел, у которой имеютс€ варианты с разными целыми типами параметров. ѕример полезен как дл€ иллюстрации проблем, св€занных с вызовом перегруженных методов, так и дл€ исследовани€ проблем арифметического переполнени€.

 

public class Math1 {

 

public static byte product(byte x, byte y){

return x*y;

}

 

public static short product(short x, short y){

return x*y;

}

 

public static int product(int x, int y){

return x*y;

}

 

public static char product(char x, char y){

return x*y;

}

 

public static long product(long x, long y){

return x*y;

}

 

}

 

“акое задание методов разрешено, так как сигнатуры перегружаемых вариантов различны. ќбратим внимание на типы возвращаемых значений Ц они могут задаватьс€ по желанию программиста. ѕодпрограммы заданы как методы класса (static) дл€ того, чтобы при их использовании не пришлось создавать объект.

 

≈сли бы мы попытались задать такие варианты методов:

 

public static byte product(byte x, byte y){

return x*y;

}

 

public static int product(byte a, byte b){

return a*b;

}

то компил€тор выдал бы сообщение об ошибке, так как у данных вариантов одинакова€ сигнатура. - Ќи тип возвращаемого значени€, ни имена параметров на сигнатуру не вли€ют.

 

≈сли при вызове метода product параметры имеют типы, совпадающие с заданными в одном из перегруженных вариантов, всЄ просто. Ќо что произойдЄт в случае, когда в качестве параметра будут переданы значени€ типов byte и int?  акой вариант будет вызван? ѕроверка идЄт при компил€ции программы, при этом перебираютс€ все допустимые варианты. ¬ нашем случае это product(int x, int y) и product(long x, long y). ќстальные варианты не подход€т из-за типа второго параметра Ц тип подставл€емого значенни€ должен иметь диапазон значений, Увписывающийс€Ф в диапазон вызываемого метода. »з допустимых вариантов выбираетс€ тот, который ближе по типу параметров, то есть в нашем случае product(int x, int y).

≈сли среди перегруженных методов среди разрешЄнных вариантов не удаЄтс€ найти предпочтительный, при компил€ции класса, где делаетс€ вызов, выдаЄтс€ диагностика ошибки. “ак бы случилось, если бы мы имели следующую реализацию класса Math2

 

public class Math2 {

 

public static int product(int x, byte y){

return x*y;

}

 

public static int product(byte x, int y){

return x*y;

}

 

}

 

и в каком-нибудь другом классе имели переменные byte b1, b2 и сделали вызов Math1.product(b1,b2). ќба варианта перегруженного метода подход€т, и выбрать более подход€щий невозможно. ќтметим, что класс Math2 при этом компилируетс€ без проблем Ц в самом нЄм ошибок нет. ѕроблема в том классе, который его использует.

—ама€ непри€тна€ особенность перегрузки Ц вызов не того варианта метода, на который рассчитывал программист. ќсобо опасные ситуации при этом возникают в случае, когда перегруженные методы отличаютс€ типом параметров, и в качестве таких параметров выступают объектные переменные. ¬ этом случае близость совместимых типов определ€етс€ по близости в иерархии наследовани€ Ц по числу этапов наследовани€. ќтметим, что выбор перегруженного варианта проводитс€ статически, на этапе компил€ции. ѕоэтому тип, используемый дл€ этого выбора, определ€етс€ типом объектной переменной, передаваемой в качестве параметра, а не типом объекта, который этой переменной назначен.





ѕоделитьс€ с друзь€ми:


ƒата добавлени€: 2017-02-28; ћы поможем в написании ваших работ!; просмотров: 563 | Ќарушение авторских прав


ѕоиск на сайте:

Ћучшие изречени€:

Ћюди избавились бы от половины своих непри€тностей, если бы договорились о значении слов. © –ене ƒекарт
==> читать все изречени€...

2256 - | 2063 -


© 2015-2024 lektsii.org -  онтакты - ѕоследнее добавление

√ен: 0.012 с.