Home | Contact Us | FAQ | Search & Site Map | Link to Us
Sign In | Join | Other 45 Sites in Network
HomeAnnouncementsWhite Papers
Discussion GroupsFirst AidDatabasesJavaBeansGUIJava 3DVirtual MachineCORBASecurityToolsGeneral
Java DirectoryOpen Source ProjectsSample Book ChaptersUser GroupsWeb Resources
Related Topics
Databases.NETMore Topics ...

Java Forum / First Aid / January 2006

Tip: Looking for answers? Try searching our database.

probably a very common inheritance problem

Thread view: 
Oliver - 08 Jan 2006 13:24 GMT
Hello, I'm having a problem accessing the right member variables :)

public class Animal { static int type; }
public class Cat extends Animal { static int type = 1; }

This works, Animal.type and Cat.type refer to two different things. In
practice Animal.type would never be referenced. The reason it is
defined at all is so the code compiles, because also in class animal,
is the show method.

public class Animal {
 static int type;

 public void show()
 {
   System.out.println(type);
 }
}

So here is the problem, Cat.type is equal to 1, but Cat.show() prints
0.

Explained anorther way - class Cat contains a static array filled with
different kinds of cats. And the show function in Animal picks one type
of animal at random from the static array "animals" array. class Cat
overrides the animals array with it's own list, but does not override
show(). Unfortunately Cat.show() doesen't come up with a list of Cats,
it comes up empty because it's accessing Animal.animals[], not
Cat.animals[].

I don't know how to make it do what I want. I want Cat.show() to print
0. But I don't want to *cut and paste* code from the superclass to the
subclass. Anyone can cut and paste, but isn't that what inheritance is
supposed to aviod? Cutting and pasting?

Simply overriding show in every kind of animal class to set type and
then call super.show() is still cutting and pasting, and just feels
like I'm doing something wrong.

original reasoning:
"Newly declared fields can hide fields declared in a superclass or
superinterface. Newly declared class members and interface members can
hide class or interface members declared in a superclass or
superinterface. Newly declared methods can hide, implement, or override
methods declared in a superclass or superinterface."
(from
http://java.sun.com/docs/books/jls/second_edition/html/classes.doc.html)

Oliver
Michael - 09 Jan 2006 11:04 GMT
Inheritance - dynamic binding at runtime - does not work for static
variables or static methods.  If you remove the "static" modifier you will
see the behavior you expect.

Of course, you don't need a type variable (perhaps you included it just for
the sake of your example) because you can query the type of an object at
runtime using "instance of", e.g.,

if (myObject instanceof Animal) {
// do something
}

Note that even the above construct is not very desirable, as you should be
able to accomplish this sort of logic directly through inheritance and
method overloading, which is the preferred approach.

Mike
www.mammothsoftware.com
"Build Swing Applications in 5 Minutes"

> Hello, I'm having a problem accessing the right member variables :)
>
[quoted text clipped - 45 lines]
>
> Oliver
Torkel Franzen - 09 Jan 2006 11:30 GMT
> Inheritance - dynamic binding at runtime - does not work for static
> variables or static methods.  If you remove the "static" modifier you will
> see the behavior you expect.

 No, there is no dynamic binding with instance variables.
Michael - 10 Jan 2006 09:56 GMT
Oops, yes of course.  But the static modifier is the basic issue here -
getters/setters should also be used for dynamic binding.

Michael
www.mammothsoftware.com
"Build Swing Applications in 5 minutes"

>> Inheritance - dynamic binding at runtime - does not work for static
>> variables or static methods.  If you remove the "static" modifier you
>> will
>> see the behavior you expect.
>
>  No, there is no dynamic binding with instance variables.
Kent Paul Dolan - 10 Jan 2006 15:08 GMT
>> Inheritance - dynamic binding at runtime - does not work for static
>> variables or static methods.  If you remove the "static" modifier you will
>> see the behavior you expect.

>   No, there is no dynamic binding with instance variables.

No, but implicitly, the OP's code compiled, so is
it then okay to reuse an instance variable name in
a subclass?  I'd guess, if so, that the subclass
and superclass _each_ have an instance of the same
named variable, but that there is an issue of the
subclass's version _hiding_ the superclass's version,
and vice versa. Then show(), being a superclass
routine, would see only the superclass version of
the instance, and since cat.show() is executing the
superclass's show(), not having overridden it, it is
doing so in the superclass's environment, where type
is zero.

Is that just me being confused, or is that somewhat
close to reality?

xanthian.
Torkel Franzen - 10 Jan 2006 16:31 GMT
> Then show(), being a superclass
> routine, would see only the superclass version of
> the instance, and since cat.show() is executing the
> superclass's show(), not having overridden it, it is
> doing so in the superclass's environment, where type
> is zero.

 Right, so if we don't want to override show in every subclass, it's
not a good idea to hide the declaration of type.  It makes good sense
that every animal has a type, which tells what kind of animal it is,
so we just let every subclass inherit that variable, and give it a
suitable value in the constructor for each subclass.
Torkel Franzen - 11 Jan 2006 08:18 GMT
> No, but implicitly, the OP's code compiled, so is
> it then okay to reuse an instance variable name in
[quoted text clipped - 8 lines]
> doing so in the superclass's environment, where type
> is zero.

 Right. Instead of my earlier nonsensical (and canceled) suggestions,
I would suggest the following. It is perfectly reasonable to have a
field in the class Animal saying which kind of animal it is. But if we
also think different kinds of animals sufficiently different to warrant
introducing corresponding subclasses, we will need to both override
show in those classes and to give the inherited field its proper value
in constructors. I can't think of any good reason for hiding the
declaration of the field in the subclasses. The class Animal should
be made abstract if its show method will never be used anyway.

 The OP reflected that it shouldn't be necessary to override show,
since the method is intended to do exactly the same thing in Animal
and in all its subclasses - let an animal say which kind of animal
it is. But given that there is no dynamic binding of fields, it has
to be done this way.
Ricky Clarkson - 13 Jan 2006 01:11 GMT
Seems simpler without subclassing:

interface Animal
{
  int getType();
}

final class Cat implements Animal
{
  public int getType()
  {
     return 1;
  }
}

final class AnimalShower
{
  public static void show(final Animal animal)
  {
     System.out.println(animal.getType());
  }
}


Free Magazines

Get these publications absolutely FREE for up to 12 months. There are no hidden fees and no obligation. Simply choose a title, complete the application form and submit it. Read more ...

Oracle MagazineNetwork ComputingComputer WorldBio-IT WorldeWeekInformation WeekInfosecurity
 
Sign In
Join
My Latest Posts
My Monitored Threads
My Blog
My Photo Gallery
My Profile
My Homepage

Start New Thread
Enable EMail Alerts
Rate this Thread



©2008 Advenet LLC   Privacy Policy - Terms of Use
This website includes both content owned or controlled by Advenet as well as content owned or controlled by third parties.