C#   Уроки программирования с нуля. Си-шарп для чайников   C#

Здравствуйте, гость!
Вход
Регистрация


Массив указателей на базовый класс в Си-шарп. Операторы is и as
Данный урок является продолжением предыдущего, посвященного наследованию.

В Си-шарп есть возможность создания массива (или списка) указателей на базовый класс в котором в качестве элементов могут быть объекты класса-наследника. Например, мы можем создать массив объектов Животное, и элементами такого массива будут объекты классов Собака, Кошка. Пример:

class Animal
{
   public string Name { get; set; }

   public Animal(string name)
   {
     Name = name;
   }
}
class Dog : Animal
{
   public Dog(string name) : base(name)
   { }

   public void Guard()
   {
     // собака охраняет
   }
}
class Cat : Animal
{
  public Cat(string name) : base(name)
   { }

  public void CatchMouse()
  {
     // кошка ловит мышь
  }
}

class Program
{
   static void Main(string[] args)
   {
     List<Animal> animals = new List<Animal>(); // создаем список указателей на базовый класс
     animals.Add(new Dog("Барбос"));
     animals.Add(new Cat("Барсик"));
     animals.Add(new Dog("Полкан"));

     foreach (Animal animal in animals)
     {
       Console.WriteLine(animal.Name);
     }
     Console.ReadLine();
  }
}


Хотя как элементы в этот список мы добавляли объекты классов-наследников Собака и Кошка, будучи элементами списка указателей на базовый класс, эти объекты преобразовываются к объектам базового класса, и мы имеем доступ только к той части объектов, которая описана в базовом классе – мы не можем здесь вызвать методы Guard() или CatchMouse(), но при этом имеем доступ к имени животного.

Обратное здесь невозможно. Нельзя создать массив объектов класса Собака, и записать в него объекты класса Животное.

Оператор is

Оператор is работает очень просто – он проверяет совместимость объекта с указанным типом (принадлежит ли объект определенному классу). Оператор is возвращает истину (true), если объект принадлежит классу. Истинна будет также при проверке совместимости объекта класса-наследника и базового класса:

static void Main(string[] args)
{
   Dog dog1 = new Dog("Барбос");

   Console.WriteLine(dog1 is Dog); // true
   Console.WriteLine(dog1 is Animal); // true
   Console.WriteLine(dog1 is Cat); // false
   Console.ReadLine();
}


Пользуясь оператором is и явным преобразованием, теперь мы можем полноценно использовать массив указателей на базовый класс:

class Animal
{
   public string Name { get; set; }

   public Animal(string name)
   {
     Name = name;
   }
}
class Dog : Animal
{
   public Dog(string name) : base(name)
   { }

   public void Guard()
  {
     Console.WriteLine(Name + " охраняет");
   }
}
class Cat : Animal
{
  public Cat(string name) : base(name)
   { }

   public void CatchMouse()
   {
     Console.WriteLine(Name + " ловит мышь");
   }
}

class Program
{
   static void Main(string[] args)
  {
     List<Animal> animals = new List<Animal>();
     animals.Add(new Dog("Барбос"));
     animals.Add(new Cat("Барсик"));
     animals.Add(new Dog("Полкан"));

     foreach (Animal animal in animals)
     {
       if (animal is Dog) // проверяем является ли данное животное собакой
         ((Dog)animal).Guard();
       else ((Cat)animal).CatchMouse();
     }
     Console.ReadLine();
   }
}

Здесь, использовав явное преобразование, мы получаем полный доступ к объектам из списка, и можем вызывать методы Guard() и CatchMouse().

Оператор as

В примере выше, вместо явного приведения типов можно было использовать оператор as. (Dog)animal эквивалентно выражению animal as Dog. Разница между оператором as и явным приведением лишь в том, что в случае невозможности преобразования, оператор as возвращает null, тогда как явное приведение выбрасывает исключение. Пример программы выше, только уже с оператором as:

class Program
{
   static void Main(string[] args)
   {
   List<Animal> animals = new List<Animal>();
   animals.Add(new Dog("Барбос"));
   animals.Add(new Cat("Барсик"));
   animals.Add(new Dog("Полкан"));

   foreach (Animal animal in animals)
   {
       if (animal is Dog) // проверяем является ли данное животное собакой
         (animal as Dog).Guard();
       else (animal as Cat).CatchMouse();
   }
   Console.ReadLine();
   }
}

Понравилась статья? Подпишись на рассылку и узнавай первым о новых уроках по почте!


Поделиться с друзьями:
01 авг 2013 16:21
Князь 25 июл 2016 23:58
Написать программу, которая позволяет создавать список заемщиков и лиц, разместивших депозит, банка, с указанием суммы кредита/депозита. Добавить заемщика и депозитора, вывести на экран список заемщиков и депозиторов.



namespace Список_заемщиков
{
class Bank
{
public string Name_debtor;
public string Name_deposit;
public int Sum_Credit;

public Bank (string name)
{
}
}

class Debtor : Bank
{
public Debtor(string name): base(name)
{
Name_debtor = name;
}
}

class Deposit : Bank
{
public Deposit(string name,int sum_credit) : base(name)
{
Name_deposit = name;
Sum_Credit = sum_credit;
}
}

class Program
{
static void Main(string[] args)
{
List<Bank> bank = new List<Bank>();
bank.Add(new Deposit("Барсук И.Ю.", 56000));
bank.Add(new Deposit("Ривс А.Е.", 105000));
List<Bank> bank2 = new List<Bank>();
bank2.Add(new Debtor("Иванов П.С."));
bank2.Add(new Debtor("Мышкин А.А."));
Console.WriteLine("Список депозиторов с указанием суммы:");
foreach (Bank banks in bank)
{

Console.WriteLine(banks.Name_deposit);
Console.WriteLine(banks.Sum_Credit);
}
Console.WriteLine("\n");
Console.WriteLine("Список заемщиков:");
foreach (Bank banks in bank2)
{
Console.WriteLine(banks.Name_debtor);
}

Console.ReadLine();
}
}
}

dmitry_zon 18 фев 2016 14:39
Всем peace!
Написать программу, которая позволяет создавать список заемщиков и лиц, разместивших депозит, банка, с указанием суммы кредита/депозита. Добавить заемщика и депозитора, вывести на экран список заемщиков и депозиторов.


namespace Lesson18
{
class Customer
{
public string CustomerFirstName;
public string CustomerLastName;
public int Amount;
public Customer(string FirstName, string LastName, int amount)
{
CustomerFirstName=FirstName;
CustomerLastName=LastName;
Amount=amount;
}
}
class Loaner:Customer
{
public Loaner(string FirstName, string LastName, int amount):base(FirstName, LastName, amount)
{ }
public void LoanerInfo()
{
Console.WriteLine("Loaner " +CustomerFirstName+" "+CustomerLastName+" has LOAN amount "+Amount);
}
}
class Depositor:Customer
{
public Depositor(string FirstName, string LastName, int amount):base(FirstName, LastName, amount)
{ }
public void DepositorInfo()
{
Console.WriteLine("Depositor " + CustomerFirstName+" "+CustomerLastName+" has a DEPOSIT amount "+Amount);
}
}
class Program
{
static void Main(string[] args)
{
List<Customer> customer = new List<Customer>();
customer.Add(new Depositor("Vladimir", "Petrov", 10000));
customer.Add(new Loaner("Ivan", "Vladimirov", 15000));
foreach (Customer record in customer)
{
if (record is Depositor)
(record as Depositor).DepositorInfo();
else
(record as Loaner).LoanerInfo();
}
Console.ReadKey();
}
}
}


Игорь 28 янв 2016 08:09
class Engineer
{
public string name;
int categori;
public Engineer(string name, int categori)
{
this.name = name;
this.categori = categori;
}

}
class technologi : Engineer
{
public technologi(string name, int categori)
: base(name, categori)
{
}
}
class construktori : Engineer
{
public construktori(string name, int categori)
: base(name, categori)
{
}
}

class Program
{
static void Main(string[] args)
{
List<Engineer> imena = new List<Engineer>();
imena.Add(new Engineer("Попов", 32));
imena.Add(new technologi("Пирогов", 44));
imena.Add(new construktori("Романова", 64));
imena.Add(new technologi("Шандрин", 48));

foreach (Engineer set in imena)
{
try
{
if (set is technologi)
{
Console.WriteLine(set.name);
}
else
{
Console.WriteLine(" ");
}
}
catch (Exception)
{
Console.WriteLine("Ошибочка");

}

vv-ch 07 дек 2015 17:46
Решил запариться и применить то, что умею


using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.IO;

namespace ConsoleApplication1
{
class Figure
{
protected string Name { get; set; }
protected double Center_x { get; set; }
protected double Center_y { get; set; }
public Figure()
{
Name = "Noname";
Center_x = 0;
Center_y = 0;
}
public Figure(double x, double y, string name)
{
Center_x = x;
Center_y = y;
Name = name;
}
}
class Triangle : Figure
{
private double A { get; set; }
private double B { get; set; }
private double C { get; set; }
private double Square { get; set; }
public double GetSquare(double a, double b, double c) {
double p = (a + b + c) / 2.0;
double sq = Math.Sqrt(p*(p-a)*(p-b)*(p-c));
return sq;
}
public Triangle() : base ()
{
A = 0;
B = 0;
C = 0;
Square = 0;
}
public Triangle(double a, double b, double c, double x, double y, string name) : base(x, y, name)
{
A = a;
B = b;
C = c;
Square = GetSquare(A, B, C);
}
public void Output(StreamWriter writer) {
writer.WriteLine("==========================");
writer.WriteLine();
writer.WriteLine();
writer.WriteLine("Данные Треугольника << " + Name + " >>:");
writer.WriteLine("Длины сторон:");
writer.WriteLine("\tA = " + A);
writer.WriteLine("\tB = " + B);
writer.WriteLine("\tC = " + C);
writer.WriteLine("Площадь:");
writer.WriteLine("\tS = " + Square);
writer.WriteLine();
writer.WriteLine();
writer.WriteLine("==========================");
}
}
class Round : Figure
{
private double R { get; set; }
private double Square { get; set; }
private double Circumference { get; set; }
public double GetSquare(double r)
{
return Math.PI * r * r;
}
public double GetCircumference(double r)
{
return Math.PI * r * 2;
}
public Round() : base ()
{
R = 0;
Square = 0;
Circumference = 0;
}
public Round(double r, double x, double y, string name) : base(x, y, name)
{
R = r;
Square = GetSquare(r);
Circumference = GetCircumference(r);
}
public void Output(StreamWriter writer)
{
writer.WriteLine("==========================");
writer.WriteLine();
writer.WriteLine();
writer.WriteLine("Данные круга << " + Name + " >>:");
writer.WriteLine("Радиус:");
writer.WriteLine("\tR = " + R);
writer.WriteLine("Площадь:");
writer.WriteLine("\tS = " + Square);
writer.WriteLine("Длина окружности:");
writer.WriteLine("\tL = " + Circumference);
writer.WriteLine();
writer.WriteLine();
writer.WriteLine("==========================");
}

}
class Input
{
public static void Message(int n)
{
string[] s = {
/*0*/ "",
/*1*/ "\tВы ввели некорректные данные, попробуйте еще раз: ",
/*2*/ "Введите колличество фигур: ",
/*3*/ "\tВведите абциссу центра фигуры: ",
/*4*/ "\tВведите ординату центра фигуры: ",
/*5*/ "\tВведите радиус круга: ",
/*6*/ "\tВведите длину стороны А трегуольника: ",
/*7*/ "\tВведите длину стороны B трегуольника: ",
/*8*/ "\tВведите длину стороны C трегуольника: ",
/*9*/ "",
/*10*/ "\tЭто треугольник или круг? (тр/кр): ",
/*11*/ "\tВведите имя фигуры: "
};
Console.Write(s[n]);
}
public static int Int_(int flag)
{
Message(flag);
try
{
int n = Convert.ToInt32(Console.ReadLine());
Message(9);
return n;
}
catch (Exception)
{
Message(1);
return Int_(0);
}
}
public static double Double_(int flag)
{
Message(flag);
try
{
double n = Convert.ToDouble(Console.ReadLine());
Message(9);
return n;
}
catch (Exception)
{
Message(1);
return Double_(0);
}
}
public static string String_(int flag)
{
Message(flag);
try
{
string n = Console.ReadLine();
Message(9);
return n;
}
catch (Exception)
{
Message(1);
return String_(0);
}
}
public static bool TrKr(int flag)

{
Message(flag);
string s = Console.ReadLine();
switch(s)
{
case "тр":
return false;
case "кр":
return true;
default:
Message(1);
return TrKr(0);
}
}
}
class Program
{
static Triangle Tr_inp()
{
double x = Input.Double_(3);
double y = Input.Double_(4);
string name = Input.String_(11);
double a = Input.Double_(6);
double b = Input.Double_(7);
double c = Math.Min(Input.Double_(8), a+b);
return new Triangle(a, b, c, x, y, name);
}
static Round Rnd_inp()
{
double x = Input.Double_(3);
double y = Input.Double_(4);
string name = Input.String_(11);
double r = Input.Double_(5);
return new Round(r, x, y, name);
}
static void Main(string[] args)
{
int n = Math.Abs(Input.Int_(2));
List < Figure > geom = new List < Figure >();
for (int i = 1; i <= n; i++) {
Console.WriteLine("\n\n" + (new string('-', 50)) + "\n\n");
Console.WriteLine("Введите данные фигуры №" + i + ":");
bool fig = Input.TrKr(10);
if (!fig)
{
Triangle f = Tr_inp();
geom.Add(f);
}
else
{
Round f = Rnd_inp();
geom.Add(f);
}
Console.WriteLine("\n\n" + (new string('-', 50)) + "\n\n");
}
Directory.CreateDirectory("C:\\Users\\SP\\Desktop\\Дирректория про фигуры");
StreamWriter writer = new StreamWriter("C:\\Users\\SP\\Desktop\\Дирректория про фигуры\\нормальный такой файл.txt");
foreach (Figure i in geom)
{
if (i is Triangle) (i as Triangle).Output(writer);
else (i as Round).Output(writer);
}
writer.Close();
}
}
}

Anatoliy 02 ноя 2015 01:29
как удалить обект списка с названием барбосик? через Remove чтото не получается

List<Animal> animals = new List<Animal>(); // создаем список указателей на базовый класс
animals.Add(new Dog("Барбос"));
animals.Add(new Cat("Барсик"));
animals.Add(new Dog("Полкан"));

Максим 13 авг 2015 12:35
Anatoliy
---
Без скобок объект не будет восприниматься компилятором преобразованным, такой синтаксис

Anatoliy 12 авг 2015 22:56
Почему здесь указатели, при преобразировании брались в скобки еще раз?

((Dog)animal).Guard();
else ((Cat)animal).CatchMouse();

Сергей 31 июл 2015 20:00
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace ConsoleApplication5
{
class Animal
{
public string name { get; set; }
private double weight;
public Animal(string name,double weight)
{
this.name=name;
this.weight=weight;
}

public double Weight
{
get
{return weight;}

set
{
if(value<1)
weight=1;
else if (value>20)
weight=20;
else weight=value;
}
}

}
class Dog:Animal
{
public string color { get; set; }
public Dog(string name,double weight,string color):base(name,weight)
{
this.color = color;
}
public void showweight()
{

Console.WriteLine(Weight+" :Weight");
}
}
class Cat:Animal
{
private double lenghtoftail { get; set; }
public Cat(string name,double weight,double lengthoftail):base(name,weight)
{
this.lenghtoftail = lenghtoftail;
}
public void showWeight()
{

Console.WriteLine(Weight+":Weight");

}
}
class Program
{
static void Main(string[] args)
{
List<Animal> animals = new List<Animal>();
animals.Add(new Dog("Barbos", 25, "red"));
animals.Add(new Cat("Barsik", 8, 5));

foreach (Animal animal in animals)
{
if (animal is Dog)
((Dog)animal).showweight();
else (animal as Cat).showWeight();
}
Console.ReadLine();
}
}
}
Как-то так

Maro 14 июл 2015 19:42
очень нравятся уроки! СПАСИБО Автору!

Maro 14 июл 2015 19:41
мне кажется стоило бы указать, что для работы с List нужно подключить System.Collections.Generic?..

sergey 06 июл 2015 11:16
В данном уроке было бы актуально сказать что фишка с масивом работает только если в конструкторах один аргумент как в примере ((name)) если несколько то не работает. Если у кого работает то пример в студию.

Максим 02 июл 2015 20:42
Лия
---
Нету пока

Лия 02 июл 2015 11:58
А домашнее ???

Flamingo 07 июн 2015 20:28
Ребята, старайтесь помимо заданий на сайте придумывать себе свои.
Благодаря этому лучше материал запомнится, и даже если Д/З отсутствует
Будет возможность освоить какую-либо статью.

Максим 10 мар 2015 11:55
AlPer
---
Возможность есть, но пока на очереди урок про http

AlPer 10 мар 2015 11:17
Класс List C#, List<> C#

может быть сделать отдельно урок на тему данного класса? есть такая возможность?

AlPer 26 фев 2015 21:11
Домашнее задание хочу. Уж больно сложный урок. Надо бы закрепить...=)))

Lucifer 25 сен 2013 15:25
Admin
_______

Уже знаю и на мой взгляд он не актуален.

Максим 20 сен 2013 16:36
Lucifer
---
Почему вы так говорите о windows forms? Уже знаете как с этим работать, или не видите смысла это изучать? Web штука непростая и переход сразу будет сложен

Lucifer 19 сен 2013 12:26
а может ну его этот windows forms ? Не будет ли лучше перейти сразу к web или WPF ?

Максим 23 авг 2013 23:14
John
---
на днях будут

John 23 авг 2013 08:41
Не хочу показаться грубым, но когда, блин, будут новые уроки?

Максим 15 авг 2013 15:59
Сергей
---
По консоли есть еще что учить. Дальше, думаю, будет Windows Forms. До Web еще далековато

Сергей 15 авг 2013 13:30
Будет ли продолжение и переход от консоли к web ? =)
Меня лично интересует соединение с БД.


Добавить комментарий:

Имя (обязат.)
E-mail (обязат., не публикуется)


Для вставки ваших программ пользуйтесь кнопкой "исходный код"
Вёрстка сайта с нуля

Уникальный Видеокурс!

"Научись верстать сайты и заработай на этом!"

Получить видеокурс

Подпишись на курс по программированию, и узнавай первым о новых уроках!

RSS подписка Страничка Вконтакте Мы в Twitter
Бесплатный курс по основам PHP
Ошибка в тексте? Выделите ее мышкой и нажмите Ctrl+Enter
Поблагодарить автора: Номер карты (ПриватБанк)
5168 7572 4170 8660
WebMoney
R372544961915 U685637142028 Z999792764387
Наверх
Система Orphus