1629295403-b876e2087bddebea4bc9666fb2377a02 (846199), страница 34
Текст из файла (страница 34)
sFirstNamepublicvoid=sName;SetLastName(stringthis. sLastName=sName)sName)sName;Обратите внимание на явное добавление ключевого слова t h i s . Добавление t h i sк ссылкам на члены не привносит ничего нового, поскольку наличие t h i s подразумевается итак. Однако когда M a i n () делает показанный ниже вызов, t h i s означает s t u d e n t l как вфункции S e t N a m e ( ) , так и в любом другом методе, который может быть вызван:studentl. S e t N a m e ( " J o h n " ,"Smith" ) ;Когда this используется явноОбычно явно использовать t h i s не требуется, так как компилятор достаточно разумен, чтобы разобраться в ситуации. Однако имеются две распространенные ситуации,когда это следует делать. Например, ключевое слово t h i s может потребоваться приинициализации членов данных:classPerson(public s t r i n g s N a m e ;public i n t n I D ;public v o i d I n i t ( s t r i n gГлава 8. Методы классаsName,intnID)185{this.sNamethis.nID=sName;// Имена а р г у м е н т о в те же,// что имена членов-данных= nID;}}Аргументы метода I n i t () носят имена s N a m e и n I D , которые совпадают с имевми соответствующих членов-данных.
Это повышает удобочитаемость, поскольку сравидно, в какой переменной какой аргумент следует сохранить. Единственная проблем!том, что имя s N a m e имеется как в списке аргументов, так и среди членов-данных. Таиситуация оказывается слишком сложной для компилятора.Добавление t h i s проясняет ситуацию, четко определяя, что именно подразумеваяпод s N a m e . ВI n i t ()имяsNameобозначает аргумент функции, в то время иt h i s . s N a m e — член объекта.Ключевое слово t h i s требуется также при сохранении текущего объекдля последующего применения или использования в некоторой друпфункции.
Рассмотрим следующую демонстрационную программу Ref аenc ingThi s Exp1i с i tly:// R e f e r e n c i n g T h i s E x p l i c i t l y// использование t h i susingSystem;namespace-программадемонстрируетявноеReferencingThisExp1iсitly{publicclassProgram{publics t a t i cvoidMain(string[]strings){//Создание студентаS t u d e n t s t u d e n t = newstudent.Init("StephenStudent();Davis",1234);' // В н е с е н и е к у р с а в с п и с о кConsole.WriteLine("Внесение в список Stephen"курса Biology 101");student.Enroll("Biology101");// Вывод п р о с л у ш и в а е м о г о к у р с аConsole.WriteLine("Информация оstudent.DisplayCourse();"+студенте:");// Ожидаем п о д т в е р ж д е н и я п о л ь з о в а т е л яConsole.WriteLine("Нажмите <Enter> для"завершенияDavis"+программы...");Console.Read();}}// S t u d e n t publicclass186класс,описывающийStudentстудентаЧасть III.
Объектно-основанное программировав// Все студенты имеют имя и идентификаторpublicpublicstringintsName;nID;// Курс, прослушиваемый студентомCourselnstance// I n i tpublic-courselnstance;инициализация объектаvoidI n i t ( s t r i n gsName,intnID){this.sNamethis.nID==sName;nID;courselnstance=null;}// E n r o l l - добавление в списокpublicvoidEnroll (stringsCourselD){c o u r s e l n s t a n c e = new C o u r s e l n s t a n c e ( ) ;courselnstance.Init(this,sCourselD);// Вывод имени студента и прослушиваемых курсовpublicvoidDisplay-Course (){Console .
W r i t e L i n e (sName)c o u r s e l n s t a n c e . D i s p l a y ();;// C o u r s e l n s t a n c e - объединение информации о студенте и// прослушиваемом курсеpublicclassCourselnstance{publicpublicStudentstringstudent;sCourselD;// I n i t - связь студента и курсаpublicvoidInit(Studentstudent,stringsCourselD)(this.studentthis.sCourselD==student;sCourselD;// D i s p l a y - вывод имени курсаpublicvoidD i s p l a y (){Console.WriteLine(sCourselD);km 8. Методы класса187В этой программе в объекте S t u d e n t имеются поля для имени и иденткстудента и один экземпляр курса (да, студент не очень ретивый...).
Функциясоздает экземпляр s t u d e n t , после чего вызывает функцию I n i t ( ) для его кзации. В этот момент ссылка c o u r s e l n s t a n c e равна n u l l , поскольку студенназначен ни один курс.Метод E n r o l l ()назначает студенту курс путем инициализации ссылюs e l n s t a n c e новым объектом. Однако метод C o u r s e l n s t a n c e .
I n i t ( ) полземпляр класса S t u d e n t в качестве первого аргумента. Какой экземпляр дол)передан? Очевидно, что вы должны передать текущий объект класса S t u d e nименно тот, ссылкой н а который является t h i s .Что делать при отсутствии thisСмешивать статические функции классов и нестатические методы объектовне из лучших, но тем не менее С# и здесь может прийти на помощь.Чтобы понять, в чем состоит суть проблемы, давайте рассмотримщий исходный текст:// M i x i n g F u n c t i o n s A n d M e t h o d s - совмещение функций// м е т о д о в о б ъ е к т о в может п р и в е с т и к проблемамusingSystem;namespaceклассаиMixingFunctionsAndMethods{publicclassStudent{publicpublicstringstringsFirstName;sLastName;// I n i t S t u d e n t - инициализация объекта s t u d e n tpublic void InitStudent(string sFirstName,stringsLastName)this.sFirstName = sFirstName;this.sLastName = sLastName;// O u t p u t B a n n e r - вывод начальнойpublics t a t i c void OutputBanner()строкиConsole.WriteLine("Никакиххитростей:");// Console.WriteLine(? какой объект используетсяpublicvoidOutputBannerAndName()// Используется класс Student,но// не передаются никакие объектыOutputBanner();188?);статическомуметодуЧасть III.
Объектно-основанное программном// Явная передачаOutputName(this);объекта}// OutputName - вывод имени с т у д е н т аpublics t a t i c void OutputName(Studentstudent){// Здесь объект указан явноConsole.WriteLine("Имястудента{о}",student.ToNameString());}II T o N a m e S t r i n g - п о л у ч е н и е и м е н иpublics t r i n g ToNameString()студента{//////retЗ д е с ь текущий о б ъ е к т у к а з а н н е я в н о ; можноиспользоватьt h i s :return this.sFirstName + " " + this.sLastName;urn sFirstName + " " + sLastName;}}publicclassProgram{publics t a t i cvoidMain(string[]args){S t u d e n t s t u d e n t = new S t u d e n t ( ) ;student.InitStudent("Madeleine",// Вывод з а г о л о в к а и и м е н иStudent.OutputBanner();Student.OutputName(student);Console.WriteLine();// Вывод з а г о л о в к а и и м е н и ещеstudent.OutputBannerAndName();"Cather");раз// Ожидаем п о д т в е р ж д е н и я п о л ь з о в а т е л яConsole.WriteLine("Нажмите <Enter> для " +"завершения программы...");Console.Read();Следует начать с конца программы, с функции M a i n ( ) , чтобы вы лучше разгляделиимеющиеся проблемы.
Программа начинается с создания объекта класса S t u d e n tи инициализации его имени. Затем она хочет всего лишь вывести имя студента с небольшим заголовком.Функция M a i n () вначале выводит заголовок и сообщение с использованием статических функций. Программа вызывает функцию O u t p u t B a n n e r () для вывода строкизаголовка и O u t p u t N a m e () для вывода имени студента. Функция O u t p u t B a n n e r ()Глава 8.
Методы класса189просто выводит строку на консоль. Функция O u t p u t N a m e () получает в качестве аргмента объект класса S t u d e n t , так что она может получить и вывести имя студента.Далее функция M a i n ( ) использует для решения той же задачи функцию объекти вызывает s t u d e n t . O u t p u t B a n n e r A n d N a m e ( ) .Метод s t u d e n t . O u t p u t B a n n e r A n d N a m e ( ) сначала вызывает статическую ф у н кцию O u t p u t B a n n e r ( ) . При этом вызове, поскольку не указан класс, к которому принадлежит функция, подразумевается, что она принадлежит тому же классу, что и вызываниефункция, т.е. классу S t u d e n t . После этого выполняется вызов O u t p u t N a m e ( ) .
Это тоже функция класса, и точно так же устанавливается ее принадлежность классу S t u dОднако эта функция требует передачи ей объекта класса S t u d e n t . Метод stud e n t . O u t p u t B a n n e r A n d N a m e ( ) передает е й в качестве этого аргумента t h i s .Более интересная ситуация возникает при вызове T o N a m e S t r i n g () из OutputN a m e ( ) . Функция O u t p u t N a m e ( ) объявлена как s t a t i c и , таким образом, н е и м е е тt h i s . У нее есть переданный ей объект класса S t u d e n t , который она и использует дляосуществления вызова.Статическая функция не может вызывать нестатические методы без явного указания объекта.
Нет объекта — нет и вызова. В общем случае статическая функция не может обратиться ни к одному нестатическому элементу класса. Однаконестатические методы могут обращаться как к статическим, так и к нестатичским членам класса — данным и функциям.В среде Visual Studio программисту доступна одна важная возможность, известныекак автозавершение (auto-complete). Когда вы вводите имя класса или объекта в вашемисходном тексте, Visual Studio пытается предвидеть, какое имя класса или метода вы намерены ввести.Описать автозавершение в Visual Studio проще на конкретном примере.