• Post Reply Bookmark Topic Watch Topic
  • New Topic
programming forums Java Mobile Certification Databases Caching Books Engineering Micro Controllers OS Languages Paradigms IDEs Build Tools Frameworks Application Servers Open Source This Site Careers Other Pie Elite all forums
this forum made possible by our volunteer staff, including ...
Marshals:
  • Campbell Ritchie
  • Jeanne Boyarsky
  • Ron McLeod
  • Paul Clapham
  • Liutauras Vilda
Sheriffs:
  • paul wheaton
  • Rob Spoor
  • Devaka Cooray
Saloon Keepers:
  • Stephan van Hulst
  • Tim Holloway
  • Carey Brown
  • Frits Walraven
  • Tim Moores
Bartenders:
  • Mikalai Zaikin

reference variables and object types

 
Greenhorn
Posts: 6
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator


usually when we use ref variable of baseclass to access an obj of derived class, we only get d access to baseclass members ,,but when i run this code ani.sleep() gives he output of derived class bird method   ..please help me guys..to understand what is happening here
 
Ranch Hand
Posts: 106
2
  • Likes 1
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
As far as I can comprehend you question, there exists a separate class named Animal which is the superclass.



Then there exists another class Bird which is the derived class or the sub class of the Animal class.



When the call is made to the Superclass via the obj reference, it prints "An animal sleeps...", where as when the call is made to the derived class via the obj1 reference it prints "A bird sleeps...". The call to the derived class prints "A bird sleeps..." because
the sleep() method of the Bird class Overrides or overshadows the method of the Animal class. I hope this resolves your doubt.
 
Bartender
Posts: 1251
87
Hibernate jQuery Spring MySQL Database Tomcat Server Java
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Welcome to CodeRanch!

Sukhitha sunil wrote:usually when we use ref variable of baseclass to access an obj of derived class, we only get d access to baseclass members


  • That is true only in case of instance variables of base class but not for all members because member of class also includes methods, members inherited from its direct superclass,direct superinterfaces etc but not applicable for all members


  • When you assigns an object of derived class to the reference variable of base class then:

  • Using that reference variable you can access instance variables of base class having public, protected and package-private( Accessible only If in same package ) access modifiers in derived class. If want to access in non-derived class then only public, protected( Accessible only If in same package ) and package-private( Accessible only If in same package )
  • Using that reference variable you can access instance methods of base class having public, protected and package-private( Accessible only If in same package ) access modifiers in derived class. If want to access in non-derived class then only public, protected( Accessible only If in same package ) and package-private( Accessible only If in same package ).


  • When derived class defines an instance method having same signature with same access modifier and return type already defined in base class then that method is overriden by derived class.
    In that case when you create an object of derived class and assign it to the reference variable of base class (like you have in your example) and invokes that method on base class's reference variable then method of derived class gets called at run time. That is what polymorphism is all about.
  • In your example derived class Bird has sleep method which overrides method of base class Animal so

  • To clear all your doubts regarding polymorphism please click here -->How my Dog learned Polymorphism to read.
  •  
    Ganesh Patekar
    Bartender
    Posts: 1251
    87
    Hibernate jQuery Spring MySQL Database Tomcat Server Java
    • Likes 1
    • Mark post as helpful
    • send pies
      Number of slices to send:
      Optional 'thank-you' note:
    • Quote
    • Report post to moderator
  • You can see an example below in which base class Animal is in one package and derived class Bird is in another. You can try such different combinations so can understand very well.

  • Animal.java as base class:

    Bird.java as derived class:
    Output:
    An Bird protectedSleep...
    publicAnimalAge: 10
    protectedAnimalAge: 20
    An Bird publicSleep...
    An Bird protectedSleep...
    An Bird publicSleep...
    An animal animalSpecialMethod...
    An animal animalSpecialMethod...
     
    Sheriff
    Posts: 11604
    178
    Hibernate jQuery Eclipse IDE Spring MySQL Database AngularJS Tomcat Server Chrome Java
    • Likes 3
    • Mark post as helpful
    • send pies
      Number of slices to send:
      Optional 'thank-you' note:
    • Quote
    • Report post to moderator
    Hi Sukhitha sunil,

    First of all, a warm welcome to CodeRanch!

    Sukhitha sunil wrote:usually when we use ref variable of baseclass to access an obj of derived class, we only get d access to baseclass members ,,but when i run this code ani.sleep() gives he output of derived class bird method   ..please help me guys..to understand what is happening here


    There is a massive difference between "which methods can be accessed" and "which methods will be executed". The first is decided at compile time, the latter is decided at runtime.

    Let's have a look at a code snippetSo we first create two Bird instances/objects, one is referred by an Animal reference variable and the other is referred by a Bird reference variable. Now the compiler does its job and checks if every method invocation is allowed (and if all other code is valid too). The class Animal has a makeSound() method, so line1 compiles just fine. But there is no fly() method in class Animal, so you'll get a compiler error on line2. And just for the record: the compiler does not execute any code at all, so it only knows (and cares about) the type of the reference variable. The class Bird has a fly() method and inherits the makeSound() method from class Animal, so both line3 and line4 will compile successfully.

    Now let's have a look at a slightly adjusted code snippetFirst the compiler checks again if all code is valid (and thus if all method invocations are allowed). That's definitely the case! So now you can execute the Zoo class and you'll get the following output:
    I am an animal.
    I am a bird.
    I am a bird.

    So probably the first and third line of the output are pretty straightforward, but the second line looks a bit odd. Which method is executed is determined at runtime based on the type of the object the reference variable is referring to. And because the Animal reference variable is referring to a Bird instance/object and the Bird class has a makeSound() method (with exactly the same method signature) as well, the makeSound() method of the Bird class is executed (= polymorphism) and that's why "I am a bird." is printed.

    This results in two very simple (and hopefully easy to remember) but very, very, very important rules:
  • Which instance variables you can access is determined at compile time based on the reference variable type.
  • Which instance methods you can call/invoke is determined at compile time based on the reference variable type. Which instance method is actually executed is decided at runtime based on the type of the actual object (= polymorphism).


  • And here is another very, very, very important rule: The compiler doesn't execute any code! So every compiler error you get, is because the compiler knows something is wrong without executing any line of code. So the compiler doesn't know and care) about the actual objects, the compiler only knows about the types of the reference variables.

    Which methods can be accessed depends on the access modifier of the class, the access modifier of the method and the package in which the classes reside. In this topic you'll find a very detailed explanation about how changing an access modifier can result in a completely different output. Definitely worth reading! In fact, it's actually a must read

    Hope it helps!
    Kind regards,
    Roel
     
    Roel De Nijs
    Sheriff
    Posts: 11604
    178
    Hibernate jQuery Eclipse IDE Spring MySQL Database AngularJS Tomcat Server Chrome Java
    • Likes 3
    • Mark post as helpful
    • send pies
      Number of slices to send:
      Optional 'thank-you' note:
    • Quote
    • Report post to moderator

    Ganesh Patekar wrote:When derived class defines an instance method having same signature with same access modifier and return type already defined in base class then that method is overriden by derived class.


    That's an incorrect statement! You should definitely review the rules for a valid override: the method signature has to be exactly the same, but access modifier and return type does not need to be the same.

    In this code snippet you'll have a valid override although the access modifier is different. For a valid override, the access modifier for an overriding method can allow more, but not less, access than the overridden methodAnd here is another code snippet with a valid override although the return type is different. The return type of the overriding method can be a subclass of the return type of the overridden method (= covariant return type)

    Hope it helps!
    Kind regards,
    Roel
     
    Bartender
    Posts: 10780
    71
    Hibernate Eclipse IDE Ubuntu
    • Likes 1
    • Mark post as helpful
    • send pies
      Number of slices to send:
      Optional 'thank-you' note:
    • Quote
    • Report post to moderator

    Sukhitha sunil wrote:usually when we use ref variable of baseclass to access an obj of derived class, we only get d access to baseclass members


    So, does Animal have a sleep() method? Yes - and furthermore, it's public, so ani.sleep() is a perfectly valid call. Anywhere.

    but when i run this code ani.sleep() gives he output of derived class bird method


    I think Roel and Genesh have already covered that bit; but just in case you've come from a C or C++ background, the way it was explained to me was that
      All instance methods in Java are "virtual" by default.

    Which is another way of saying precisely what

    Roel wrote:There is a massive difference between "which methods can be accessed" and "which methods will be executed". The first is decided at compile time, the latter is decided at runtime.


    HIH

    Winston
     
    Enthuware Software Support
    Posts: 4810
    52
    • Likes 1
    • Mark post as helpful
    • send pies
      Number of slices to send:
      Optional 'thank-you' note:
    • Quote
    • Report post to moderator

    Winston Gutkowski wrote:All instance methods in Java are "virtual" by default.


    Minor correction - All instance methods in Java are "virtual", period.
    You can't change this behavior so there is no "by default".
    Final methods cannot be overridden so this concept is not relevant for them anyway.
     
    Ganesh Patekar
    Bartender
    Posts: 1251
    87
    Hibernate jQuery Spring MySQL Database Tomcat Server Java
    • Mark post as helpful
    • send pies
      Number of slices to send:
      Optional 'thank-you' note:
    • Quote
    • Report post to moderator

    Roel De Nijs wrote:For a valid override, the access modifier for an overriding method can allow more, but not less, access than the overridden method.


    Damn! I tried combinations of override method with lesser modifier only.

    The return type of the overriding method can be a subclass of the return type of the overridden method (= covariant return type)

    I really had no notion about covariant return type, new thing learned. That link was much much helpful and mostly the explanation of last post of your's was in detail, learned a lot.
    You were just awesome Roel

    Edited: I adore the way you test whether somebody really understood or not by your famous pop quizzes hahaha just great
     
    Sukhitha sunil
    Greenhorn
    Posts: 6
    • Mark post as helpful
    • send pies
      Number of slices to send:
      Optional 'thank-you' note:
    • Quote
    • Report post to moderator
    thank you so much everyone.. every reply for my post helped me to get not only the actual idea but also more than it.. as a newbie i didn't expect it this much response
     
    Roel De Nijs
    Sheriff
    Posts: 11604
    178
    Hibernate jQuery Eclipse IDE Spring MySQL Database AngularJS Tomcat Server Chrome Java
    • Mark post as helpful
    • send pies
      Number of slices to send:
      Optional 'thank-you' note:
    • Quote
    • Report post to moderator

    Sukhitha sunil wrote:as a newbie i didn't expect it this much response


    As the moose tells you, CodeRanch is a friendly place for programming greenhorns, so we are glad to help you
     
    Roel De Nijs
    Sheriff
    Posts: 11604
    178
    Hibernate jQuery Eclipse IDE Spring MySQL Database AngularJS Tomcat Server Chrome Java
    • Likes 2
    • Mark post as helpful
    • send pies
      Number of slices to send:
      Optional 'thank-you' note:
    • Quote
    • Report post to moderator

    Ganesh Patekar wrote:Edited: I adore the way you test whether somebody really understood or not by your famous pop quizzes hahaha just great


    Thanks for these kind words. Highly appreciated! Glad to read you like those questions and I can easily create another pop quiz question here too

    What's the output of the following code snippet?
     
    Ganesh Patekar
    Bartender
    Posts: 1251
    87
    Hibernate jQuery Spring MySQL Database Tomcat Server Java
    • Likes 1
    • Mark post as helpful
    • send pies
      Number of slices to send:
      Optional 'thank-you' note:
    • Quote
    • Report post to moderator
  • Here a1 refers to an object of Animal and tries to invoke makeSound method of Animal which is private so not accessible outside of class so will give CE.

  • Here a2 is reference variable of Animal which refers to an object of Bird and tries to invoke makeSound method of Animal, why not makeSound method of Bird? because makeSound method of Animal is private, and private methods are not inherited by subclass i.e. Bird so as we have a2 as reference variable of Animal It tries to invoke makeSound method of Animal which is private so gives CE.

  • Because of above two CE, will not get executed. If you remove above to calls then It will invoke makeSound method of Bird because that method has public access modifier so accessible.

  • Now ugly truth, I didn't even notice we are invoking a private makeSound() method of Animal from Zoo means ouside of Animal class and decided makeSound method of Animal will get called. That came in my notice when I copied code in eclipse. It is not like I don't know private methods are not accessible outside of the class where It is declared. I know that but my problem which I always suffer from, I do silly mistakes like If you ask me to do (1*3/6-3+12+1) then I will do mistake like I'll miss to add last 1 in calculation. I think I lack observation Or may be because of trying to solve problem hurriedly. If you have time, love to have one more
     
    We cannot change unless we survive, but we will not survive unless we change. Evolving tiny ad:
    a bit of art, as a gift, the permaculture playing cards
    https://gardener-gift.com
    reply
      Bookmark Topic Watch Topic
    • New Topic