|
Программирование >> Программирование с использованием ajax
Они позволят использовать такой код: AddClassl opl = new AddClassl (); opl.val = 5; AddClass2 op2 = new AddClass2(); op2.val = 5; AddClassS op3 = opl + op2; Когда требуется, можно смешивать типы подобным образом. Обратите, однако, внимание на то, что в случае добавления в AddClass2 такой же операции, предыдущий код не работал бы, поскольку появилась бы неоднозначность по поводу того, какая именно из операций должна использоваться. Это означает, что следует соблюдать осторожность и не добавлять операции с одинаковой сигнатурой в более чем один класс. Помимо этого, в случае смешивания типов, операнды должны обязательно предоставляться перегруженной операции в том же самом порядке, что параметры. При попытке применить перегруженную операцию с операндами, идущими не в том порядке, операция работать не будет. Например, нельзя использовать такую операцию: AddClassS орЗ = ор2 + opl; если только, конечно, не предоставить еще одну перегрузку с идущими в обратном порядке параметрами: public static AddClassS operator +(AddClass2 opl, AddClassl op2) { AddClassS returnVal = new AddClass3(); returnVal.val = opl.val + op2.val; return returnVal; Ниже перечислены все те операции, которые можно перегружать. □ Унарные операции: +, -, !, ~, ++, - , true, false. □ Бинарные операции: +,-,*,/,%,&, , , < <, > >. □ Операции сравнения: ==, !=,<,>,<=, >=. В случае перегрузки операций true и false классы можно использовать в булевских выражениях, таких как i f (opl) {}. Перегружать операции присваивания вроде += нельзя, но у таких операций имеются свои простые аналоги, такие как +, так что волноваться об этом не стоит. Перегрузка + означает, что += будет функционировать, как и ожидалось. Перегружать операцию = тоже нельзя из-за ее фундаментального предназначения, но она связана с определяемыми пользователем операциями преобразования, о которых будет рассказываться в следующем разделе. Еще нельзя перегружать и такие операции, как & & и , но они для выполнения своих вычислений используют операции & и , перегрузки которых вполне достаточно. Некоторые операции, например, < и >, требуется перегружать парами. Другими словами, нельзя перегружать операцию < и не перегружать при этом >. Во многих случаях можно просто вызывать из этих операций другие операции для сокращения количества требуемого кода (и, соответственно, ошибок, которые могут возникнуть), как показано в следующем примере: public class AddClassl { GetHashCode () применяется для получения уникального значения int для экземпляра объекта на основе его состояния. Здесь использование val является допустимым, потому что val тоже является значением типа int. Обратите внимание на то, что в Equals () применяется параметр типа object. Такая сигнатура является необходимой, иначе это будет перегрузка, а не переопределение данного метода, и тогда реализация по умолчанию все равно будет доступна пользователям класса. Вместо этого для получения требуемого результата необходимо применять приведение типов. Зачастую проверка типа объекта с помощью описанной ранее операции is является стоящим делом, как, например, в показанном ниже коде: public static bool operator >= (AddClassl opl, AddClassl op2) { return (opl.val >= op2.val); public static bool operator < (AddClassl opl, AddClassl op2) { return !(opl >= op2) ; Также необходрош реалиэахц1и для операции <= и >. В определениях более сложных операций такой подход действительно может сокращать количество подлежащих написанию строк кода, а также, следовательно, и объем изменяемого кода в случае, если позже понадобится изменить реализацию этих операций. То же самое касается операций == и ! =, но в их случае зачастую лучше переопределять методы Ob j ect. Equals () и Ob j ect. GetHashCode (), поскольку они оба тоже могут применяться для сравнения объектов. Переопределение этих методов обеспечивает гарантию того, что какой бы прием не использовали пользователи класса, результат они будут получать одинаковый. Существенным этот факт не является, но заслуживает упоминания для полноты изложения и требует применения следующих нестатических переопределенных методов: public class AddClassl { public int val; public static bool operator ==(AddClassl opl, AddClassl op2) return (opl.val == op2.val); public static bool operator !=(AddClassl opl, AddClassl op2) return ! (opl == op2) ; public override bool Equals (object opl) return val = ((AddClassl)opl) .val; public override int GetHashCodeO return val; public override bool Equals(ob]ect opl) { if (opl is AddClassl) { return val == ( (AddClassl)opl).val; else { throw new ArgumentException ( Cannot солфаге AddClassl objects with objects of type + opl. GetType () . ToString ()) ; В этом коде в случае, если переданный методу Equals операнд оказывается не того типа или не может быть приведен к правильному типу, генерируется исключение. Конечно, такое поведение может и не быть подходящим. Вместо него может быть необходимо, чтобы была возможность сравнивать объекты одного типа с объектами другого типа, в случае чего потребуется большее ветвление кода. Или же может быть нужно, чтобы сравнение выполнялось только между объектами абсолютно одинакового типа, в случае чего потребуется внести в первый оператор if следующее изменение: if (opl.GetTypeО == typeof(AddClassl)) Добавление перегруженных операций в CardLib Теперь можно снова обновить проект ChllCardLib, добавив в его класс Card перегрузку операций. Перед этим, однако, потребуется добавить в класс Card дополнительные поля, позволяющие определять козырные масти и назначать тузы старшей картой. Их нужно сделать статическими, поскольку в случае установки для них значений они будут применяться ко всем объектам Card: public class Card { Флаг для применения козырных карт. При значении true козырные карты должны цениться больше, чем карты других мастей, public static bool useTruns = false; Козырная масть, которая должна использоваться в случае, если useTruns равняется true, public static Suit trump = Suit.Club; Флаг, определякхций то, таляются ли тузы старше королей или младше двоек, public static bool isAceHigh = true; Обратите внимание, что эти правила распространяются на все объекты Card в каждом экземпляре Deck в приложении. Невозможно иметь две колоды, карты в каждой из которых подчиняются разным правилам. Для данной библиотеки, однако, подобное допустимо, потому что она позволяет спокойно предположить, что если одно приложение хочет использовать отдельные правила, тогда оно может обслуживать таковые самостоятельно, например, за счет установки значений для статических членов Card при каждой смене колоды. Сделав это, стоить добавить в класс Deck еще несколько конструкторов для инициализации колод с разными характеристиками:
|
© 2006 - 2024 pmbk.ru. Генерация страницы: 0
При копировании материалов приветствуются ссылки. |