Главная Случайная страница


Полезное:

Как сделать разговор полезным и приятным Как сделать объемную звезду своими руками Как сделать то, что делать не хочется? Как сделать погремушку Как сделать так чтобы женщины сами знакомились с вами Как сделать идею коммерческой Как сделать хорошую растяжку ног? Как сделать наш разум здоровым? Как сделать, чтобы люди обманывали меньше Вопрос 4. Как сделать так, чтобы вас уважали и ценили? Как сделать лучше себе и другим людям Как сделать свидание интересным?


Категории:

АрхитектураАстрономияБиологияГеографияГеологияИнформатикаИскусствоИсторияКулинарияКультураМаркетингМатематикаМедицинаМенеджментОхрана трудаПравоПроизводствоПсихологияРелигияСоциологияСпортТехникаФизикаФилософияХимияЭкологияЭкономикаЭлектроника






Ссылки на базовый класс и объекты производных классов





// Эта программа не подлежит компиляции.

using System;

class X

{

int a;

public X(int i) { a = i; }

}

class Y

{

int a;

public Y(int i) { a = i; }

}

class IncompatibleRef

{

static void Main()

{

X x = new X(10);

X x2;

Y y = new Y(5);

x2 = x; //верно, поскольку оба объекта относятся к одному и тому же типу

x2 = y; //ошибка, поскольку это разнотипные объекты

}

}

Несмотря на то что классы X и Y в данном примере совершенно одинаковы по своей структуре, ссылку на объект типа Y нельзя присвоить переменной ссылки на объект типа X, поскольку типы у них разные.

Вообще говоря, переменная ссылки на объект может ссылаться только на объект своего типа.

Но из этого принципа строгого соблюдения типов в C# имеется одно важное исключение: переменной ссылки на объект базового класса может быть присвоена ссылка на объект любого производного от него класса.

// По ссылке на объект базового класса можно обращаться

// к объекту производного класса.

using System;

class X

{

public int a;

public X(int i)

{

a = i;

}

}

class Y: X

{

public int b;

public Y(int i, int j)

: base(j)

{

b = i;

}

}

class BaseRef

{

static void Main()

{

X x = new X(10);

X x2;

Y у = new Y(5, 6);

x2 = x; // верно, поскольку оба объекта относятся к одному и тому же типу

Console.WriteLine("х2.а: " + x2.a);

x2 = у; // тоже верно, поскольку класс Y является производным от класса X

Console.WriteLine("х2.а: " + x2.a);

// ссылкам на объекты класса X известно только о членах класса X

x2.a = 19; // верно

// х2.b = 27; // неверно, поскольку член b отсутствует у класса X

}

}

Следует особо подчеркнуть, что доступ к конкретным членам класса определяется типом переменной ссылки на объект, а не типом объекта, на который она ссылается. Это означает, что если ссылка на объект производного класса присваивается переменной ссылки на объект базового класса, то доступ разрешается только к тем частям этого объекта, которые определяются базовым классом. Именно поэтому переменной х2 недоступен член b класса Y, когда она ссылается на объект этого класса. И в этом есть

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

Один из самых важных моментов для присваивания ссылок на объекты производного класса переменным базового класса наступает тогда, когда конструкторы вызываются в иерархии классов. Как вам должно быть уже известно, в классе нередко определяется конструктор, принимающий объект своего класса в качестве параметра. Благодаря этому в классе может быть сконструирована копия его объекта. Этой особенностью можно выгодно воспользоваться в классах, производных от такого класса. В качестве примера рассмотрим очередные варианты классов TwoDShape и Triangle. В оба класса добавлены конструкторы, принимающие объект в качестве параметра.

// Передать ссылку на объект производного класса

// переменной ссылки на объект базового класса.

using System;

class TwoDShape

{

double pri_width;

double pri_height;

// Конструктор по умолчанию.

public TwoDShape()

{

Width = Height = 0.0;

}

// Конструктор для класса TwoDShape.

public TwoDShape(double w, double h)

{

Width = w;

Height = h;

}

// Сконструировать объект равной ширины и высоты.

public TwoDShape(double x)

{

Width = Height = x;

}

// Сконструировать копию объекта TwoDShape.

public TwoDShape(TwoDShape ob)

{

Width = ob.Width;

Height = ob.Height;

}

// Свойства ширины и высоты объекта.

public double Width

{

get { return pri_width; }

set { pri_width = value < 0? -value: value; }

}

public double Height

{

get { return pri_height; }

set { pri_height = value < 0? -value: value; }

}

public void ShowDim()

{

Console.WriteLine("Ширина и высота равны " + Width + " и " + Height);

}

}

// Класс для треугольников, производный от класса TwoDShape.

class Triangle: TwoDShape

{

string Style;

// Конструктор, используемый по умолчанию.

public Triangle()

{

Style = "null";

}

// Конструктор для класса Triangle.

public Triangle(string s, double w, double h)

: base(w, h)

{

Style = s;

}

// Сконструировать равнобедренный треугольник.

public Triangle(double x)

: base(x)

{

Style = "равнобедренный";

}

// Сконструировать копию объекта типа Triangle.


public Triangle(Triangle ob)

: base(ob)

{

Style = ob.Style;

}

// Возвратить площадь треугольника.

public double Area()

{

return Width * Height / 2;

}

// Показать тип треугольника.

public void ShowStyle()

{

Console.WriteLine("Треугольник " + Style);

}

}

class Shapes7

{

static void Main()

{

Triangle t1 = new Triangle("прямоугольный", 8.0, 12.0);

// Сделать копию объекта t1.

Triangle t2 = new Triangle(t1);

Console.WriteLine("Сведения об объекте t1: ");

t1.ShowStyle();

t1.ShowDim();

Console.WriteLine("Площадь равна " + t1.Area());

Console.WriteLine();

Console.WriteLine("Сведения об объекте t2: ");

t2.ShowStyle();

t2.ShowDim();

Console.WriteLine("Площадь равна " + t2.Area());

}

}

Сведения об объекте t1:

Треугольник прямоугольный

Ширина и высота равны 8 и 12

Площадь равна 48

Сведения об объекте t2:

Треугольник прямоугольный

Ширина и высота равны 8 и 12

Площадь равна 48

Обратите особое внимание на следующий конструктор класса Triangle:

public Triangle(Triangle ob): base(ob)

{

Style = ob.Style;

}

Он принимает объект типа Triangle в качестве своего параметра и передает его(с помощью ключевого слова base) следующему конструктору класса TwoDShape.

public TwoDShape(TwoDShape ob)

{

Width = ob.Width;

Height = ob.Height;

}







Date: 2015-09-02; view: 386; Нарушение авторских прав



mydocx.ru - 2015-2024 year. (0.011 sec.) Все материалы представленные на сайте исключительно с целью ознакомления читателями и не преследуют коммерческих целей или нарушение авторских прав - Пожаловаться на публикацию