Классы. Наследование: различия между версиями

Материал из wikiru.visual-prolog.com

Строка 170: Строка 170:




Цитата
Цитата
Если интерфейс не указывается, то класс является статическим, то есть не способен порождать объекты.
А есть особенности его наследования? (статические методы остаются статическими)
Статический класс не наследуется - у него нет ни конструктора, ни интерфейса, а они необходимы для работы механизма наследования.
Цитата
В 5-ке в классе описывается весь интерфейс, а в 6-ке есть интерфейсы, и что теперь описывается в классе (class : interface >...< end class)?
Т.е. класс потдерживает некий интерфейс (набор фактов и предикатов) прлюс ещё некий набор статических фактов и предикатов?
Да, класс может поддерживать некий интерфейс и плюс набор статических сущностей.
Цитата
Цитата
В имплементации происходит наследование классов,
а вот наследуются методы или нет - это определяется интерфейсами, которые эти классы поддерживают.
Опа. Это тема, видимо, касается и predicates from.
А можно показать пример для уточнения, как интерфейсы влияют на наследование.
А то я, по ранее написанному, понял, что пока явно не пропишешь predicates from,
то все наследуемые предикаты protected, независимо от совпадения имён и интерфейс
наследуемого предиката ваще игнорируется.
Нет, конструкция "predicates from ..." - это из разряда охотничьих рассказов "... А вот у меня однажды случай был...!... И тогда я ..."
Здесь все проще.
Из иплементации дочернего класса видны все предикаты, декларированные в интерфейсах родительских классов.
При обращении же к дочернему классу видны только предикаты, декларированные в интерфейсе этого дочернего класса.
Рассмотрим пример.
Допустим, есть классы - родители (я опускаю синтаксические детали вроде 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


[[Категория:VipLanguage]]
[[Категория:VipLanguage]]

Версия 15:37, 19 сентября 2007

Не редактировать. Статья в работе

В VIP: 1. Правила видимости существуют, но нет ни одного ключевого слова для их обозначения, то есть и ключевое слово protected тоже исчезло. В VIP все правила видимости определяются местом декларации сущности.

2. Понятие АBSTACT CLASS не используется, его заменила более гибкая конструкция Interface

3. Ключевое слово STATIC не используется, его аналогом являются конструкции class predicates и class facts.

4. Имя интерфейса является также и именем домена, что дает возможность взаимных преобразований интерфейсов по общим правилам преобразования доменов (семантически допустимым, естественно).

Сразу подчеркну, что факты подчиняются только правилу видимости private. Это сделано намеренно.

а вот пример действия правила protected


Код 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. Причина дисциплинарного характера - выполнять операции над фактами только через соответствующие предикаты. Глобальные данные должны храниться в объекте, о котором должны знать те, кому положено.

Учитывая 2, не стали бороться с 1.


Цитата В обьявлении класса указываются ТОЛЬКО интерфейс (притом один)

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


Цитата а вот наследование методов происходит только в имплементах. Или я не угадал?

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

Ниже я переименовал классы и интерфейсы, чтобы было яснее где что.


Код 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.


Цитата Коль, обьявления класса основывается на интерфейсах и описывается в декларативной части, а реализация наследуется и описывается в имплементной, то можно предположить, что можно, в принципе, заинтерфейснить от одного, а заинхеритить от другого, никак (даже далеко) не связанного с данным интерфейсом класса, лиш бы в итоге все методы с полями интерфейса были реализованны. Или не так?

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

Лучше смотреть с такой позиции: a) Интерфейс никак не зависит от класса - это именованный набор предикатов и/или доменов и/или констант.

B) Класс поддерживает некоторый интерфейс (своей имплементацией), если этот интерйес указан в декларации класса.

c) Имплементация всегда соответствует классу и имеет с ним одно имя.

d) Если класс поддерживает интерфейс, то имплементация должна тем или иным образом привести к клаузу для каждого предиката интерфейса.

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


Цитата Цитата Если интерфейс не указывается, то класс является статическим, то есть не способен порождать объекты.

А есть особенности его наследования? (статические методы остаются статическими)


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


Цитата В 5-ке в классе описывается весь интерфейс, а в 6-ке есть интерфейсы, и что теперь описывается в классе (class : interface >...< end class)? Т.е. класс потдерживает некий интерфейс (набор фактов и предикатов) прлюс ещё некий набор статических фактов и предикатов?


Да, класс может поддерживать некий интерфейс и плюс набор статических сущностей.

Цитата Цитата В имплементации происходит наследование классов, а вот наследуются методы или нет - это определяется интерфейсами, которые эти классы поддерживают.

Опа. Это тема, видимо, касается и predicates from. А можно показать пример для уточнения, как интерфейсы влияют на наследование. А то я, по ранее написанному, понял, что пока явно не пропишешь predicates from, то все наследуемые предикаты protected, независимо от совпадения имён и интерфейс наследуемого предиката ваще игнорируется.


Нет, конструкция "predicates from ..." - это из разряда охотничьих рассказов "... А вот у меня однажды случай был...!... И тогда я ..."

Здесь все проще.

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

Рассмотрим пример.

Допустим, есть классы - родители (я опускаю синтаксические детали вроде 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