关于基本oops概念的问题

时间:2011-02-18 04:47:46

标签: oop interface

我只是想找到这个问题的答案

设A是一个父类,B,C是子类。

现在我们按如下方式创建对象,

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

  4. A o4 = new B();

  5. B o5 = new A();
  6. C o6 = new B();
  7. 从这些都会产生错误以及为什么......我很困惑,因为从6开始我们就知道这是一个错误,因为b可能有一些专门的变量,7个是可能的,8个是不可能的。

    如果我错了,请纠正我,

    1. A o7 = o4;
    2. B 08 = o5;
    3. 请建议我正确的答案和解释,并给我链接教程与这种谜题。

4 个答案:

答案 0 :(得分:3)

假设所有对象都是指针类型 -

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*的子对象,因此左值可以指向它,它也等于类型A*。这有助于在派生类中访问基类重写的虚拟方法。

  2. new A()构造一个A*类型的对象并返回它的地址。因此,返回类型为A*,但接收类型为B*。所以,它们都不相容而且是错误的。

  3. 示例:Output results

    #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";
        }
    

    };

    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


    析构函数A


    析构函数B

    析构函数A


    析构函数C

    析构函数A


    请注意,销毁顺序与构造顺序相反。

答案 1 :(得分:1)

除了#5&amp; #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();

答案 2 :(得分:1)

这不是你问题的直接答案,因为我认为其他人已经回答了你的问题。但是,我注意到你似乎在假设对象根据内存分配进行类型检查。

他们不会根据类定义进行检查。让我举个例子,希望能带来一种理解:

假设我们有两个已在同一名称空间中定义的类,它们具有相同的方法和属性。唯一的区别是他们的班级名称。就编译器和运行时而言,这两个类将无任何关系

您必须定义另一种与他们相关的OOP方式。例如,您可以让两个类继承相同的父级,或者让它们都实现相同的接口。

使用Interface方法通常更可取,因为许多关系不大的类可以实现一个接口,以便其他对象可以通过接口方法与它们进行交互。

OOP很难理解,因为它实际上是关于抽象的,与编码金属的关系很小。一旦了解了抽象的内容以及它们如何一起使用,事情变得更容易。祝你好运。

答案 3 :(得分:1)

在您提出的问题中,

A是超类,
B,C是A的两个不同的子类,即B extends AC 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.    

原因:这是因为超类在继承时不知道它的子类添加了什么功能。因此,超类对象到子类引用的分配是incorrectfutile.


现在是第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.