Как сравнить два объекта типа Oracle OQL с общим базовым суперклассом - PullRequest
1 голос
/ 30 марта 2019

Пример:

  1. базовый класс Figure_t (супер класс)
  2. сфера_т под цифрой_т
  3. pyramid_t под figure_t
  4. оба имеют объем.
  5. Как сделать сравнение объектов, используя карту или функцию заказа?

То, что я делаю, - это использование функции-члена map в суперклассе для сравнения с использованием объема. Я попытался с / без переопределения функции карты в подклассе, но до сих пор не повезло. Я могу сравнить, если я создаю один и тот же объект дважды, но не могу, если я создаю разные.

В приведенном ниже примере я вставляю только сферу, поскольку она почти одинакова как для сферы, так и для пирамиды.

Это мой супер класс:

CREATE OR REPLACE TYPE figure_t AS OBJECT (
    v_volume   NUMBER,
    v_area      NUMBER,
    MAP MEMBER FUNCTION compare RETURN NUMBER, PRAGMA restrict_references ( compare, wnds, trust )
);
/

CREATE OR REPLACE TYPE BODY figure_t AS
    MAP MEMBER FUNCTION compare RETURN NUMBER IS
    BEGIN
        RETURN v_volume;
    END;

END;
/

ALTER TYPE figure_t NOT FINAL
    CASCADE;
/

Тогда это мой подтип:

CREATE OR REPLACE TYPE sphere_t UNDER figure_t (
    v_radio NUMBER,
    CONSTRUCTOR FUNCTION sphere_t (
           radio NUMBER
       ) RETURN SELF AS RESULT,
    MEMBER FUNCTION get_volume RETURN NUMBER,
    MEMBER FUNCTION get_area RETURN NUMBER,
    OVERRIDING MAP MEMBER FUNCTION compare RETURN NUMBER
);
/

CREATE OR REPLACE TYPE BODY sphere_t AS
    CONSTRUCTOR FUNCTION sphere_t (
        radio NUMBER
    ) RETURN SELF AS RESULT IS
    BEGIN
        self.v_radio := radio;
        self.v_volume := ( 4 / 3 ) * 3.141592654 * power(radio, 3);

        self.v_area := 4 * 3.141592654 * power(radio, 2);
        return;
    END;

    MEMBER FUNCTION get_volume RETURN NUMBER IS
    BEGIN
        RETURN v_volume;
    END;

    MEMBER FUNCTION get_area RETURN NUMBER IS
    BEGIN
        RETURN v_area;
    END;

OVERRIDING
    MAP MEMBER FUNCTION compare RETURN NUMBER IS
    BEGIN
        RETURN self.v_volume;
    END;

END;
/

Для сравнения это выглядит так:

DECLARE
    sphere_v   sphere_t;
    pyramid_v   pyramid_t;
BEGIN
    pyramid_v := pyramid_t(120, 90, 30);
    sphere_v := sphere_t(10);
    IF ( sphere_v != pyramid_v ) THEN
        dbms_output.put_line('NOT EQUAL');
    END IF;
END;

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

Ответы [ 2 ]

0 голосов
/ 31 марта 2019

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

Есть способ, просто он неочевиден.

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

 IF ( sphere_1 != sphere_2 ) THEN ...

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

 IF ( sphere_v.compare() != pyramid_v.compare() ) THEN ...

Да, это неуклюже. Но Oracle - это СУБД, а не ORDBMS (как они утверждали в версии 8.0 дней).

0 голосов
/ 30 марта 2019

Должен быть способ для этого сравнения, поскольку у фигур есть общий суперкласс

Я не совсем уверен в том, чего вы хотели достичь здесь.Кроме того, каково определение pyramid_t, которое вы используете в своем сравнении.

IF (сфера_v! = Pyramid_v) THEN

Вышеуказанное условие выглядит рискованным для меня какэто всегда будет так.

Когда вы делаете sphere_v := sphere_t(10); означает, что вы пытаетесь получить весь возврат от sphere_t до sphere_v.Так что было бы хорошо, если бы вы могли сравнить громкость и площадь Sphere и pyramid отдельно.Ниже приведена демонстрация того, как вы могли бы принять эти значения:

DECLARE
    sphere_v   sphere_t;
   -- pyramid_v   pyramid_t;

BEGIN               
    sphere_v := sphere_t(10);

    dbms_output.put_line('Input Radio     -->'||sphere_v.v_radio);
    dbms_output.put_line('Volume of Sphere-->'||sphere_v.v_volume);
    dbms_output.put_line('Area Of Sphere  -->'||sphere_v.v_area);

  --Similarly you can take the values of `volume` and `area` 
  --of pyramid and get it compared with that of Sphere.

  -- pyramid_v := pyramid_t(120, 90, 30); 
  --  dbms_output.put_line('Input Radio Pyramid -->'||pyramid_v.v_radio);
  --  dbms_output.put_line('Volume of Pyramid    -->'||pyramid_v.v_volume);
  --  dbms_output.put_line('Area Of Pyramid      -->'||pyramid_v.v_area);

  -- If sphere_v.v_volume = pyramid_v.v_volume then
  --   dbms_output.put_line('Equal');
  -- Else 
  --   dbms_output.put_line('Not Equal'); 

END;

Предположение: pyramid_t также имеет такое же определение тела объекта, имеющее вычисление объема и площади.

...