вопрос об основных понятиях упс - PullRequest
1 голос
/ 18 февраля 2011

Я просто хочу найти ответ на этот вопрос

Пусть A будет родительским классом с B, C дочерними классами.

Теперь мы создаем объекты следующим образом,

  1. A o1 = новый A ();
  2. B o2 = новый B ();
  3. C o3 = новый C ();

  4. A o4 = новый B ();

  5. B o5 = новый A ();
  6. C o6 = новый B ();

Из этих, которые будут создавать ошибки и почему .. Я много запутался, потому что из 6 мы знаем, что это ошибка, потому что b может иметь некоторые специализированные переменные, а 7 возможно, а 8 невозможно.

Если я ошибаюсь, поправьте меня, а также,

  1. A o7 = o4;
  2. B 08 = o5;

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

Ответы [ 4 ]

3 голосов
/ 18 февраля 2011

Предполагая, что все объекты относятся к типу указателя-

1. A *o1 = new A();   // Correct
2. B *o2 = new B();   // Correct
3. C *o3 = new C();   // Correct

4. A *o4 = new B(); // A pointer to a derived class is type-compatible with a pointer to its base class. This is up casting which acts by default.
5. B *o5 = new A(); // Wrong because the other-wise relationship of the above comment isn't true. Though there is a separate concept called Down-casting which isn't valid here.
6. C *o6 = new B();  // Wrong : C, B has no hierarchial relationships

7. A *o7 = o4;      // Correct because o4, o7 are both of same type
8. B *o8 = o5;      // Wrong. Since, 5 itself is wrong.

Объяснение для 4 и 5:

  1. new B() вызывает конструктор A's, за которым следует конструктор B's. Итак, у нас есть подобъекты типа A*, B*. Поскольку существует подобъект типа A*, на него может указывать lvalue, который также равен типу A*. Это полезно для доступа к переопределенным виртуальным методам базового класса в производном классе.

  2. new A() создает объект типа A* и возвращает его адрес. Итак, тип возвращаемого значения - A*, а тип получаемого - B*. Итак, они оба несовместимы и ошибочны.

Пример: Результаты вывода

#include <iostream>
using namespace std;
class A
{
    public:
    A(){
        cout << " \n Constructor A \n";
    }
    virtual ~A(){
        cout << "\n Destructor A \n";
    }
};

class B: public A
{
    public:
    B(){
        cout << " \n Constructor B \n";
    }
    ~B(){
        cout << "\n Destructor B \n";
    }

};

class C: public A
{
    public:
    C(){
        cout << " \n Constructor C \n";
    }
    ~C(){
        cout << "\n Destructor C \n";
    }
* +1034 *};
int main()
{
    A* obj1 = new A;
    std::cout<< "******************************" << std::endl;

    A* obj2 = new B;
    std::cout<< "******************************" << std::endl;

    A* obj3 = new C;
    std::cout<< "******************************" << std::endl;

    delete obj1;
    std::cout<< "******************************" << std::endl;

    delete obj2;
    std::cout<< "******************************" << std::endl;

    delete obj3;
    std::cout<< "******************************" << std::endl;

    return 0;
}

Результаты

Конструктор A


Конструктор A

Конструктор B


Конструктор A

Конструктор C


Деструктор А


Деструктор B

Деструктор A


Деструктор С

Деструктор A


Обратите внимание, что порядок уничтожения обратен порядку строительства.

1 голос
/ 21 февраля 2011

В вашем вопросе, как вы упомянули,

A - это суперкласс,
B, C - два разных подкласса A. т.е. B extends A, C extends A

Давайте пойдем шаг за шагом

Теперь ваше представление о ссылках на различные объекты длится до 4-го шага.
т.е.

A o1 = new A();   //Creates a new A() object and assigns it to ref. of type A. So  Correct.
B o2 = new B();   //Creates a new B() object and assigns it to ref. of type B. So  Correct.
C o3 = new C();   //Creates a new C() object and assigns it to ref. of type C. So  Correct. 

A o4 = new B();   //Subclass object being assigned to a superclass reference. That's also correct.  

Теперь на5-й шаг,

B o5 = new A();   //Will not compile since a superclass object is assigned to a subclass reference.  
                  //This is not allowed in Java.    

Причина: Это потому, что суперкласс не знает, какие функции его подкласс добавил к себе при наследовании.Таким образом, это назначение объекта суперкласса для ссылки на подкласс: incorrect и futile.


Теперь на 6-м шаге

C o6 = new B();  // There isn't any hiearchical relationship between B and C. 
                 // They are just subclass of class A. This won't compile.  

Теперь на 7-м шаге,

A o7 = o4;      //Correct. Because both the references i.e o4 & o7 are of same type (A).
                // Hence, will compile.  

Теперь на 8-м шаге

B 08 = o5;     // It is wrong because the 5th step was itself wrong.  
               // So it will produce a compile time error.
1 голос
/ 18 февраля 2011

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

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

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

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

Использование метода Interface часто предпочтительнее, так как многие классы, которые имеют небольшие отношения, могут реализовать Interface, чтобы другие объекты могли взаимодействовать с ними через методы Interface.

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

1 голос
/ 18 февраля 2011

Все будут работать, кроме # 5 и # 6, во втором наборе # 2 не будет работать просто потому, что # 5 не работает (также потому что 08 не является допустимым именем переменной).# 5 не работает, потому что B может иметь методы, которые не являются частью A, поэтому new A() не возвращает объект, совместимый с B.

В общем, вы можетеделать:

ChildOne c1 = new ChildOne();
Parent p1 = new ChildOne();

, тогда как вы не можете сделать:

ChildOne c1 = new ChildTwo();
ChildOne p1 = new Parent();
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...