Классы. Наследование: различия между версиями
Строка 1: | Строка 1: | ||
Обсуждаемы далее механизмы наследования включают понятие "правила видимости". | |||
В | В вульгарной интерпретации под правилом видимости мы понимаем возможность обращения к константам, доменам, предикатам, клаузам и фактам (базовым элементам языка) одной сущности из какой-либо другой сущности. Такими сущностями являются классы и объекты. | ||
В VIP все правила видимости определяются местом декларации. Таким местом может быть: | |||
*декларация класса (class ... end class) | |||
*декларация интерфейса (interface ... end interface) | |||
*имплементация класса (implement ... end implement) | |||
Рассмотрим следующие программные конструкции | |||
<vip> | |||
class parent:parent | class parent:parent | ||
end class | end class | ||
Строка 21: | Строка 15: | ||
predicates | predicates | ||
helloWorldFromParent:(string Text). | helloWorldFromParent:(string Text). | ||
end interface parent | end interface parent | ||
Строка 28: | Строка 21: | ||
helloWorldFromParent(Text):- | helloWorldFromParent(Text):- | ||
write(Text). | write(Text). | ||
end implement parent | end implement parent | ||
class child:child | class child:child | ||
Строка 37: | Строка 28: | ||
interface child | interface child | ||
helloWorldFromChild:(string Text). | helloWorldFromChild:(string Text). | ||
end interface child | end interface child | ||
implement child | implement child | ||
inherits parent | inherits parent | ||
clauses | clauses | ||
helloWorldFromChild(Text):- | helloWorldFromChild(Text):- | ||
write(Text). | write(Text). | ||
end implement child | end implement child | ||
</vip> | |||
Здесь | Здесь | ||
helloWorldFromChild(...) - подчиняется правилу public | helloWorldFromChild(...) - подчиняется правилу public | ||
а на | а на | ||
Строка 62: | Строка 47: | ||
helloWorldFromChild(...), так и к предикату helloWorldFromParent(...). | helloWorldFromChild(...), так и к предикату helloWorldFromParent(...). | ||
Имя интерфейса является также и именем домена | Имя интерфейса является также и именем домена | ||
объединение предикатов нескольких интерфейсов или подмена одного интерфейса другим легко делается с помощью объявления supports, например, | объединение предикатов нескольких интерфейсов или подмена одного интерфейса другим легко делается с помощью объявления supports, например, | ||
<vip> | |||
interface myInterface | interface myInterface | ||
supports myInterface1 | supports myInterface1 | ||
supports myInterface2 | supports myInterface2 | ||
end interface myInterface | end interface myInterface | ||
</vip> | |||
Если у Вас есть интерфейсы myInterface1 и myInterface2, то через myInterface можно оперировать предикатами из myInterface1 и myInterface2 как предикатами одного интерфейса. В добавок myInterface тоже может иметь свой список объявлений предикатов. | Если у Вас есть интерфейсы myInterface1 и myInterface2, то через myInterface можно оперировать предикатами из myInterface1 и myInterface2 как предикатами одного интерфейса. В добавок myInterface тоже может иметь свой список объявлений предикатов. | ||
Строка 99: | Строка 75: | ||
2. Причина дисциплинарного характера - выполнять операции над фактами только через соответствующие предикаты. Глобальные данные должны храниться в объекте, о котором должны знать те, кому положено. | 2. Причина дисциплинарного характера - выполнять операции над фактами только через соответствующие предикаты. Глобальные данные должны храниться в объекте, о котором должны знать те, кому положено. | ||
В имплементации происходит наследование классов (точнее - объектов-экземпляров этих классов), а вот наследуются методы или нет - это определяется интерфейсами, которые эти классы поддерживают. Кроме того, предикаты, объявленные внутри имплементации видны только изнутри только этой имплементации. | В имплементации происходит наследование классов (точнее - объектов-экземпляров этих классов), а вот наследуются методы или нет - это определяется интерфейсами, которые эти классы поддерживают. Кроме того, предикаты, объявленные внутри имплементации видны только изнутри только этой имплементации. | ||
Ниже я переименовал классы и интерфейсы, чтобы было яснее где что. | Ниже я переименовал классы и интерфейсы, чтобы было яснее где что. | ||
<vip> | |||
class parentClass:parentInterface | class parentClass:parentInterface | ||
end class parentClass | end class parentClass | ||
Строка 146: | Строка 107: | ||
interface childInterface | interface childInterface | ||
end interface childInterface | end interface childInterface | ||
</vip> | |||
publicPredicate() доступен из класса childClass,а | publicPredicate() доступен из класса childClass,а | ||
Строка 152: | Строка 113: | ||
кроме как в самом классе parentClass. | кроме как в самом классе parentClass. | ||
*Интерфейс никак не зависит от класса - это именованный набор предикатов и/или доменов и/или констант. | |||
*Класс поддерживает некоторый интерфейс (своей имплементацией), если этот интерйес указан в декларации класса. | |||
*Имплементация всегда соответствует классу и имеет с ним одно имя. | |||
*Если класс поддерживает интерфейс, то имплементация должна тем или иным образом привести к клаузу для каждого предиката интерфейса. | |||
Поэтому может быть много разных классов , поддерживающих один и тот же интерфейс. | Поэтому может быть много разных классов , поддерживающих один и тот же интерфейс. | ||
Статический класс не наследуется - у него нет ни конструктора, ни интерфейса, а они необходимы для работы механизма наследования. | Статический класс не наследуется - у него нет ни конструктора, ни интерфейса, а они необходимы для работы механизма наследования. | ||
Да, класс может поддерживать некий интерфейс и плюс набор статических сущностей. | Да, класс может поддерживать некий интерфейс и плюс набор статических сущностей. | ||
В имплементации происходит наследование классов, | В имплементации происходит наследование классов, | ||
а вот наследуются методы или нет - это определяется интерфейсами, которые эти классы поддерживают. | а вот наследуются методы или нет - это определяется интерфейсами, которые эти классы поддерживают. | ||
Из иплементации дочернего класса видны все предикаты, декларированные в интерфейсах родительских классов. | Из иплементации дочернего класса видны все предикаты, декларированные в интерфейсах родительских классов. | ||
Строка 210: | Строка 134: | ||
Допустим, есть классы - родители (я опускаю синтаксические детали вроде end class... и похожие) | Допустим, есть классы - родители (я опускаю синтаксические детали вроде end class... и похожие) | ||
<vip> | |||
parentClass_1:Interface_1 | parentClass_1:Interface_1 | ||
parentClass_2:Interface_2 | parentClass_2:Interface_2 | ||
</vip> | |||
Имплементации классов parentClass_1 и parentClass_2 поддерживают предикаты, декларированные в интерфейсах Interface1 и Interface2, соответственно. | Имплементации классов parentClass_1 и parentClass_2 поддерживают предикаты, декларированные в интерфейсах Interface1 и Interface2, соответственно. | ||
Допустим, есть дочерний класс childClass:childInterface | Допустим, есть дочерний класс childClass:childInterface | ||
Пусть есть интерфейс | Пусть есть интерфейс | ||
<vip> | |||
interface childInterface | interface childInterface | ||
supports Interface_1 | supports Interface_1 | ||
</vip> | |||
Примечание: для такого случая можно было бы иметь | Примечание: для такого случая можно было бы иметь | ||
декларацию класса в виде childClass:Interface_1 | декларацию класса в виде childClass:Interface_1 | ||
Теперь пусть есть имплементация дочернего класса: | Теперь пусть есть имплементация дочернего класса: | ||
<vip> | |||
implement childClass | implement childClass | ||
inherits parentClass_1 | inherits parentClass_1 | ||
inherits parentClass_2 | inherits parentClass_2 | ||
</vip> | |||
Что и откуда можно видеть? | Что и откуда можно видеть? | ||
1. из имплемнтации childClass видны (могут быть вызваны): | 1. из имплемнтации childClass видны (могут быть вызваны): | ||
Строка 236: | Строка 160: | ||
B) все предикаты, декларированные интерфейсе Interface_1 | B) все предикаты, декларированные интерфейсе Interface_1 | ||
с) все предикаты, декларированные интерфейсе Interface_2 | с) все предикаты, декларированные интерфейсе Interface_2 | ||
2. Из какого-либо класса вне childClass видны (могут быть вызваны) при обращеии к его экземпляру: | 2. Из какого-либо класса вне childClass видны (могут быть вызваны) при обращеии к его экземпляру: | ||
a) все предикаты, непосредственно декларированные интерфейсе childInterface | a) все предикаты, непосредственно декларированные интерфейсе childInterface |
Версия 14:03, 26 сентября 2007
Обсуждаемы далее механизмы наследования включают понятие "правила видимости". В вульгарной интерпретации под правилом видимости мы понимаем возможность обращения к константам, доменам, предикатам, клаузам и фактам (базовым элементам языка) одной сущности из какой-либо другой сущности. Такими сущностями являются классы и объекты.
В VIP все правила видимости определяются местом декларации. Таким местом может быть:
- декларация класса (class ... end class)
- декларация интерфейса (interface ... end interface)
- имплементация класса (implement ... end implement)
Рассмотрим следующие программные конструкции
class parent:parent end class interface parent predicates helloWorldFromParent:(string Text). end interface parent implement parent clauses helloWorldFromParent(Text):- write(Text). end implement parent class child:child end class interface child helloWorldFromChild:(string Text). end interface child implement child inherits parent clauses helloWorldFromChild(Text):- write(Text). end implement child
Здесь helloWorldFromChild(...) - подчиняется правилу public а на helloWorldFromParent(...) - действует правило protected.
У объекта класса child можно вызвать только предикат helloWorldFromChild(...), а из объекта класса child можно обратиться как к предикату helloWorldFromChild(...), так и к предикату helloWorldFromParent(...).
Имя интерфейса является также и именем домена
объединение предикатов нескольких интерфейсов или подмена одного интерфейса другим легко делается с помощью объявления supports, например,
interface myInterface supports myInterface1 supports myInterface2 end interface myInterface
Если у Вас есть интерфейсы myInterface1 и myInterface2, то через myInterface можно оперировать предикатами из myInterface1 и myInterface2 как предикатами одного интерфейса. В добавок myInterface тоже может иметь свой список объявлений предикатов.
Кроме того есть такие возможности, как delegate interface - когда можно передать исполнение предикатов интерфейса объекту, хранящемуся в факте-переменной.
Возможно перекрывать имплементацию предиката(ов) родительского класса имплементацией предиката(ов) дочернего класса, например, родителький класс содержит имплементацию "по умолчанию", а ряд конкретных классов должен реагировать на вызов предикатов особенным образом.
Клаузы для предикаты одного интерфейса могут содержаться в имлементациях разных классов путем использования конструкции predicates from ...
То есть интерфейс есть фасадная часть класса (динамического), а механизмы имплементации могут быть самыми разными.
Я думаю здесь та же история, что и с типизацией в Turbo, PDC и Visual Прологах: технически оправдано и практически ведет к повышению надежности программ.
1. Ни классы, ни интерфейсы не имеют никаких предопределенных предикатов (кроме конструкторов, относящихся только к декларации класса), а видимость фактов предполагает операции над ними и, cоответственно, наличие предопределенных предикатов. 2. Причина дисциплинарного характера - выполнять операции над фактами только через соответствующие предикаты. Глобальные данные должны храниться в объекте, о котором должны знать те, кому положено.
В имплементации происходит наследование классов (точнее - объектов-экземпляров этих классов), а вот наследуются методы или нет - это определяется интерфейсами, которые эти классы поддерживают. Кроме того, предикаты, объявленные внутри имплементации видны только изнутри только этой имплементации.
Ниже я переименовал классы и интерфейсы, чтобы было яснее где что.
class parentClass:parentInterface end class parentClass interface parentInterface predicates publicPredicate:(). end interface parentInterface implement parentClass clauses publicPredicate():- write(""). predicates privatePredicate:(). clauses privatePredicate():- write("TTT"). end implement parentClass class childClass:childInterface end class childClass implement childClass inherits parentClass end implement childClass interface childInterface end interface childInterface
publicPredicate() доступен из класса childClass,а privatePredicate недоступен для использования нигде, кроме как в самом классе parentClass.
- Интерфейс никак не зависит от класса - это именованный набор предикатов и/или доменов и/или констант.
- Класс поддерживает некоторый интерфейс (своей имплементацией), если этот интерйес указан в декларации класса.
- Имплементация всегда соответствует классу и имеет с ним одно имя.
- Если класс поддерживает интерфейс, то имплементация должна тем или иным образом привести к клаузу для каждого предиката интерфейса.
Поэтому может быть много разных классов , поддерживающих один и тот же интерфейс.
Статический класс не наследуется - у него нет ни конструктора, ни интерфейса, а они необходимы для работы механизма наследования.
Да, класс может поддерживать некий интерфейс и плюс набор статических сущностей.
В имплементации происходит наследование классов, а вот наследуются методы или нет - это определяется интерфейсами, которые эти классы поддерживают.
Из иплементации дочернего класса видны все предикаты, декларированные в интерфейсах родительских классов. При обращении же к дочернему классу видны только предикаты, декларированные в интерфейсе этого дочернего класса.
Рассмотрим пример.
Допустим, есть классы - родители (я опускаю синтаксические детали вроде end class... и похожие)
parentClass_1:Interface_1 parentClass_2:Interface_2
Имплементации классов parentClass_1 и parentClass_2 поддерживают предикаты, декларированные в интерфейсах Interface1 и Interface2, соответственно.
Допустим, есть дочерний класс childClass:childInterface Пусть есть интерфейс
interface childInterface supports Interface_1
Примечание: для такого случая можно было бы иметь декларацию класса в виде childClass:Interface_1
Теперь пусть есть имплементация дочернего класса:
implement childClass inherits parentClass_1 inherits parentClass_2
Что и откуда можно видеть? 1. из имплемнтации childClass видны (могут быть вызваны): a) все предикаты, непосредственно декларированные интерфейсе childInterface B) все предикаты, декларированные интерфейсе Interface_1 с) все предикаты, декларированные интерфейсе Interface_2
2. Из какого-либо класса вне childClass видны (могут быть вызваны) при обращеии к его экземпляру: a) все предикаты, непосредственно декларированные интерфейсе childInterface B) все предикаты, декларированные интерфейсе Interface_1