Чем отличается виртуальный вызов от виртуальной цепи
Перейти к содержимому

Чем отличается виртуальный вызов от виртуальной цепи

  • автор:

Для чего нужно virtual/override?

Недавно ходил на собеседование на позицию .Net разработчика, на собеседовании у меня спросили «Для чего нужен virtual/override?». Я рассказал о том, что помечая метод виртуальным, мы можем в классе наследнике его переопределить и либо добавить свою реализацию к базовой, либо оставить только свою. Далее меня спросили «только для того, чтоб можно было переопределить метод?», я сказал, что в EF для ленивой загрузки данных, в итоге мои ответы не являлись исчерпывающим ответом на вопрос.
Какие еще могут быть ответы?

P.S. я не стал спрашивать у интервьюера правильный ответ, так как были сомнения в его профессионализме

  • Вопрос задан более трёх лет назад
  • 936 просмотров

1 комментарий

Оценить 1 комментарий

e70af6331a684879a82e8cbf3a14a073.jpg

Решения вопроса 0
Ответы на вопрос 3
Deerenaros @Deerenaros
Программист, математик, задрот и даже чуть инженер

Ахтунг, товарищ. Перед тем как сомневаться в профессионализме своих коллег очень советую хотя бы немного сомневаться в собственном. Это как минимум изредка полезно. А теперь ноги в руки и вперёд читать про таблицы, виртуальность и методы. Это не просто полезно, но архиважно. Учитывая, собственно, вопрос.

А вопрос состоял в следующем. Вот у нас есть объекты, друг от друга наследуются, имплементируются и всё круто-прекрасно, но блджад. Зачем они нужны-то? Нет, не агрегация данных, хотя и она тоже. Нет, не агрегация реализации, хотя и она тоже. И нет, нет, не просто потому что. Хотя и это тоже. А вот подумай о такой ситуации. Есть библиотека. Да не важно какая, ну пусть это будет UI/UX. Вот есть абстрактный (!) класс кнопка. Почему абстрактный? Да потому что любая кнопка — это кнопка. Это как бы класс над классом. Кнопка может быть красной, может быть кликабельной, может становится не кликабельной после нажатия, может открывать диалог выбора файлов, а может закрывать приложение к чертям. В общем, много чего может уметь делать кнопка. И вот эту кнопку хочется поставить на формочку. И сделал создатель библиотеки такой прекрасный метод у формы PutAnyButtonHere(Button btn, Point xy). Но. Чёрт, чувак, мы должны передать объект класса Button, а у нас какой-нибудь наследник MyBestButton : BestAbstractLibraryButton, который наследник той самой Button. И у Button декларирован такой прекрасный метод TimeWhenUserClickOnMe(Point xy, AnotherInfo somethinElse), собственно. Получается, что где-то в недрах той самой библиотеки, когда автор прекрасной UI/UX библиотеки вызывает этот самый метод он должен вызвать НАШУ реализацию, а не реализацию BestAbstractLibraryButton. И уж точно не несуществующую реализацию Button (ибо метод там чисто-виртуальный). Идея виртуальных методов изначально именно в том, что есть особая таблица, которая хранит реализации отдельно, объекты отдельно, но когда мы пытаемся вызывать у объекта виртуальный метод происходит такая магия, которую принято называть поздним связыванием.

А ключевые слова это просто для того, чтобы программист читая чужие полотна кода хоть ну немного имел возможность хоть как-то их понять. Что конкретно хотел программист в конкретной ситуации. И, если в Java все методы по дефолту виртуальные и ничерта не понятно из чужих полотен, хотел здесь программист позднее связывание, или это просто агрегация функционала, то в шарпе данной проблемы «как бы нет», язык порой чрезвычайно многословен на, казалось, такие банальности. Что в итоге изредка, но экономит чёртову тучу времени.

Сухой остаток. Если мы вызываем виртуальный метод у объекта класса наследника некоторого супер-класса имея ссылку типа супер-класса, то вызывается реализация метода наследника. Если мы вызываем не виртуальный метод у объекта класса наследника некоторого супер-класса имея ссылку типа супер-класса, то вызывается реализация метода супер-класса. В остальном поведение тривиальное.

Отсебятина. Не понимая данных вещей невозможно говорить, что принципы объектно-ориентированного программирования были усвоены. Советую прочитать «Философия Java» (вообще там Java скорее как язык для примеров, в общем-то ООП оно и в Африке ООП). Ну и пытаться разобраться в точке зрения любого человека, особенно если его компетенция хоть чем-то подтверждена (например, успешным трудоустройством).

Чем отличается виртуальный вызов от виртуальной цепи

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

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

А чтобы переопределить метод в классе-наследнике, этот метод определяется с модификатором override . Переопределенный метод в классе-наследнике должен иметь тот же набор параметров, что и виртуальный метод в базовом классе.

Например, рассмотрим следующие классы:

class Person < public string Name < get; set; >public Person(string name) < Name = name; >public virtual void Print() < Console.WriteLine(Name); >> class Employee : Person < public string Company < get; set; >public Employee(string name, string company) : base(name) < Company = company; >>

Здесь класс Person представляет человека. Класс Employee наследуется от Person и представляет сотруднника предприятия. Этот класс кроме унаследованного свойства Name имеет еще одно свойство — Company.

Чтобы сделать метод Print доступным для переопределения, этот метод определен с модификатором virtual . Поэтому мы можем переопределить этот метод, но можем и не переопределять. Допустим, нас устраивает реализация метода из базового класса. В этом случае объекты Employee будут использовать реализацию метода Print из класса Person:

Person bob = new Person("Bob"); bob.Print(); // вызов метода Print из класса Person Employee tom = new Employee("Tom", "Microsoft"); tom.Print(); // вызов метода Print из класса Person
Bob Tom

Но также можем переопределить виртуальный метод. Для этого в классе-наследнике определяется метод с модификатором override , который имеет то же самое имя и набор параметров:

class Employee : Person < public string Company < get; set; >public Employee(string name, string company) : base(name) < Company = company; >public override void Print() < Console.WriteLine($"работает в "); > >

Возьмем те же самые объекты:

Person bob = new Person("Bob"); bob.Print(); // вызов метода Print из класса Person Employee tom = new Employee("Tom", "Microsoft"); tom.Print(); // вызов метода Print из класса Employee
Bob Tom работает в Microsoft

Виртуальные методы базового класса определяют интерфейс всей иерархии, то есть в любом производном классе, который не является прямым наследником от базового класса, можно переопределить виртуальные методы. Например, мы можем определить класс Manager, который будет производным от Employee, и в нем также переопределить метод Print.

При переопределении виртуальных методов следует учитывать ряд ограничений:

  • Виртуальный и переопределенный методы должны иметь один и тот же модификатор доступа. То есть если виртуальный метод определен с помощью модификатора public, то и переопредленный метод также должен иметь модификатор public.
  • Нельзя переопределить или объявить виртуальным статический метод.

Ключевое слово base

Кроме конструкторов, мы можем обратиться с помощью ключевого слова base к другим членам базового класса. В нашем случае вызов base.Print(); будет обращением к методу Print() в классе Person:

class Employee : Person < public string Company < get; set; >public Employee(string name, string company) :base(name) < Company = company; >public override void Print() < base.Print(); Console.WriteLine($"работает в "); > >

Переопределение свойств

Также как и методы, можно переопределять свойства:

class Person < int age = 1; public virtual int Age < get =>age; set < if(value >0 && value < 110) age = value; >> public string Name < get; set; >public Person(string name) < Name = name; >public virtual void Print() => Console.WriteLine(Name); > class Employee : Person < public override int Age < get =>base.Age; set < if (value >17 && value < 110) base.Age = value; >> public string Company < get; set; >public Employee(string name, string company) : base(name) < Company = company; base.Age = 18; // возраст для работников по умолчанию >>

В данном случае в классе Person определено виртуальное свойство Age, которое устанавливает значение, если оно больше 0 и меньше 110. В классе Employee это свойство переопределено — возраст работника должен быть не меньше 18.

Person bob = new Person("Bob"); Console.WriteLine(bob.Age); // 1 Employee tom = new Employee("Tom", "Microsoft"); Console.WriteLine(tom.Age); // 18 tom.Age = 22; Console.WriteLine(tom.Age); // 22 tom.Age = 12; Console.WriteLine(tom.Age); // 22

Запрет переопределения методов

Также можно запретить переопределение методов и свойств. В этом случае их надо объявлять с модификатором sealed :

class Employee : Person < public string Company < get; set; >public Employee(string name, string company) : base(name) < Company = company; >public override sealed void Print() < Console.WriteLine($"работает в "); > >

При создании методов с модификатором sealed надо учитывать, что sealed применяется в паре с override, то есть только в переопределяемых методах.

И в этом случае мы не сможем переопределить метод Print в классе, унаследованном от Employee.

Чем отличается виртуальный вызов от виртуальной цепи

При вызове функции программа должна определять, с какой именно реализацией функции соотносить этот вызов, то есть связать вызов функции с самой функцией. В С++ есть два типа связывания — статическое и динамическое.

Когда вызовы функций фиксируются до выполнения программы на этапе компиляции, это называется статическим связыванием (static binding), либо ранним связыванием (early binding). При этом вызов функции через указатель определяется исключительно типом указателя, а не объектом, на который он указывает. Например:

#include class Person < public: Person(std::string name): name < >void print() const < std::cout private: std::string name; // имя >; class Employee: public Person < public: Employee(std::string name, std::string company): Person, company  < >void print() const < Person::print(); std::cout private: std::string company; // компания >; int main() < Person tom ; Person* person ; person->print(); // Name: Tom Employee bob ; person = &bob; person->print(); // Name: Bob >

В данном случае класс Employee наследуется от класса Person, но оба этих класса определяют функцию print() , которая выводит данные об объекте. В функции main создаем два объекта и поочередно присваиваем их указателю на тип Person и вызываем через этот указатель функцию print. Однако даже если этому указателю присваивается адрес объекта Employee, то все равно вызывает реализация функции из класса Person:

Employee bob ; person = &bob; person->print(); // Name: Bob

То есть выбор реализации функции определяется не типом объекта, а типом указателя. Консольный вывод программы:

Name: Tom Name: Bob

Динамическое связывание и виртуальные функции

Другой тип связывания представляет динамическое связывание (dynamic binding), еще называют поздним связыванием (late binding), которое позволяет на этапе выполнения решать, функцию какого типа вызвать. Для этого в языке С++ применяют виртуальные функции . Для определения виртуальной функции в базовом классе функция определяется с ключевым словом virtual . Причем данное ключевое слово можно применить к функции, если она определена внутри класса. А производный класс может переопределить ее поведение.

Итак, сделаем функцию print в базовом классе Person виртуальной:

#include class Person < public: Person(std::string name): name < >virtual void print() const // виртуальная функция < std::cout private: std::string name; >; class Employee: public Person < public: Employee(std::string name, std::string company): Person, company  < >void print() const < Person::print(); std::cout private: std::string company; >; int main() < Person tom ; Person* person ; person->print(); // Name: Tom Employee bob ; person = &bob; person->print(); // Name: Bob // Works in Microsoft >

Таким образом, базовый класс Person определяет виртуальную функцию print, а производный класс Employee переопределяет ее. В первом же примере, где функция print не была виртуальной, класс Employee не переопределял, а скрывал ее. Теперь при вызове функции print для объекта Employee через указатель Person* будет вызываться реализация функции именно класса Employee. Соответственно тепепрь мы получим другой консольный вывод:

Name: Tom Name: Bob Works in Microsoft

В этом и состоит отличие переопределения виртуальных функций от скрытия.

Класс, который определяет или наследует виртуальную функцию, еще назвается полиморфным (polymorphic class). То есть в данном случае Person и Employee являются полиморфными классами.

Стоит отметить, что вызов виртуальной функции через имя объекта всегда разрешается статически.

Employee bob ; Person p = bob; p.print(); // Name: Bob - статическое связывание

Динамическое связывание возможно только через указатель или ссылку.

Employee bob ; Person &p ; // присвоение ссылке p.print(); // динамическое связывание Person *ptr ; // присвоение адреса указателю ptr->print(); // динамическое связывание

При определении вирутальных функций есть ряд ограничений. Чтобы функция попадала под динамическое связывание, в производном классе она должна иметь тот же самый набор параметров и возвращаемый тип, что и в базовом классе. Например, если в базовом классе виртуальная функция определена как константная, то в производном классе она тоже должна быть константной. Если же функция имеет разный набор параметров или несоответствие по константности, то мы будем иметь дело со скрытием функций, а не переопределением. И тогда будет применяться статическое связывание.

Также статические функции не могут быть виртуальными.

Ключевое слово override

Чтобы явным образом указать, что мы хотим переопредлить функцию, а не скрыть ее, в производном классе после списка параметров функции указывается слово override

#include class Person < public: Person(std::string name): name < >virtual void print() const // виртуальная функция < std::cout private: std::string name; >; class Employee: public Person < public: Employee(std::string name, std::string company): Person, company  < >void print() const override // явным образом указываем, что функция переопределена < Person::print(); std::cout private: std::string company; >; int main() < Person tom ; Person* person ; person->print(); // Name: Tom Employee bob ; person = &bob; person->print(); // Name: Bob // Works in Microsoft >

То есть здесь выражение

void print() const override

указывает, что мы явным образом хотим переопределить функцию print. Однако может возникнуть вопрос: в предыдущем примере мы не указывали override для вирутальной функции, но переопределение все равно работало, зачем же тогда нужен override ? Дело в том, что override явным образом указывает компилятору, что это переопределяемая функция. И если она не соответствует виртуальной функции в базовом классе по списку параметров, возвращаемому типу, константности, или в базовом классе вообще нет функции с таким именем, то компилятор при компиляции сгенерирует ошибку. И по ошибке мы увидим, что с нашей переопределенной функцией что-то не так. Если же override не указать, то компилятор будет считать, что речь идет о скрытии функции, и никаких ошибок не будет генерировать, компиляция пройдет успешно. Поэтмоу при переопределении виртуальной функции в производном классе лучше указывать слово override

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

Принцип выполнения виртуальных функций

Стоит отметить, что виртальные функции имеют свою цены — объекты классов с виртуальными функциями требуют немного больше памяти и немного больше времени для выполнения. Поскольку при создании объекта полиморфного класса (который имеет виртуальные функции) в объекте создается специальный указатель. Этот указатель используется для вызова любой виртуальной функции в объекте. Специальный указатель указывает на таблицу указателей функций, которая создается для класса. Эта таблица, называемая виртуальной таблицей или vtable, содержит по одной записи для каждой виртуальной функции в классе.

Когда функция вызывается через указатель на объект базового класса, происходит следующая последовательность событий

vtable, полиформизм и виртуальные функции в C++

  1. Указатель на vtable в объекте используется для поиска адреса vtable для класса.
  2. Затем в таблице идет поиск указателя на вызываемую виртуальную функцию.
  3. Через найденный указатель функции в vtable вызывается сама функция. В итоге вызов виртуальной функции происходит немного медленнее, чем прямой вызов невиртуальной функции, поэтому каждое объявление и вызов виртуальной функции несет некоторые накладные расходы.

Запрет переопределения

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

class Person < public: virtual void print() const final < >>; class Employee : public Person < public: void print() const override // Ошибка. < >>;

Также можно переопределить функцию базового класса, но запретить ее переопределение в дальнейших производных классах:

class Person < public: virtual void print() const // переопределение разрешено < >>; class Employee : public Person < public: void print() const override final // в классах, производных от Employee переопределение запрещено < >>;

Входящая связь через мини АТС

Схема поджлючения каналов внешней связи к АТС МАКСИКОМ MXM500P

В зависимости от модели мини АТС возможны разные комбинации. Например, к цифровой АТС МАКСИКОМ MXM500P можно подключить и аналоговые линии, и IP каналы. Или, скажем, цифровой поток, аналоговые СЛ и GSM -каналы (ы) через шлюз.

Как входящая связь через мини АТС обеспечивается технически

При любом способе соединения мини АТС организации с внешним миром нужно решить следующие задачи.

  • Принять вызов “на стороне мини АТС”.
  • Обеспечить поступление вызова на конкретные внутренние линии.
  • Настроить для каждой абонентской линии режимы приема и дальнейшей обработки входящего вызова.

Входящая связь через мини АТС -структурная схема

В зависимости от типа внешней линии используют разные способы решения.

Входящая связь через мини АТС по аналоговым линиям.

Вызов поступает на порт СЛ. Порты соединительных линий находятся на платах, а платы устанавливают в платоместа базового блока мини АТС.

Публичный номер (тот, который организация показывает в справочниках, на сайте и т.п.) можно подать по одной или нескольким линиям. Например, публичный номер Мультикома — +78123251540. Звонки на этот номер поступают на мини АТС офиса (кстати, это МАКСИКОМ MXM500P) по нескольким СЛ.

При этом каждая соединительная линия входит в станцию через свой, отдельный порт СЛ.

Далее, при участии процессора вызов наводится на конкретную абонентскую линию или на группу АЛ. Для этого используют таблицы наведения.

О таблицах наведения и программировании АТС рассказывается в этом материале.

Кроме того, краткое изложение идеи появится ниже по тексту.

Входящая связь по цифровым линиям.

Если АТС подключена к ТФОП по цифровому потоку, вызов принимает плата Е1-500P. Плата имеет связь с остальной аппаратурой станции через специальные “внутренние” соединительные линии. Входящий вызов направляется через внутренние СЛ на нужные порты АЛ — опять же, в соответствии с программным наведением.

Входящая связь по IP.

Вызовы, приходящие через SIP-транк, поступают на IP плату. На сервере платы зарегистрированы как IP- клиенты, так и MXM — клиенты (аналоговые телефоны и системные аппараты).

За счет программного наведения сигнал поступает на

  • аналоговые порты мини АТС
  • порты системных ТА (цифровых или четырехпроводных).

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

Входящая связь через GSM-шлюзы.

Вызовы с мобильных телефонов поступают через GSM-шлюз на порт СЛ. Оттуда, как говорилось выше, за счет программного наведения — на порты абонентских линий.

А теперь — некоторые подробности и комментарии

ВХОДЯЩАЯ СВЯЗЬ ЧЕРЕЗ МИНИ АТС И МАРШРУТЫ ВХОДЯЩИХ ЗВОНКОВ.

Входящая связь через мини АТС - схема с тональным донабором и наведением.

Независимо от канала. по которому поступает внешний вызов, мини АТС должна его обработать. Чем-то это похоже на игру. Сначала принять мяч, который прилетел откуда-то извне. Потом сделать правильный пас -отправить мяч тому, кто должен его в конечном счете поймать. А если этот “кто-то” занят или отошел в сторону, оперативно передать мяч другому игроку. Главное. чтобы этот мяч не упал на землю.

Эту сложную игру ведет процессор мини АТС, который делает то. что ему предписано программой.

Есть два способа организовать маршрут звонка на этапе “поступление входящего вызова — прием входящего вызова”

  • Навести вызов на нужные абонентские линии.
  • Дать возможность внешнему абоненту самому набрать известный внутренний номер.

Рассмотрим эти варианты чуть подробнее.

Наведение входящих вызовов.
Наведение входящих вызовов, которые поступают по аналоговым СЛ.

Это абсолютно необходимый этап, без которого работа мини АТС вообще не имеет смысла. В качестве примера возьмем аналоговый порт СЛ. Этот порт имитирует работу телефонного аппарата, который принимает внешний вызов. Но ответить-то на этот вызов порт не может. Значит, телефон“ должен позвонить на какой-то внутренний номер, и там ответят. А на какой?

Суть наведения — программная подсказка станции, какой внутренний абонент (или абоненты) должны принять поступивший вызов. Более того, станции часто подсказывают, что делать, если нужный абонент (абоненты) заняты или не отвечают. Можно оставить все как есть, и тогда внешний абонент получит уведомление о том, что соединение в данный момент невозможно. Но есть и другой способ: дозвониться до других внутренних абонентов — вдруг они ответят.

Так или иначе, мини АТС предлагается программная “дорожная карта” — таблица наведения. Количество строк таблицы = количеству вариантов передать входящий звонок. Иначе говоря, количество последовательных попыток установить соединение хоть с кем-то из тех внутренних абонентов, которые имеют возможность или право отвечать на звонки..

В каждой такой строке можно указать
Один конкретный внутренний номер.
Номер группы (трехзначный). В этом случае звонок поступает сразу на все телефонные аппараты, входящие в группу.
Список внутренних номеров. Они могут относиться к разным группам. В этом случае вызов также одновременно поступит на все АЛ, указанные в списке.

Варианты наведения внешних вызовов через мини АТС - поясняющая схема

Таблица наведения может содержать много строк. На картинке показаны двухстрочные таблицы. Это означает, что вначале мини АТС подаст звонок на все АЛ, указанные в первой строке (на самом деле, в строке указывают аппаратные или программные номера АЛ). Затем. если ни одна АЛ не примет входящий вызов, мини АТС перейдет ко второй строке. Кстати. в строке можно указать всего один номер. Например, первая строка таблицы наведения для звонков, предназначенных руководству, содержит только номер АЛ секретаря.

К каждой СЛ можно прикрепить свою таблицу наведения. Более того, в зависимости от времени суток могут действовать разные таблицы.

То, что касается одной СЛ, относится и к группе соединительных линий. Если прикрепить к нескольким СЛ одну и ту же таблицу наведения, внешний звонок. который поступает на любую СЛ из группы. отправится по одному и тому же маршруту.

Ненаведенный вызов и прямое наведение с СЛ.

Мини АТС “не имеет права” терять входящие вызовы. Даже если для конкретной СЛ не сделали таблицу наведения. В этом случае вызов автоматически поступит на конкретную АЛ., которая жестко закреплена за данной СЛ, Таблицы закрепления можно увидеть в руководствах по эксплуатации конкретных моделей АТС МАКСИКОМ.

Таким образом, ненаведенный вызов — вызов, поступающий на конкретную АЛ по прямому наведению. .

В каких случаях срабатывает прямое наведение.

  • Другие варианты не запрограммированы. В принципе, для небольшой организации возможен и такой вариант.
  • УАТС выключена. Увы. такое тоже случается — при длительной аварии на электросети. Первое время питание АТС поддерживает ИБП (источник бесперебойного питания). Но его ресурс не бесконечен. Если сеть к этому моменту не починят, УАТС просто выключится. Но при этом реле на платах автоматически переведет СЛ в режим прямого наведения. То есть, УАТС не работает, а связь с внешним миром все равно есть. После возвращения электропитания все исходные установки станции снова заработают
Наведение входящих вызовов, поступающих по цифровому потоку.

Если станция подключена к оператору ТФОП по цифровому потоку, появляются гораздо более разнообразные возможности.

В самом грубом приближении, эта плата представляет собой 30 виртуальных СЛ со своими внутренними аппаратными номерами. Почему 30? Дело в том, что в структуре цифрового потока — 32 канала, из которых 30 используются для передачи голосовых сообщений. Следовательно, по цифровому потоку можно установить до 30 одновременных соединений.

Входящая связь по цифровому потоку - упрощенная схема.

Но это не означает, что и номеров, по которым могут звонить внешние абоненты, должно быть не больше 30. На самом деле, плата Е1-500Р поддерживает входящую номерную емкость в 200 городских номеров.

Эти номера выдает оператор ТФОП. По сути. это т.н. виртуальные номера входящей связи. Кстати, в отличие от аналогового подключения, организация платит не за количество номеров, а за использование цифрового потока.

Таким образом, до 200 внутренних абонентов мини АТС могут иметь прямо адресуемые городские номера.

Некоторую часть этих номеров размещают в публичном доступе. То есть. эти номера известны всем. Другие номера можно сообщать только определенным группам внешних абонентов.

Для каждого номера можно выбрать один из трех вариантов входящей связи
  • Таблица наведения. В данном случае, суть ровно такая же, как и при аналоговом подключении.
  • “Команда” — групповой номер. В МАКСИКОМ MXM500P можно создать до 40 групп абонентов. Если входящий городской номер привязан к группе абонентов, то при поступлении входящего вызова зазвонят все телефоны группы.
  • Виртуальные СЛ. Виртуальный номер входящей связи привязан к одной из виртуальных СЛ. А к ней, в свою очередь, прикрепляют таблицу наведения (в данному случае можно привязать к одной виртуальной СЛ разные таблицы для разных временных зон). Кроме того, можно направить входящие звонки по виртуальной СЛ на механизм тонального донабора DISA. Наконец, есть возможность организовать равномерную загрузку входящих вызовов по виртуальным СЛ.

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

Наведение входящих вызовов, поступающих по каналам IP телефонии.
Входящая IP связь через шлюз.

К порту СЛ мини АТС можно подключить VOIP — шлюз FXS. Это устройство выполняет преобразование цифровых пакетов в аналоговый сигнал и в таком виде передает сигнал на соединенный с ним порт СЛ. Далее наведение с этого порта организуют так же, как и описано выше — прикрепляют нужные таблицы наведения.

Входящая IP связь через IP плату.

В самом общем виде, IP-плата представляет собой 20 виртуальных СЛ со своими внутренними аппаратными номерами. Эти виртуальные СЛ также называют MXM-транками.

На плате имеется модуль MXM, который как раз и занимается распределением нагрузки на виртуальные СЛ.

Также плата содержит VOIP сервер.

Входящую связь для MXM-абонентов также организуют с помощью таблиц наведения. Эти таблицы прикрепляют к виртуальным СЛ (MXM-транкам).

IP плата - логическая схема организации связи с MXM500P

Входящая связь через мини АТС посредством GSM-шлюза.

Для приема входящих звонков по каналам сотовой связи к порту (портам) СЛ подключают GSM-шлюзы FXS. Шлюх выполняет нужное преобразование и направляет аналоговый сигнал на порт СЛ.

Наведение вызовов с этого порта организуют так же, как это было описано для аналоговых портов СЛ.

Режим DISA на соединительных линиях.

Это способ сразу дать возможность звонящему внешнему абоненту донабрать внутренний номер, если он ему известен.

Режим можно установить как на отдельной СЛ, так и для группы — да хоть для всех соединительных линий.

По сути дела, внешний абонент получает возможность ограниченного управления станцией. То есть, он указывает ”ей, на какую абонентскую линию нужно направить вызов. А ему, в свою очередь, подсказывает голосовой автоинформатор (В MXM500P)/ В других моделях мини АТС Максиком для этой же цели подключают автосекретарь.

ПРОМЕЖУТОЧНЫЕ УЗЛЫ В СИСТЕМЕ ВХОДЯЩЕЙ СВЯЗИ.

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

Предприятие нанимает на работу не внутренних абонентов, а сотрудников. И наделяет некоторых из них правом (и обязанностью) решать, что делать с поступившим вызовом. То есть, ответить самому или передать соединение кому-то еще.

Каждый такой сотрудник — промежуточное звено в цепочке приемы входящих звонков. Пожалуй. самый яркий пример — секретарь. Во многих офисах все или практически все внешние вызовы наводят на АЛ секретаря. Часто на этом “пункте” цепочка и заканчивается. Но бывает и так, что секретарь переводит звонок кому-то еще: начальнику или, скажем. сотруднику нужного отдела.

В некоторых ведомственных сетях связи звонки между станциями обрабатываются ТОЛЬКО так. Никаких обходных путей — только через конкретного сотрудника.

Пример такой организации связи — в этой статье.
А вот еще примерорганизация связи кабинетов и цехов. Здесь тоже имеются промежуточные узлы передачи информации по телефону.

Идеальный телефонный аппарат для секретаря или другого сотрудника. который и сам отвечает на звонки. и переводит их на другие абонентские линии — системный аппарат АТС.

Системный телефон АТС - схема использования СТА в составе мини АТС.

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

А дальше сотрудник использует те или иные сервисные функции мини АТС и распоряжается соединением в соответствии со своими полномочиями и обязанностями.

КОНЕЧНАЯ ТОЧКА МАРШРУТА КАК НАЧАЛО НОВОГО ПУТИ.

Или о том, как можно обработать входящий звонок.

ПРИНЯТЬ.

Даже еще не подняв трубку, внутренний абонент уже знает, какого типа вызов “прилетел” на его абонентскую линию.

Мини АТС подсказывает тип входящего вызова соответствующий звонковым сигналом.

Например, МАКСИКОМ MXM500P “заставляет” телефон внутреннего абонента звонить по-разному в следующих случаях:
  • Входящий внешний вызов ( пришел с соединительной линии)
  • Входящий внутренний вызов (пришел с другой АЛ)
  • Вызов пришел с домофона. (зависит от модели домофона. Например, звонки с универсального домофона DMFu такие же, как с абонентской линии).
  • Вызов группы. В этом случае имеется в виду, что один и тот же вызов поступил на несколько АЛ. Отвечает тот, кто первым поднял трубку.

В каждом случае звонок имеет свой собственный звуковой рисунок — сочетание сигнала и пауз определенной продолжительности. Например, вызов с СЛ — длинные звонки, как бы копирующие внешний вызов. Групповой вызов — двойной длинный и короткий звонок с периодом 4 сек.

Хотим ответить — просто поднимаем трубку.

ПРИНЯТЬ ВО ВРЕМЯ СОЕДИНЕНИЯ

Помимо звонков, мини АТС сообщает о поступивших вызовах даже в тот момент, когда абонент уже разговаривает с кем-то. Для этого она подает в линию специальные сигналы. Например, та же МАКСИКОМ MXM500P подает в линию следующие звуковые подсказки:

  • Поступил внешний вызов.
  • Внутренний абонент требует срочного соединения. Такой же сигнал подается при сборе селекторного совещания.
  • Звонит домофон

В любом случае, абонент принимает решение:

  • Игнорировать этот вызов и спокойно продолжать разговор
  • Принять вызов с прекращением текущего соединения. Для этого нужно положить и снова снять трубку. Предыдущее соединение теряется.
  • Принять новый звонок с сохранением предыдущего соединения. Чтобы и на елку влезть, и ничего не ободрать, набираем на телефоне F 6. “F” — либо кнопка “Флэш”, либо другая кнопка, которая на данном ТА выполняет функцию предварительного уведомления мини АТС. Набрав F 5, абонент сохраняет и предыдущее соединение, и может принять новый звонок. Между соединениями можно переключаться. Каждому переключению предшествует набор F 6.
ПЕРЕХВАТИТЬ

Перехватить вызов — значит дать мини АТС команду перевести на свою абонентскую линию вызов. который поступает на другую АЛ.

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

Перехватить чужой внешний вызов.
  • Абонент, готовый перехватить вызов, в данный момент не разговаривает по своему телефону. В этом случае нужно снять трубку, дождаться сигнала “Готовность” и набрать 8.
  • Абонент в данный момент разговаривает. Нужно набрать F 8. Мини АТС временно отсоединит АЛ от текущего соединения, но не оборвет его. Переключаться между предыдущим и новым “перехваченным” соединением можно с помощью набора F 6.
Перехватить любой чужой вызов.

Все то же самое, но теперь можно перехватить и внешние, и внутренние входящие вызовы.

Нужно снять трубку своего телефона, дождаться сигнала “Готовность”, затем набрать внутренний номер звонящего телефона и, услышав сигнал “Занято, набрать 8.

Кстати. перехватывать чужие вызовы можно только в том случае. если данной АЛ такая функция разрешена. Запреты и разрешения настраивают для отдельных АЛ и их групп на этапе программирования АТС. Впрочем, любые настройки можно оперативно изменить.

Если функция запрещена, любая попытка перехватить чужой вызов закончится тем. что АТС подаст сигнал “Ошибка”.

ПЕРЕДАТЬ

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

Для перенаправления вызова есть два способа.

  • Передача соединения. В этом случае мини АТС посылает другому абоненту уведомление.
  • Посылка соединения. В этом случае предварительного уведомления не будет.
Как это делается (на примере МАКСИКОМ MXM500P).
Передача внешнего соединения.

Чтобы передать внешнее соединение, нужно набрать F и нужный внутренний номер. В этот момент мини АТС переведет СЛ в режим музыкального “ожидания”. Затем нужно дождаться ответа абонента и сообщить ему приятную новость. Например. сказать: “Вася, тут звонят насчет срыва сроков по контракту. Я вот подумал, что лучше ты им все объяснишь”. И положить трубку. Мини АТС выведет СЛ из режима музыкального ожидания. и разъяренный внешний абонент услышит в трубке растерянный голос Васи.

А что если линия нужного абонента занята? Не будем отчаиваться. есть варианты. Можно набрать:

  • 1 для выхода из состояния “Занято” и восстановления прежнего соединения.
  • 6 для посылки срочного вызова занятому внутреннему абоненту. В этом случае станция подаст в соответствующую АЛ сигнал о требовании срочного соединения.
  • 7 для подключения к соединению. То есть. просто включиться в разговор другого абонента с кем-то еще и попросить принять внешний вызов.

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

Передача внешнего вызова по ГГС.

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

Для таких ситуаций потребуется ГГС. Конечно, только если канал громкоговорящей связи подключен к мини АТС.

Итак, набираем F, номер ГГС и прямо со своего телефона делаем оповещение по громкой связи. Искомый сотрудник подходит к ближайшему телефонному аппарату, набирает на нем номер соответствующего канала ГГС и 7.

После этого можно положить трубку. Мини АТС передаст соединение на АЛ того телефонного аппарата, к которому подошел сотрудник.

Посылка внешнего соединения.

Как говорилось выше, абонент. которому посылают внешнее соединение, никакого уведомления от “посылающего” не получит. Для него ситуация будет выглядеть так же, как если бы звонок исходно поступал на его телефон.

Итак, набираем F и внутренний номер абонента, а потом кладем трубку. Мини АТС подает на АЛ этого абонента звонковый сигнал “вызов от СЛ”.

Если этот абонент занят, мини АТС подаст в линию сигнал “требование соединения”

Все это время внешний абонент будет находиться в режиме ожидания.

Конечно, бывает и так. что абонент. которому послали вызов, не отвечает. Тогда соединение возвращается к первому абоненту. Мини АТС подает на его АЛ специальный сигнал “Заказ выполнен”. Мол, не обессудьте, гражданин, я сделала все, что могла.

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

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

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

ОБЪЕДИНИТЬ.

Предположим, сотрудник разговаривает по телефону с коллегой. В этот момент мини АТС подает в линию сигнал о том. что поступил внешний вызов.

Выше уже рассказывалось о том, как сохранить текущее соединение и принять новый звонок. Дальше можно переключаться между соединениями, сколько душе угодно. Для этого имеется команда F 6.

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

Для таких случаев предусмотрена команда F 8. Получив ее, мини АТС объединяет два соединения в одно, и все трое могут и говорить, и слышать друг друга.

Таким образом. входящая связь через мини АТС может быть организована очень гибко и разнообразно. Главное — знать. как это делается, и установить нужные настройки для соединительных и абонентских линий.

ПЕРЕАДРЕСОВАТЬ
Переадресация. или “Следуй за мной”

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

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

Именно для таких случаев настраивают переадресацию. Кстати. это касается как внешней. так и внутренней входящей связи. Суть такова (на примере МАКСИКОМ MXM500P).

На своем телефоне абонент выполняет следующие действия:
  • снимает трубку.
  • Дожидается сигнала “Готовность”
  • набирает последовательность 65+номер своей АЛ + номер новой АЛ.

Теперь все входящие вызовы: как внешние, так и внутренние, будут поступать на “новую ” АЛ. Более того, с новой АЛ можно настроить еще одну переадресацию и т.д. — до образования целой цепочки.

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

Очень удобно, что цепочки переадресаций можно менять, зная график и маршрут своих перемещений.

Более того, схемы переадресации можно оперативно менять. При этом никакие программные настройки самой станции менять не придется.

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

Ваш адрес email не будет опубликован. Обязательные поля помечены *