Мы поможем в написании ваших работ!



ЗНАЕТЕ ЛИ ВЫ?

Вложенные классы и понятие «Вложенные типы»

Поиск

Вложенные классы и понятие «Вложенные типы»

 

Вложенные классы

 

Иногда некоторый клас с играет чисто вспомогательную роль для другого класса и используется только внутри него. В этом случае логично описать его внутри существующего класса. Вот пример такого описания:

 

using System;

using System.Collections.Generic;

using System.Linq;

using System.Text;

 

namespace LC_Console

{

class ClassA

{

// Вложенный класс

private class ClassB

{

public int z;

}

// Переменная типа вложенного класса

private ClassB w;

// Конструктор

public ClassA()

{

w = new ClassB();

w.z = 35;

}

// Некоторый метод

public int SomeMethod()

{

return w.z;

}

}

class Test

{

static void Main(string[] args)

{

ClassA v = new ClassA();

int k = v.SomeMethod();

Console.WriteLine(k);

// Выведет: 35

Console.WriteLine("Для продолжения нажмите любую клавишу...");;

Console.ReadKey();

}

}

}

 

Здесь класс ClassB объявлен внутри класса ClassA. Объявлен он со словом private, так что его экземпляры мы можем создавать только внутри класса ClassA (что и делаем в конструкторе класса ClassA). Методы класса ClassA имеют доступ к экземпляру класса ClassB (как, например, метод SomeMethod).

Вложенный класс имеет смысл использовать тогда, когда его экземпляр используется только в определенном классе. Кроме того, при использовании вложенных классов улучшается читаемость кода — если нас не интересует устройство основного класса, то разбирать работу вложенного класса нет необходимости.

Обратим также внимание, как вложенные классы показываются на вкладке «Окно классов» в Среде разработки Visual Studio 2010:

 

Рис. 1. Окно классов проекта LC_Console

 

Понятие «Вложенные типы»

 

Итак, тип, определённый внутри класса или структуры, называется вложенным типом. Пример:

 

class Container

{

class Nested

{

Nested() { }

}

}

 

Независимо от того, являются ли внешние типы классом или структурой, вложенные типы по умолчанию являются private, но могут быть также public, protected internal, protected, internal. В предыдущем примере тип Nested недоступен для внешних типов, но он может являться открытым:

 

class Container

{

public class Nested

{

Nested() { }

}

}

 

Вложенный или внутренний тип может получить доступ к содержащему или внешнему типу. Чтобы получить доступ к содержащему типу, передаём его в качестве конструктора во вложенный тип. Пример:

 

public class Container

{

public class Nested

{

private Container parent;

 

public Nested()

{

}

 

public Nested(Container parent)

{

this.parent = parent;

}

}

}

 

Вложенные типы могут получать доступ к закрытым и защищенным членам содержащего типа, включая любые наследуемые закрытые или защищенные члены.

В предыдущем объявлении полным именем класса Nested является Container.Nested. Это имя используется для создания нового экземпляра вложенного класса, как показано ниже:

 

Container.Nested nest = new Container.Nested();

 

Понятие «Абстрактный класс», «Запечатанный класс» и «Разделяемые классы» и «Разделяемые методы»

Понятие «Абстрактный класс», «Запечатанный класс» и «Разделяемые классы» и «Разделяемые методы»

 

Понятие «Абстрактный класс»

 

Ключевое слово abstract позволяет создавать классы и члены классов, которые являются неполными и должны быть реализованы в производном классе.

Классы могут быть объявлены абстрактными классами путём помещения ключевого слова abstract перед определением класса. Пример:

 

public abstract class A

{

// Члены класса

}

 

Создавать экземпляры абстрактного класса нельзя. Назначение абстрактного класса заключается в предоставлении общего определения для базового класса, которое могут совместно использовать несколько производных классов. Например, в библиотеке классов может быть определён абстрактный класс, используемый в качестве параметра для многих из её функций, поэтому программисты, использующие эту библиотеку, должны задать свою реализацию этого класса, создав производный класс.

Абстрактные классы могут определять абстрактные методы. Для этого перед типом возвращаемого значения метода необходимо поместить ключевое слово abstract. Пример:

 

public abstract class A

{

public abstract void DoWork(int i);

}

 

Абстрактные методы не имеют реализации, поэтому определение такого метода заканчивается точкой с запятой вместо обычного блока метода. Классы, производные от абстрактного класса, должны реализовывать все абстрактные методы. Если абстрактный класс наследует виртуальный метод* из базового класса, абстрактный класс может переопределить виртуальный метод с помощью абстрактного метода. Пример:

 

public class D

{

public virtual void DoWork(int i) // Виртуальный метод

{

// Оригинальная реализация

}

}

 

public abstract class E: D

{

public abstract override void DoWork(int i);

}

 

public class F: E

{

public override void DoWork(int i)

{

// Новая реализация

}

}

 

Если метод virtual объявляется abstract, он всё равно считается виртуальным по отношению к любому классу, наследующему от абстрактного класса. Класс, наследующий абстрактный метод, не может обращаться к исходной реализации метода (предыдущий пример, DoWork в классе F не может вызывать DoWork в классе D). Таким образом, абстрактный класс может принуждать производные классы предоставлять новые реализации для виртуальных методов.

 

ПРИМЕЧАНИЕ: virtual ― ключевое слово, которое может употребляться с методами и свойствами, индексаторами и событиями класса, чтобы обозначить, что их реализация может быть переопределена в производных классах с помощью ключевого слова override. Методы, не помеченные как virtual, не могут быть переопределены. Например, этот метод может быть переопределен любым производным классом:

 

public virtual double Area()

{

return x * y;

}

 

При вызове виртуального метода тип времени выполнения объекта проверяется на переопределение члена. Вызывается переопределение члена в самом дальнем классе. Это может быть исходный член, если никакой производный класс не выполнял переопределение этого члена.

По умолчанию методы не являются виртуальными. Такой метод нельзя переопределить.

Модификатор virtual нельзя использовать с модификаторами static, abstract, private или override. В следующем примере показано виртуальное свойство.

 

class MyBaseClass

{

// Виртуально переопределяемое свойство

public virtual string Name { get; set; }

// Прочие члены класса

private int num; // Переменная

public virtual int Number // Свойство

{

get { return num; }

set { num = value; }

}

}

 

 

class MyDerivedClass: MyBaseClass

{

private string name;

// Переопределяем виртуальное свойство в производном классе

public override string Name

{

get

{

return name;

}

set

{

if (value!= String.Empty)

{

name = value;

}

else

{

name = "Неизвестно";

}

}

}

}

 



Поделиться:


Последнее изменение этой страницы: 2016-12-28; просмотров: 275; Нарушение авторского права страницы; Мы поможем в написании вашей работы!

infopedia.su Все материалы представленные на сайте исключительно с целью ознакомления читателями и не преследуют коммерческих целей или нарушение авторских прав. Обратная связь - 13.58.201.75 (0.01 с.)