1
$\begingroup$

Let's say I have three classes, Animal, Bird and Pigeon. If Bird extends Animal and Pigeon extends Bird, is Animal the parent class for both or is Bird?

So, for instance, if the constructor for Animal said "hi I am animal" and the constructor for Bird said "hi am I bird", which will it say in class Pigeon if I call the super constructor?

$\endgroup$
  • 1
    $\begingroup$ Questions about Java are off-topic here. I suggest you just write a Java program and see what it prints. $\endgroup$ – Yuval Filmus Aug 7 '17 at 10:23
  • $\begingroup$ I think this can be read as an OOP terminology question, @YuvalFilmus . Don't think the answer is specific to Java. $\endgroup$ – Raphael Aug 7 '17 at 10:34
  • 1
    $\begingroup$ fade2black's answer shows that it is a Java question after all. $\endgroup$ – Yuval Filmus Aug 7 '17 at 12:59
  • $\begingroup$ @YuvalFilmus I fully agree with you. $\endgroup$ – fade2black Aug 7 '17 at 12:59
  • 1
    $\begingroup$ @YuvalFilmus Maybe there are to separate questions here. a) Is Animal a "parent" for both? This has a general answer in the OOP world. b) Which constructors get called? This may depend on the specific language/compiler. $\endgroup$ – Raphael Aug 7 '17 at 13:27
2
$\begingroup$

You cannot answer this question unambiguously. Different OOP languages implement OOP paradigm differently.

In Ruby you will get only "Hi, I am bird!"

class Animal
  def initialize
    puts "Hi, I am animal!"
  end
end

class Bird < Animal
  def initialize
    puts "Hi, I am bird!"
  end
end

class Pigeon < Bird
  def initialize
    super # <= call to the superclass
  end
end

pg = Pigeon.new

In PHP we get only "Hi, I am bird!"

<?php

   class Animal {

      public function __construct()
      {
        echo "I'm Animal";
      }

    }

    class Bird extends Animal {

       public function __construct()
       {
         echo "I'm Bird";
       }  

    }

   class Pigeon extends Bird {

      public function __construct()
      {
         parent::__construct();
      }

    }

   $Pigeon = new Pigeon();

  ?>

While in C++ you will get both "Hi I am animal!" and "Hi I am Bird!"

#include <iostream>
using namespace std;

class Animal
{
   public:
   Animal()
   {
     cout << "Hi I am animal!" << endl;
   }
};

class Bird : public Animal
{
  public:
  Bird()
  {
    cout << "Hi I am Bird!" << endl;
  }
};

class Pigeon : public Bird
{
  public:
  Pigeon():Bird(){} // <= call to the base constructor
};

int main()
{
  Pigeon pg;
}

In Swift (Apple) we get both, too

class Animal {
  public init() {
    print("I'm Animal")
  }
}

class Bird: Animal {
   public override init() {
     print("I'm Bird")
   }
}

class Pigeon: Bird {
   public override init() {
    super.init()
   }
}

var pigeon = Pigeon()

To understand why, you should get into details of how C++ implements OOP (vtables and etc.) and how Ruby classes lookup its methods and constants in the hierarchy, and other languages.

In addition if you want to see Object Oriented "Nightmare" then have a look at Lua, though I like it.

As to your question in the title: "Are grandparent classes also parents", of course subclasses are related to all super-classes up in the hierarchy chain, but that relationship are implemented differently in different programming languages.

$\endgroup$
  • $\begingroup$ Leaving out calls to the parent constructor will have different effects, true. For instance, in Swift calls to super.init() are added implicitly. I don't think this answer is helpful on the conceptual level. $\endgroup$ – Raphael Aug 7 '17 at 13:26
  • $\begingroup$ @Raphael I don't want to discuss the concepts in OOP as such here, since the asker's question is not about the concepts of OOP. He describes a scenario and asks for an output probably with Java in mind. I clearly answered the asker's question, namely, that it cannot be answered unambiguously, by giving examples. Maybe it is not helpful (as YOU think) on the conceptual level, but my intention wasn't to give full conceptual answer. I think if asker is interested in more detailed answer he may ask by posting a comment. $\endgroup$ – fade2black Aug 7 '17 at 14:20
  • $\begingroup$ If you read the question as a Java question, you should have voted to close as offtopic instead of answering. The question about principles is the only one that's ontopic here; no specific programming language is. That said, the scope of your answer is certainly your choice. As the scope of my comment is mine. $\endgroup$ – Raphael Aug 7 '17 at 15:17
0
$\begingroup$

You have a type hierarchy here. Animal is parent for Bird and Bird is for Pigeon. Since the inheritance relation is transitive, Animal is a "parent" for Pigeon as well.

In real-world language, of course, lots of watering down and extension of core principles happen. For instance, which behaviour overrides which can be different due to different method dispatching rules.

Specifically for constructors, conceptually Pigeon() should call Bird(), and Bird() should call Animal(); otherwise we don't know that the object is set up correctly. Hence, Pidgeon() will "say" both! (Which it says first depends on where in the constructors the super() calls happen in relation to the "saying".)

Note that some programming languages may allow you to leave out calls to the super constructor at your own risk (specifically breaking Liskov's substitution principle if you're not careful).

$\endgroup$
  • $\begingroup$ You are still wrong. Do some reading. The main purpose of a constructor is to prepare and create an object, make it ready for use. A properly written constructor leaves the resulting object in a valid state, an there is no requirement to call all superclass constructors up in the hierarchy chain. I will call base class constructor, or not, it's up to me. $\endgroup$ – fade2black Aug 7 '17 at 14:33
  • $\begingroup$ @fade2black I specifically address this scenario in the last paragraph. $\endgroup$ – Raphael Aug 7 '17 at 15:16
  • 2
    $\begingroup$ If you are going to use terminology like "parent" and "grandparent", then there's no reason to consider Animal a "parent" of Pigeon. The typical term for the transitive relation would be "ancestor". $\endgroup$ – Derek Elkins Aug 7 '17 at 23:01

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.