Главная | Обратная связь | Поможем написать вашу работу!
МегаЛекции

Доступ к членам базового класса из производного.

Модификаторы доступа

Объявленная доступность Значение
public (открытый) Доступен всем методам во всех сборках.
protected Доступен только методам в определяющем типе и вложенных в него типах или одном из его производных типов независимо от сборки
internal (внутренний) Доступен только методам в определяющей сборке.
protected internal Доступ ограничен текущей сборкой или типами, которые являются производными от содержащего класса. (Защищенный OR внутренний)
private(закрытый) Доступен только методам в определяющем типе и вложенных в него типах.

Модификаторы доступа для типов

class- modifier struct-modifier: interface-modifier enum-modifier: delegate-modifier:
new public protected internal private abstract sealed static new public protected internal private new public protected internal private   new public protected internal private new public protected internal private

Наследование. Полиморфизм. Базовый класс (base) и производный класс (derived)

class A {}

class B: A {}

Структуры не поддерживают наследование, но они могут реализовывать интерфейсы.

В языке С# производный класс может наследовать свойства только одного базового класса.

Конструкторы. Конструкторы экземпляров не наследуются. Пример.

using System;

namespace ConsoleApplication16

{

class BaseClass

{

public BaseClass()

{

Console.WriteLine("Вызван конструктор базового класса");

}

}

class DerivedClass: BaseClass

{

public DerivedClass()

{

Console.WriteLine("Вызван конструктор производного класса");

}

}

class Program

{

static void Main(string[] args)

{

DerivedClass md = new DerivedClass();

}

}

}

При создании экземпляра производного класса вызывается конструктор производного класса, который вызывает конструктор базового класса, выполняется код конструктора базового класса, после этого выполняется код конструктора производного класса.

 

Если в базовом классе определено несколько перегруженных конструкторов необходимо определить конструктор без параметров, если его нет выдается сообщение об ошибке. Для вызова конструктора с параметром необходимо использовать инициализатор конструкторов base. Пример. Использование base.

using System;

namespace ConsoleApplication16

{

public class BaseClass

{

int num;

public BaseClass()

{

Console.WriteLine("in BaseClass()");

}

public BaseClass(int i)

{

this.num = i;

Console.WriteLine("in BaseClass(int i)");

}

 

public int GetNum()

{

return num;

}

}

public class DerivedClass: BaseClass

{

// This constructor will call BaseClass.BaseClass()

public DerivedClass(): base()

{

}

// This constructor will call BaseClass.BaseClass(int i)

public DerivedClass(int i): base(i)

{

}

}

class Program

{

static void Main(string[] args)

{

DerivedClass md = new DerivedClass();

DerivedClass md1 = new DerivedClass(1);

Console.WriteLine(md1.GetNum());

}

}

}

Доступ к членам базового класса из производного.

Поля и методы, объявленные в базовом классе с модификатором private, будут доступны только в методах базового класса. С помощью модификатора protected можно предоставить доступ к полям и методам базового класса для методов производных классов, но не для внешних по отношению к классу методов. Пример.

using System;

namespace ConsoleApplication16

{

public class Person

{

protected string ssn = "444-55-6666";

protected string name = "John L. Malgraine";

public virtual void GetInfo()

{

Console.WriteLine("Name: {0}", name);

Console.WriteLine("SSN: {0}", ssn);

}

}

class Employee: Person

{

public string id = "ABC567EFG";

public override void GetInfo()

{

base.name = "ttttttttttt";

base.GetInfo();

Console.WriteLine("Employee ID: {0}", id);

}

}

class TestClass

{

static void Main()

{

Employee E = new Employee();

E.GetInfo();

}

}

}

Базовые классы могут определять и реализовывать виртуальные методы, а производные классы могут переопределять их. Виртуальный метод не может быть статическим. Переопрелеленный метод является виртуальным и может быть переопределен. Для переопределения невиртуального метода (сокрытие) используется ключевое слово new. Модификатор new создает новый элемент с таким же именем. Пример.

public class BaseClass

{

public void DoWork() { Console.WriteLine("Метод базового класса");}

}

public class DerivedClass: BaseClass

{

public new void DoWork() { Console.WriteLine("Метод производного класса"); }

}

class Program

{

static void Main(string[] args)

{

DerivedClass B = new DerivedClass();

B.DoWork(); // Calls the new method.

BaseClass A = new BaseClass();

A.DoWork(); // Calls the old method.

BaseClass AA = (BaseClass)B;

AA.DoWork();

BaseClass AAA = new DerivedClass();

AAA.DoWork();

}

}

Сравните

public class BaseClass

{

public virtual void DoWork() { Console.WriteLine("Метод базового класса");}

}

public class DerivedClass: BaseClass

{

public override void DoWork() { Console.WriteLine("Метод производного класса"); }

}

class Program

{

static void Main(string[] args)

{

DerivedClass B = new DerivedClass();

B.DoWork(); // Calls the new method.

BaseClass A = new BaseClass();

A.DoWork(); // Calls the old method.

BaseClass AA = (BaseClass)B;

AA.DoWork();

BaseClass AAA = new DerivedClass();

AAA.DoWork();

}

}

Задание. Создать базовый класс Shape. Создать производные классы Point и Rectangle.

static void Main(string[] args)

{

Shape[] allShapes = new Shape[4];

allShapes[0] = new Rectangle(1, 24, 10, 20);

allShapes[1] = new Point(10, 25);

allShapes[2] = new Point(1, 25);

allShapes[3] = new Rectangle(1, 4, 10, 20);

foreach (Shape s in allShapes)

{

s.Draw();

}

}


Наследование

Создать два класса в каждом конструктор и метод

using System;

namespace ConsoleApplication17

{

class Point

{

int x;

int y;

public Point(int x, int y)

{

this.x = x;

this.y = y;

}

public void Draw()

{

Console.WriteLine("Рисование точки в ({0}, {1})", x, y);

}

}

class Rectangle

{

int x;

int y;

int w;

int h;

public Rectangle(int x, int y, int w,int h)

{

this.x = x;

this.y = y;

this.w = w;

this.h = h;

}

public void Draw()

{

Console.WriteLine("Рисование прямоугольника в ({0}, {1})", x, y);

}

}

class ShapeApp

{

static void Main(string[] args)

{

Rectangle r = new Rectangle(1, 24, 10, 20);

r.Draw();

Point p = new Point(10, 25);

p.Draw();

}

}

}

 

В классах Point и Rectangle определен метод Draw.


Создать базовый класс Shape

using System;

namespace ConsoleApplication17

{

class Shape

{

protected int x;

protected int y;

public Shape(int x, int y)

{

this.x = x;

this.y = y;

}

}

class Point: Shape

{

public Point(int x, int y): base(x,y)

{

}

public void Draw()

{

Console.WriteLine("Рисование точки в ({0}, {1})", x, y);

}

}

class Rectangle:Shape

{

int w;

int h;

public Rectangle(int x, int y, int w,int h): base(x,y)

{

this.w = w;

this.h = h;

}

public void Draw()

{

Console.WriteLine("Рисование прямоугольника в ({0}, {1})", x, y);

}

}

class ShapeApp

{

static void Main(string[] args)

{

Rectangle r = new Rectangle(1, 24, 10, 20);

r.Draw();

Point p = new Point(10, 25);

p.Draw();

}

}

}

 


Метод Draw класса Shape определим с ключевым словом virtual. Метод Draw производных классов – override, для того чтобы можно было создавать два объекта дочерних: классов, записывая ссылки на эти объекты в переменную с типом базового класса.

 

Shape pt = new Point(10, 25);

Shape rect = new Rectangle(1, 4, 10, 20);

using System;

namespace ConsoleApplication17

{

class Shape

{

protected int x;

protected int y;

public Shape(int x, int y)

{

this.x = x;

this.y = y;

}

public virtual void Draw()

{

}

}

class Point: Shape

{

public Point(int x, int y): base(x,y)

{

}

public override void Draw()

{

Console.WriteLine("Рисование точки в ({0}, {1})", x, y);

}

}

class Rectangle:Shape

{

int w;

int h;

public Rectangle(int x, int y, int w,int h): base(x,y)

{

this.w = w;

this.h = h;

}

public override void Draw()

{

Console.WriteLine("Рисование прямоугольника в ({0}, {1})", x, y);

}

}

class ShapeApp

{

static void Main(string[] args)

{

Shape r = new Rectangle(1, 24, 10, 20);

r.Draw();

Shape p = new Point(10, 25);

p.Draw();

}

}

}
Если public virtual void Draw(int x, int y){} не определена появится сообщение об ошибке. Применение ключевого слова override. Виртуальный метод базового класса подменяется соответствующим методом производного класса не во время компиляции, а во время работы программы.

Таким образом, в следующем фрагменте кода виртуальный метод Draw базового класса Shape подменяется методом Draw производного класса

Создать массив для хранения четырех объектов базового класса Shape:

Shape[] allShapes = new Shape[4];

 

class Shape

{

protected int x;

protected int y;

public Shape(int x, int y)

{

this.x = x;

this.y = y;

}

public virtual void Draw()

{

}

}

class Point: Shape

{

public Point(int x, int y): base(x,y)

{

}

public override void Draw()

{

Console.WriteLine("Рисование точки в ({0}, {1})", x, y);

}

}

class Rectangle:Shape

{

int w;

int h;

public Rectangle(int x, int y, int w,int h): base(x,y)

{

this.w = w;

this.h = h;

}

public override void Draw()

{

Console.WriteLine("Рисование прямоугольника в ({0}, {1})", x, y);

}

}

class ShapeApp

{

static void Main(string[] args)

{

Shape[] allShapes = new Shape[4];

allShapes[0] = new Rectangle(1, 24, 10, 20);

allShapes[1] = new Point(10, 25);

allShapes[2] = new Point(1, 25);

allShapes[3] = new Rectangle(1, 4, 10, 20);

foreach (Shape s in allShapes)

{

s.Draw();

}

}

}

Поделиться:





Воспользуйтесь поиском по сайту:



©2015 - 2024 megalektsii.ru Все авторские права принадлежат авторам лекционных материалов. Обратная связь с нами...