Главная страница

Васильев А.Н. Основы программирования на C#. Васильев А. Н. Программирование


Скачать 5.54 Mb.
НазваниеВасильев А. Н. Программирование
АнкорВасильев А.Н. Основы программирования на C
Дата20.09.2022
Размер5.54 Mb.
Формат файлаpdf
Имя файлаVasilev_Programmirovanie-na-C-dlya-nachinayushchih-Osobennosti-y.pdf
ТипДокументы
#686596
страница4 из 40
1   2   3   4   5   6   7   8   9   ...   40
Листинг 1.6. Интерфейсные переменные System;
//
ɂɧɬɟɪɮɟɣɫ:
interface MyInterface{
//
Ɉɛɴɹɜɥɟɧɢɟ ɦɟɬɨɞɚ:
char getChar(int n);
//
Ɉɛɴɹɜɥɟɧɢɟ ɢɧɞɟɤɫɚɬɨɪɚ:
char this[int k]{
get;
}
Абстрактные классы и интерфейсы
ɉɟɪɜɵɣ ɤɥɚɫɫ, ɪɟɚɥɢɡɭɸɳɢɣ ɢɧɬɟɪɮɟɣɫ:
class Alpha:MyInterface{
//
Ɂɚɤɪɵɬɨɟ ɫɢɦɜɨɥɶɧɨɟ ɩɨɥɟ:
private char symb;
//
Ʉɨɧɫɬɪɭɤɬɨɪ ɫ ɫɢɦɜɨɥɶɧɵɦ ɚɪɝɭɦɟɧɬɨɦ:
public Alpha(char s){
//
ɉɨɥɸ ɩɪɢɫɜɚɢɜɚɟɬɫɹ ɡɧɚɱɟɧɢɟ:
symb=s;
}
//
Ɉɩɢɫɚɧɢɟ ɦɟɬɨɞɚ:
public char getChar(int n){
//
Ɋɟɡɭɥɶɬɚɬ:
return (char)(symb+n);
}
//
Ɉɩɢɫɚɧɢɟ ɢɧɞɟɤɫɚɬɨɪɚ:
public char this[int k]{
//
Ⱥɤɫɟɫɫɨɪ ɞɥɹ ɫɱɢɬɵɜɚɧɢɹ ɡɧɚɱɟɧɢɹ:
get{
//
Ɋɟɡɭɥɶɬɚɬ:
return getChar(k);
}
}
}
//
ȼɬɨɪɨɣ ɤɥɚɫɫ, ɪɟɚɥɢɡɭɸɳɢɣ ɢɧɬɟɪɮɟɣɫ:
class Bravo:MyInterface{
//
Ɂɚɤɪɵɬɨɟ ɬɟɤɫɬɨɜɨɟ ɩɨɥɟ:
private string text;
//
Ʉɨɧɫɬɪɭɤɬɨɪ ɫ ɬɟɤɫɬɨɜɵɦ ɚɪɝɭɦɟɧɬɨɦ:
public Bravo(string t){
//
ɉɨɥɸ ɩɪɢɫɜɚɢɜɚɟɬɫɹ ɡɧɚɱɟɧɢɟ:
text=t;
Глава 1
42
}
//
Ɉɩɢɫɚɧɢɟ ɦɟɬɨɞɚ:
public char getChar(int k){
return text[k%text.Length];
}
//
Ɉɩɢɫɚɧɢɟ ɢɧɞɟɤɫɚɬɨɪɚ:
public char this[int k]{
//
Ⱥɤɫɟɫɫɨɪ ɞɥɹ ɫɱɢɬɵɜɚɧɢɹ ɡɧɚɱɟɧɢɹ:
get{
//
Ɋɟɡɭɥɶɬɚɬ:
return getChar(k);
}
}
}
//
Ʉɥɚɫɫ ɫ ɝɥɚɜɧɵɦ ɦɟɬɨɞɨɦ:
class InterfaceVarDemo{
//
Ƚɥɚɜɧɵɣ ɦɟɬɨɞ:
static void Main(){
//
ɐɟɥɨɱɢɫɥɟɧɧɚɹ ɩɟɪɟɦɟɧɧɚɹ:
int m=5;
//
ɂɧɬɟɪɮɟɣɫɧɚɹ ɩɟɪɟɦɟɧɧɚɹ:
MyInterface R;
//
ɋɨɡɞɚɟɬɫɹ ɨɛɴɟɤɬ ɤɥɚɫɫɚ Alpha ɢ ɫɫɵɥɤɚ ɧɚ ɧɟɝɨ
//
ɡɚɩɢɫɵɜɚɟɬɫɹ ɜ ɢɧɬɟɪɮɟɣɫɧɭɸ ɩɟɪɟɦɟɧɧɭɸ:
R=new Alpha('F');
//
ȼɵɡɨɜ ɦɟɬɨɞɚ ɱɟɪɟɡ ɢɧɬɟɪɮɟɣɫɧɭɸ ɩɟɪɟɦɟɧɧɭɸ:
Console.WriteLine(
Ǝɋɢɦɜɨɥɵ ɨɬ \'{0}\' ɞɨ \'{1}\':Ǝ,R.getChar(-m),R.getChar(m));
//
ɂɧɞɟɤɫɢɪɨɜɚɧɢɟ ɨɛɴɟɤɬɚ ɱɟɪɟɡ
//
ɢɧɬɟɪɮɟɣɫɧɭɸ ɩɟɪɟɦɟɧɧɭɸ:
for(int i=-m;i<=m;i++){
Console.Write(
Ǝ|Ǝ+R[i]);
}
Абстрактные классы и интерфейсы Console.WriteLine(
Ǝ|Ǝ);
//
ɋɨɡɞɚɟɬɫɹ ɨɛɴɟɤɬ ɤɥɚɫɫɚ Bravo ɢ ɫɫɵɥɤɚ ɧɚ ɧɟɝɨ
//
ɡɚɩɢɫɵɜɚɟɬɫɹ ɜ ɢɧɬɟɪɮɟɣɫɧɭɸ ɩɟɪɟɦɟɧɧɭɸ:
R=new Bravo(
ƎbravoƎ);
//
ȼɵɡɨɜ ɦɟɬɨɞɚ ɱɟɪɟɡ ɢɧɬɟɪɮɟɣɫɧɭɸ ɩɟɪɟɦɟɧɧɭɸ:
Console.WriteLine(
Ǝɋɢɦɜɨɥɵ ɨɬ \'{0}\' ɞɨ \'{1}\':Ǝ,R.getChar(0),R.getChar(2*m+1));
//
ɂɧɞɟɤɫɢɪɨɜɚɧɢɟ ɨɛɴɟɤɬɚ ɱɟɪɟɡ
//
ɢɧɬɟɪɮɟɣɫɧɭɸ ɩɟɪɟɦɟɧɧɭɸ:
for(int i=0;i<=2*m+1;i++){
Console.Write(
Ǝ|Ǝ+R[i]);
}
Console.WriteLine(
Ǝ|Ǝ);
Результат выполнения программы следующий Результат выполнения программы (из листинга 1.6)

ɋɢɦɜɨɥɵ ɨɬ 'A' ɞɨ 'K':
|A|B|C|D|E|F|G|H|I|J|K|
ɋɢɦɜɨɥɵ ɨɬ 'b' ɞɨ 'В программе описан интерфейс MyInterface. В этом интерфейсе объявляется метод getChar() с целочисленным аргументом и символьным результатом, а также объявлен индексатор с целочисленным индексом и символьным значением. Интерфейс MyInterface реализуется в классах Alpha и Bravo. В классе Alpha имеется закрытое символьное поле symb и конструктор с одним аргументом (определяет значение символьного поля. Метод getChar() описан в классе так, что результатом возвращается значение выражения (char)(symb+n). Это значение вычисляется следующим образом к коду символа из поля symb прибавляется целочисленное значение аргумента метода n, и полученное целое число преобразуется к символьному типу. Индексатор определен
Глава так, что при заданном индексе k результатом возвращается значение выражения. То есть при индексировании объекта с индексом k
и вызове метода getChar() с аргументом k по определению получаем один и тот же результат. Стоит сразу отметить, что в классе Bravo ин- дексатор определен также на основе метода getChar(). Этот класс тоже реализует интерфейс MyInterface. В классе есть закрытое текстовое поле text и конструктор с текстовым аргументом, определяющим значение текстового поля. Метод getChar() определен таким образом, что при аргументе k в качестве результата возвращается значение выражения text[k%text.Length]. Это символ из текстового поля text с индексом k (с учетом циклической перестановки индекса, если он выходит за верхнюю допустимую границу ПОДРОБНОСТИ bЗначением выражения k%text.Length является значение k
, если значение меньше значения выражения text.Length
(количество символов в тексте. Вообще же значение выражения k%text.Length
— это остаток отделения значения k
назначение Как отмечалось выше, для индексатора с индексом k результатом возвращается значение getChar(k).
{
i
НАЗ А МЕТКУ Метод getChar()
в классе
Alpha определен так, что объект этого класса можно индексировать, помимо прочего, и отрицательными индексами. В классе
Bravo метод getChar()
определен таким образом, что индексировать объект класса можно только неотрицательными индексами.
В главном методе командой MyInterface R объявляется интерфейсная переменная R типа MyInterface. Командой R=new Alpha(
ƍFƍ) создается объект класса Alpha, и ссылка на него записывается в интерфейсную переменную R. Так можно делать, поскольку класс Alpha реализует интерфейс MyInterface. При значении -5 целочисленной переменной выполняется оператор цикла, в котором индексная переменная i пробегает значения от -m до m, отображаются значение, выражения
R[i]
с проиндексированным объектом. Получаем последовательность символов, начиная с символа за 5 позиций до символа
ƍFƍ (аргумент конструктора класса Alpha при создании объекта) до символа через
Абстрактные классы и интерфейсы позиций после
ƍFƍ. Первый и последний символы в этой последовательности можно вычислить с помощью выражений R.getChar(-m) ив которых через интерфейсную переменную вызывается метод объекта, на который переменная ссылается.
Похожие операции выполняются с объектом класса Bravo. Этот объект создается командой R=new Bravo(
ƎbravoƎ), а ссылка на него записывается в интерфейсную переменную R. Как ив предыдущем случае, когда переменная R ссылалась на объект класса Alpha, мы можем вызывать через переменную метод getChar() (команды R.getChar(0) и R.getChar(2*m+1)), а также можем индексировать объект, на который ссылается переменная (команда вида R[i]). При этом необходимо учитывать, что перебор символов выполняется в тексте
ƎbravoƎ (аргумент, переданный конструктору класса Bravo при создании объекта) с использованием принципа циклической перестановки индекса, если он выходит за верхнюю допустимую границу НАЗ А МЕТКУ При вызове метода через интерфейсную переменную версия метода определяется по объекту, из которого вызывается метод. Собственно, других, даже теоретических, вариантов здесь нет, поскольку в интерфейсе метод только объявляется, ноне описывается.
Явная реализация членов интерфейса Вот у вас, на Земле, как вы определяете — кто перед кем сколько должен присесть Ну, это на глаз...
из к/ф «Кин-дза-дза»
Если класс реализует несколько интерфейсов, то может сложиться ситуация, когда в нескольких интерфейсах объявлен один и тот же метод, свойство или индексатор. В таком случаев классе, реализующем интерфейсы, достаточно один раз описать соответствующий член. В следующем примере класс реализует два интерфейса, которые содержат объявление одинаковых методов. Код упрощен, чтобы легче было понять суть. Программа представлена в листинге 1.7.
Глава 1
46

Листинг 1.7. Интерфейсы и неявная реализация членов System;
//
ɉɟɪɜɵɣ ɢɧɬɟɪɮɟɣɫ:
interface First{
void show();
}
//
ȼɬɨɪɨɣ ɢɧɬɟɪɮɟɣɫ:
interface Second{
void show();
}
//
Ʉɥɚɫɫ ɪɟɚɥɢɡɭɟɬ ɢɧɬɟɪɮɟɣɫɵ:
class MyClass:First,Second{
//
Ɉɩɢɫɚɧɢɟ ɦɟɬɨɞɚ:
public void show(){
Console.WriteLine(
ƎɈɛɴɟɤɬ ɤɥɚɫɫɚ MyClassƎ);
}
}
//
Ʉɥɚɫɫ ɫ ɝɥɚɜɧɵɦ ɦɟɬɨɞɨɦ:
class ImplInterfaceDemo{
//
Ƚɥɚɜɧɵɣ ɦɟɬɨɞ:
static void Main(){
//
ɋɨɡɞɚɧɢɟ ɨɛɴɟɤɬɚ:
MyClass obj=new MyClass();
//
ɋɫɵɥɤɚ ɧɚ ɨɛɴɟɤɬ ɡɚɩɢɫɵɜɚɟɬɫɹ
//
ɜ ɢɧɬɟɪɮɟɣɫɧɵɟ ɩɟɪɟɦɟɧɧɵɟ:
First A=obj;
Second B=obj;
//
ȼɵɡɨɜɵ ɦɟɬɨɞɚ ɱɟɪɟɡ ɪɚɡɧɵɟ ɩɟɪɟɦɟɧɧɵɟ:
obj.show();
A.show();
Абстрактные классы и интерфейсы B.show();
Ниже представлен результат выполнения программы Результат выполнения программы (из листинга 1.7)

Ɉɛɴɟɤɬ ɤɥɚɫɫɚ MyClass
Ɉɛɴɟɤɬ ɤɥɚɫɫɚ MyClass
Ɉɛɴɟɤɬ ɤɥɚɫɫɚ В программе описаны интерфейсы First ив каждом из которых объявлен метод show() без аргументов, не возвращающий результат. Класс MyClass реализует оба эти интерфейса, но метод show() в классе описан только один раз (при вызове метод выводит сообщение в консоль. В главном методе программы создается объект класса MyClass ив три переменные (объектная obj класса MyClass, интерфейсная A типа First и интерфейсная переменная B типа Second) записывается ссылка на него. Затем через каждую из трех переменных вызывается метод show(). Вполне ожидаемо результат во всех трех случаях один и тот же ПОДРОБНОСТИ bЕсли бы в рассмотренном выше примере кроме интерфейсов
First и
Second был еще и абстрактный базовый класс
Base
, в котором объявлен абстрактный метод show()
, то ситуация разрешалась бы похожим образом. В классе
MyClass
, наследующем класс
Base и реализующем интерфейсы
First и
Second
, следовало бы описать метод show()
, нов описании метода необходимо использовать ключевое слово Ноу насесть и альтернатива. Мы можем воспользоваться явной реализацией методов, свойств и индексаторов интерфейса. При явной реализации, когда соответствующий член описывается в классе, перед его именем (через точку) указывается название интерфейса, а спецификатор уровня доступа не указывается. Доступ к такому члену класса можно получить через переменную соответствующего интерфейса. Дальше обратимся к примеру. Программа представлена в листинге 1.8.
Глава 1
48

Листинг 1.8. Интерфейсы и явная реализация членов System;
//
Ȼɚɡɨɜɵɣ ɤɥɚɫɫ:
abstract class Base{
//
Ⱥɛɫɬɪɚɤɬɧɨɟ ɫɜɨɣɫɬɜɨ:
public abstract char symbol{
get;
}
//
Ⱥɛɫɬɪɚɤɬɧɵɣ ɢɧɞɟɤɫɚɬɨɪ:
public abstract int this[int k]{
get;
}
//
Ⱥɛɫɬɪɚɤɬɧɵɣ ɦɟɬɨɞ:
public abstract void show();
}
//
ɉɟɪɜɵɣ ɢɧɬɟɪɮɟɣɫ:
interface First{
//
ɋɜɨɣɫɬɜɨ:
char symbol{
get;
}
//
ɂɧɞɟɤɫɚɬɨɪ:
int this[int k]{
get;
}
//
Ɇɟɬɨɞ:
void show();
}
//
ȼɬɨɪɨɣ ɢɧɬɟɪɮɟɣɫ:
interface Second{
//
ɋɜɨɣɫɬɜɨ:
char symbol{
Абстрактные классы и интерфейсы get;
}
//
ɂɧɞɟɤɫɚɬɨɪ:
int this[int k]{
get;
}
//
Ɇɟɬɨɞ:
void show();
}
//
ɉɪɨɢɡɜɨɞɧɵɣ ɤɥɚɫɫ ɧɚɫɥɟɞɭɟɬ ɚɛɫɬɪɚɤɬɧɵɣ ɛɚɡɨɜɵɣ ɤɥɚɫɫ
//
ɢ ɪɟɚɥɢɡɭɟɬ ɢɧɬɟɪɮɟɣɫɵ:
class MyClass:Base,First,Second{
//
Ɂɚɤɪɵɬɨɟ ɫɢɦɜɨɥɶɧɨɟ ɩɨɥɟ:
private char smb;
//
Ʉɨɧɫɬɪɭɤɬɨɪ ɫ ɫɢɦɜɨɥɶɧɵɦ ɚɪɝɭɦɟɧɬɨɦ:
public MyClass(char s):base(){
smb=s;
}
//
Ɉɩɢɫɚɧɢɟ ɫɜɨɣɫɬɜɚ ɢɡ ɚɛɫɬɪɚɤɬɧɨɝɨ ɤɥɚɫɫɚ:
public override char symbol{
get{
return smb;
}
}
//
əɜɧɚɹ ɪɟɚɥɢɡɚɰɢɹ ɫɜɨɣɫɬɜɚ ɢɡ ɢɧɬɟɪɮɟɣɫɚ First:
char First.symbol{
get{
return (char)(smb+1);
}
}
//
Ɉɩɢɫɚɧɢɟ ɢɧɞɟɤɫɚɬɨɪɚ ɢɡ ɛɚɡɨɜɨɝɨ ɤɥɚɫɫɚ:
public override int this[int k]{
Глава 1
50
get{
return smb+k;
}
}
//
əɜɧɚɹ ɪɟɚɥɢɡɚɰɢɹ ɢɧɞɟɤɫɚɬɨɪɚ ɢɡ ɢɧɬɟɪɮɟɣɫɚ Second:
int Second.this[int k]{
get{
return smb-k;
}
}
//
Ɉɩɢɫɚɧɢɟ ɦɟɬɨɞɚ ɢɡ ɛɚɡɨɜɨɝɨ ɤɥɚɫɫɚ:
public override void show(){
Console.WriteLine(
ƎȻɚɡɨɜɵɣ ɤɥɚɫɫ Base:\t\ƍ{0}\ƍƎ,symbol);
}
//
əɜɧɚɹ ɪɟɚɥɢɡɚɰɢɹ ɦɟɬɨɞɚ ɢɡ ɢɧɬɟɪɮɟɣɫɚ First:
void First.show(){
Console.WriteLine(
Ǝɂɧɬɟɪɮɟɣɫ First:\t\ƍ{0}\ƍƎ,symbol);
}
//
əɜɧɚɹ ɪɟɚɥɢɡɚɰɢɹ ɦɟɬɨɞɚ ɢɡ ɢɧɬɟɪɮɟɣɫɚ Second:
void Second.show(){
Console.WriteLine(
Ǝɂɧɬɟɪɮɟɣɫ Second:\t\ƍ{0}\ƍƎ,symbol);
}
}
//
Ʉɥɚɫɫ ɫ ɝɥɚɜɧɵɦ ɦɟɬɨɞɨɦ:
class ExplInterfaceDemo{
//
Ƚɥɚɜɧɵɣ ɦɟɬɨɞ:
static void Main(){
//
ɋɨɡɞɚɧɢɟ ɨɛɴɟɤɬɚ:
MyClass obj=new MyClass(
ƍAƍ);
//
ɂɧɬɟɪɮɟɣɫɧɵɟ ɩɟɪɟɦɟɧɧɵɟ:
First A=obj;
Second B=obj;
Абстрактные классы и интерфейсы //
ȼɵɡɨɜ ɦɟɬɨɞɚ ɱɟɪɟɡ ɩɟɪɟɦɟɧɧɵɟ:
obj.show();
A.show();
B.show();
//
ɋɱɢɬɵɜɚɧɢɟ ɡɧɚɱɟɧɢɹ ɫɜɨɣɫɬɜɚ:
Console.WriteLine(
Ǝobj.symbol=\ƍ{0}\ƍƎ,obj.symbol);
Console.WriteLine(
Ǝ A.symbol=\ƍ{0}\ƍƎ,A.symbol);
Console.WriteLine(
Ǝ B.symbol=\ƍ{0}\ƍƎ,B.symbol);
//
ɂɧɞɟɤɫɢɪɨɜɚɧɢɟ ɨɛɴɟɤɬɚ:
Console.WriteLine(
Ǝobj[10]={0}Ǝ,obj[10]);
Console.WriteLine(
Ǝ A[10]={0}Ǝ,A[10]);
Console.WriteLine(
Ǝ B[10]={0}Ǝ,B[10]);
Результат выполнения программы следующий Результат выполнения программы (из листинга 1.8)

Ȼɚɡɨɜɵɣ ɤɥɚɫɫ Base: 'A'
ɂɧɬɟɪɮɟɣɫ First: 'A'
ɂɧɬɟɪɮɟɣɫ Second: ƍAƍ
obj.symbol=
ƍAƍ
A.symbol=
ƍBƍ
B.symbol=
ƍAƍ
obj[10]=75
A[10]=75
Интерфейсы First и Second описаны одинаково. Отличает их только название. В каждом из интерфейсов объявлено символьное свойство с get-аксессором, индексатор с целочисленным индексом и get-аксессором и метод show() — без аргументов и не возвращающий результат. Такая же начинка и у абстрактного класса Base, но только с поправкой на использование в описании соответствующих членов
Глава ключевых слови. Класс MyClass наследует класс
Base и реализует интерфейсы First и Second. В этом классе появляется закрытое символьное поле smb и конструктор с одним символьным аргументом, который определяет значение поля. Но нас, конечно, в первую очередь интересует тот способ, которым описывается метод show()
, свойство symbol и индексатор.
Свойство symbol описано дважды. Одно из описаний свойства — это обычное описание унаследованного из абстрактного класса свойства. При запросе значения свойства результатом возвращается значение поля smb. Также в классе есть явная специализация для свойства из интерфейса. Данная версия описана без ключевого слова public, а название свойства указано в виде First.symbol. Значение свойства вычисляется как (char)(smb+1). Это следующий символ после символа, записанного в полено значение самого поля smb при этом не меняется. Такая версия свойства будет задействована, если мы будем обращаться к объекту класса MyClass через интерфейсную переменную типа First. Если мы будем получать доступ к объекту через объектную переменную класса MyClass или интерфейсную переменную типа
Second
, то используется первая версия свойства.
У индексатора также две версии. Одна описана как свойство, переопределяемое в производном классе. При запросе значения выражения с проиндексированным объектом при заданном индексе k результатом возвращается значение smb+k (сумма кода символа из поля smb и индекса k). Явная реализация индексатора выполняется для интерфейса Second. Версия описывается без ключевого слова public, а вместо ключевого слова this используется конструкция Second.this. Запрос значения выражения с проиндексированным объектом вычисляется как разность кода символа из поля smb и индекса k (выражение smb-k). Явная реализация индексатора будет задействована, если мы станем индексировать объект через интерфейсную переменную типа Second. При индексировании объекта через объектную переменную класса MyClass или через интерфейсную переменную типа First в игру вступает первая версия индексатора.
У метода show() в классе MyClass есть три версии. Версия с ключевым словом override вызывается через объектную переменную базового класса. Явная реализация метода из интерфейса First задейству- ется при обращении к объекту через переменную интерфейсного типа
Абстрактные классы и интерфейсы. При обращении к объекту через интерфейсную переменную типа Second используется явная реализация метода для интерфейса
Second
. Каждая версия метода отображает значение свойства symbol объекта и название класса или интерфейса, для которого выполнена реализация метода ПОДРОБНОСТИ bВообще общая концепция использования явных реализаций методов, свойств и индексаторов интерфейса немного другая. Мы можем для интерфейса выполнить явную реализацию метода, свойства, индексатора. И если обращение к объекту выполняется через интерфейсную переменную соответствующего типа, то используется данная явная реализация для метода, свойства, индексатора. Во всех прочих случаях используются обычные реализации (или неявные реализации — для них не указывается имя интерфейса. Что касается метода show()
, то для него определены явные реализации для интерфейсов
First и
Second
. Первая используется, если доступ к объекту выполняется через ссылку типа
First
, а вторая — при использовании переменной типа
Second
. Во всех прочих случаях используется версия, переопределяющая абстрактный метод из класса
Base
. Для нас все прочие случаи — это обращение к объекту через объектную переменную класса В главном методе командой MyClass obj=new MyClass(
ƍAƍ) создается объект класса MyClass. Командами First A=obj и Second
B=obj ссылка на этот объект записывается в интерфейсные переменные
A
и B. Переменные A, B и obj мы используем для вызова метода show() команды obj.show(), A.show() и B.show()), считывания значения свойства symbol (инструкции obj.symbol, A.symbol и B.symbol) и индексирования объектов (инструкции obj[10], A[10] и B[10]). Верится, что особых пояснений результат выполнения программы не требует. Но есть одно обстоятельство, связанное с методом show(). В этом методе выполняется обращение к свойству symbol. Но через какую бы переменную мы ни вызывали метод, всегда используется общая версия свойства, поэтому во всех трех случаях значение свойства равно
ƍAƍ значение аргумента, переданного конструктору класса MyClass при создании объекта. А вот когда мы обращаемся к свойству через переменную, то получаем значение
ƍBƍ, поскольку здесь задействована явная реализация для данного свойства
Глава 1
54
Резюме
Не надо булочной. Не надо справочной.
из к/ф «Кин-дза-дза»
• Абстрактным называется метод, который не содержит описания у него нет тела с командами, выполняемыми при вызове метода. Абстрактный метод описывается с ключевым словом abstract
. Если в классе есть хотя бы один абстрактный метод, то такой класс является абстрактным. Абстрактный класс также описывается с ключевым словом abstract
• На основе абстрактного класса нельзя создать объектно можно объявить объектную переменную абстрактного класса. Абстрактный класс используется как базовый для создания производных классов. В производном классе (если он не является абстрактным) должны быть описаны (переопределены) все абстрактные методы из абстрактного базового класса Абстрактные методы по умолчанию являются виртуальными. Ключевое слово virtual в объявлении абстрактных методов не используется. При описании (переопределении) абстрактных методов в производном классе используется ключевое слово override
. Абстрактный метод не может быть статическим Свойства и индексаторы также могут быть абстрактными. При объявлении абстрактного свойства или индексатора используется ключевое слово abstract
. В теле абстрактного свойства или индексатора указываются ключевые слова get и set
(без тела с выполняемыми командами. Если у свойства или индексатора должен быть только один аксессор, то указывается только одно из ключевых словили (в зависимости оттого, какой аксессор должен быть у свойства или индексатора). При описании (переопределении) таких свойств и индексаторов указывается ключевое слово override
• Интерфейс представляет собой блок из объявления методов, ин- дексаторов, свойств (и событий. Описание интерфейса начинается с ключевого слова interface
, после которого указывается название интерфейса. В блоке из фигурных скобок выполняется объявление методов, свойств и индексаторов. Объявление выполняется также, как и объявление соответствующих абстрактных членов абстрактного класса, но при этом ключевые слова public и abstract
1   2   3   4   5   6   7   8   9   ...   40


написать администратору сайта