Звыняйте за ламерский вопрос, о всё же...
Разбираюсь с книгой "C# и платформа .NET" Троелсена и никак не могу взять в толк где и при каких обстоятельствах применять интерфейсы! Понял только что пришли они из мира COM, и необходимы для того, чтоб клиент мог взаимодействовать с класом...
И всё же для чего они нужны? Расскажите, если не трудно!
Hello, "soljen"
> Звыняйте за ламерский вопрос, о всё же... > Разбираюсь с книгой "C# и платформа .NET" Троелсена и никак не могу взять в толк где и при каких обстоятельствах применять интерфейсы! Понял только что пришли они из мира COM, и необходимы для того, чтоб клиент мог взаимодействовать с класом... >
COM тут совершенно не причем. Интерфейс это стредство для абстрагирования от конкретной реализаци. И, если реализация может быть одна (множественного наследования нет), то интерфейсов может быть несколько (есть множественное наследование).
Posted via RSDN NNTP Server 1.9
Если у Вас нет паранойи, то это еще не значит, что они за Вами не следят.
Здравствуйте, soljen, Вы писали:
S>Доброго времени суток, дамы и господа!
S>Звыняйте за ламерский вопрос, о всё же... S>Разбираюсь с книгой "C# и платформа .NET" Троелсена и никак не могу взять в толк где и при каких обстоятельствах применять интерфейсы! Понял только что пришли они из мира COM, и необходимы для того, чтоб клиент мог взаимодействовать с класом...
S>И всё же для чего они нужны? Расскажите, если не трудно!
Интерфейс дает представление внешней среде о том, как она /среда/ может с ним /объектом/ взаимодействовать.
Так среда может почти не знать "что есть объект" по сути (не знать пути наследования), но знать что объект реализует определенный интерфейс, т.е. способ общения.
Использование — указывая, что данный класс реализует определенный интерфейс, ты обязываешься заложить в класс указанные в описании интерфейса члены и скорее всего реалзовать в этом классе поведение, описываемое интерфейсом.
Возможен также вариант "return NOT_IMPLEMENTED;", когда данный класс реализует несколько "урезанный" вариант интерфейса, но это bad code ИМХО, поскольку в местах использования интерфейса (при реализации той самой среды) придется проверять полноту реализации. Проще внегласно предъявить требование "если класс обязывается реализвать интерфейс, то он его реализует в полной мере", а урезанный вариант увязать с наследованием интерфейсов, выделив "урезанный" функционал в родительский интерфейс.
Доброго времени суток, TK!
TK>COM тут совершенно не причем. Интерфейс это стредство для абстрагирования от конкретной реализаци. И, если реализация может быть одна (множественного наследования нет), то интерфейсов может быть несколько (есть множественное наследование).
Т.е. своими словами, это возможность использовать методы класа не создавая его наследника?
Здравствуйте, soljen, Вы писали:
S>Доброго времени суток, TK!
TK>>COM тут совершенно не причем. Интерфейс это стредство для абстрагирования от конкретной реализаци. И, если реализация может быть одна (множественного наследования нет), то интерфейсов может быть несколько (есть множественное наследование).
S>Т.е. своими словами, это возможность использовать методы класа не создавая его наследника?
S> В корень запутался!
Глупый пример:
есть светильник и токарный станок
Оба имеют выключатель.
Так вот есть два пути:
1) выделить общего предка "штука с выключателем", что зачастую бывает абсолютно некорректно
2) объявить интерфейс "выключателя" (например интерфейс ISwitchable с методом switch() ) и указать, что светильник и станок реализуют этот интерфейс, что уже более корректно.
В первом случае проблем даже больше чем просто некорректность — там еще заморочки с абстрактными методами, перекрытием... С интерфейсом все ясно — объявил, что класс реализует интерфейс, значит в классе должны быть объявлены все члены этого самого интерфейса.
В примере еще одна характерная весчь — метод switch() для классов станка и светильника будет наверняка в корне отличаться по реализации, зато интерфейс один и когда придет к нам РАО ЕЭС со своим рубильником то сможет сделать пакость одним движением руки ((ISwitchable)obj).switch()
Доброго времени суток, nayato!
N>Глупый пример: N>есть светильник и токарный станок N>Оба имеют выключатель. N>Так вот есть два пути: N>1) выделить общего предка "штука с выключателем", что зачастую бывает абсолютно некорректно N>2) объявить интерфейс "выключателя" (например интерфейс ISwitchable с методом switch() ) и указать, что светильник и станок реализуют этот интерфейс, что уже более корректно.
N>В первом случае проблем даже больше чем просто некорректность — там еще заморочки с абстрактными методами, перекрытием... С интерфейсом все ясно — объявил, что класс реализует интерфейс, значит в классе должны быть объявлены все члены этого самого интерфейса.
Угу, немного прояснилось! Перечитаю ка я главу ещё разок, да примерчики поковыряю снова!
N>... и когда придет к нам РАО ЕЭС со своим рубильником то сможет сделать пакость одним движением руки ((ISwitchable)obj).switch()
Доброго времени суток, nayato
N>Глупый пример: N>есть светильник и токарный станок N>Оба имеют выключатель. N>Так вот есть два пути: N>1) выделить общего предка "штука с выключателем", что зачастую бывает абсолютно некорректно N>2) объявить интерфейс "выключателя" (например интерфейс ISwitchable с методом switch() ) и указать, что светильник и станок реализуют этот интерфейс, что уже более корректно.
N>В первом случае проблем даже больше чем просто некорректность — там еще заморочки с абстрактными методами, перекрытием... С интерфейсом все ясно — объявил, что класс реализует интерфейс, значит в классе должны быть объявлены все члены этого самого интерфейса. N>В примере еще одна характерная весчь — метод switch() для классов станка и светильника будет наверняка в корне отличаться по реализации, зато интерфейс один и когда придет к нам РАО ЕЭС со своим рубильником то сможет сделать пакость одним движением руки ((ISwitchable)obj).switch()
А почем не метод? Чем плох метод в данном случае? Или в каких лучше методы использовать, в каких интерфейсы?
Здравствуйте, soljen, Вы писали:
S>А почем не метод? Чем плох метод в данном случае? Или в каких лучше методы использовать, в каких интерфейсы?
Дело не в том, плох он или нет, а в том, что цепочки наследования у токарного станка и у светильника могут со-о-овсем разными и выделить "штуку с выкючателем" ты просто не сможешь.
Есть еще один момент, о котором не упомянули. Классы могут иметь свои данные, интерфейсы — нет.
Здравствуйте, Andrbig, Вы писали:
A>Здравствуйте, soljen, Вы писали:
S>>А почем не метод? Чем плох метод в данном случае? Или в каких лучше методы использовать, в каких интерфейсы?
A>Дело не в том, плох он или нет, а в том, что цепочки наследования у токарного станка и у светильника могут со-о-овсем разными и выделить "штуку с выкючателем" ты просто не сможешь.
A>Есть еще один момент, о котором не упомянули. Классы могут иметь свои данные, интерфейсы — нет.
Однако интерфэйсы могут определять свойства и события.
Здравствуйте, Twirl, Вы писали:
T>Здравствуйте, Andrbig, Вы писали:
A>>Здравствуйте, soljen, Вы писали:
S>>>А почем не метод? Чем плох метод в данном случае? Или в каких лучше методы использовать, в каких интерфейсы?
A>>Дело не в том, плох он или нет, а в том, что цепочки наследования у токарного станка и у светильника могут со-о-овсем разными и выделить "штуку с выкючателем" ты просто не сможешь.
A>>Есть еще один момент, о котором не упомянули. Классы могут иметь свои данные, интерфейсы — нет.
T>Однако интерфэйсы могут определять свойства и события.
Здравствуйте, Andrbig, Вы писали:
A>Здравствуйте, Twirl, Вы писали:
T>>Здравствуйте, Andrbig, Вы писали:
A>>>Здравствуйте, soljen, Вы писали:
S>>>>А почем не метод? Чем плох метод в данном случае? Или в каких лучше методы использовать, в каких интерфейсы?
A>>>Дело не в том, плох он или нет, а в том, что цепочки наследования у токарного станка и у светильника могут со-о-овсем разными и выделить "штуку с выкючателем" ты просто не сможешь.
A>>>Есть еще один момент, о котором не упомянули. Классы могут иметь свои данные, интерфейсы — нет.
T>>Однако интерфэйсы могут определять свойства и события.
A>Классы тоже
Я думаю Троелсен этого не упустил
И вообще вопрос был ни что умеют интерфейсы, а зачем они вообще. Кстати, интересно кто как изощряется в этой области
Здравствуйте, soljen, Вы писали:
S>А почем не метод? Чем плох метод в данном случае? Или в каких лучше методы использовать, в каких интерфейсы?
А в смысле метод? Вижу два варианта ответа:
1) у выделенного общего предка
2) просто у каждого написать switch(), не заморачиваясь на интерфейсах
Так вот:
1) уже разъяснили — некорректно может быть выделять этого самого предка.
2) тогда нет унифицированного доступа. Конечно можно с Reflection играться, но смысл, когда для этого и созданы интерфейсы?! Продолжим извращаться: есть класс "общий рубильник" (ЕЭСовский ), который держит список произвольных объектов с единственным требованием — они должны реализовывать интерфейс ISwitchable. Тогда для переключения всех сразу достаточно вызвать метод этого рубильника:
public void turnOffAll()
{
foreach (Object obj in fSwitchableObjectsCollection) {
((ISwitchable)obj).switch();
}
}
или что-то вроде...
как просто сделать это "методом" во втором смысле мне что-то не представляется...
public interface Кусаемое
{
public void Откусить();
}
public class НесъедобныеОбъекты
{
}
public class ВкусныеОбъекты
{
}
public class Ручка:НесъедобныеОбъекты,Кусаемое
{
#region Кусаемое Members
public void Откусить()
{
Console.WriteLine ( "Тьфу какая, гадость!" );
}
#endregion
}
public class Яблоко:Кусаемое
{
#region Кусаемое Members
public void Откусить()
{
Console.WriteLine ( "МММ.... Вкуснятина!" );
}
#endregion
}
public class Человек
{
public void Покусать (Кусаемое чтото)
{
for(Int32 i = 0; i < 10; i++)
{
чтото.Откусить();
}
}
}
Объект типа "Человек" может покусать все что является Кусаемым. Но Кусаемое не обязано быть СъедобнымОбъектом. Интерфейс описывает только методы, которые поддерживает объект. Любое Кусаемое можно Откусить.
Чтобы вызвать метод, нужно заранее знать тип (класс) объекта.
Фактически, Вы и вызываете метод. Только сначала приводите объект (тип которого Вам во время компиляции неизвестен) к интерфейсу (про который известно на момент компиляции, что данный объект его реализует).