views:

131

answers:

6

If I have an abstract class in java named Foo and it has an implementor named Bar then I want to know the following.

lets say Foo looks something like

public abstract class Foo {

  Service serviceFoo

  ...

}

And Bar is

public class Bar extends Foo {
...
}

Also, lets assume I have an instance with Foo, named foo, currently that has serviceFoo instantiated

If I then declare:

Foo foo = new Bar();

will this create a a new instance of Bar that has serviceFoo instantiated or not? E.g. will that field be inherited and instantiated or just inherited?

+4  A: 

No, inheritance does not happen between instances; only between class definitions.

When you instantiate new Bar(), serviceFoo will be instantiated according to its declaration in Foo. In the current case, it has no instantiation in Foo, so it would be a null reference in the new instance of Bar.

Also, you should know that all non-primitives in Java are reference types. That is, foo is not a Foo, but a reference to a Foo. When you assign your new Bar() to foo, you are reassigning its reference to a new object entirely.

Edit: One more, minor nitpick - if you already have an instance of Foo named foo as you claim, then the line

Foo foo = new Bar();

would not compile as it is a redeclaration of foo.

danben
yeah, I meant foo = new Bar() sorry :p
stevebot
+1  A: 

No, serviceFoo won't be instantiated. The line

Foo foo = new Bar();

drops the reference to the "old" object referenced by foo and creates a brand new one. In particlar, it does not "convert" the old foo (of type Foo) into an object of type Bar.

Heinzi
+4  A: 

When you call new Bar();, the constructor for Foo is called implicitly. If Foo's constructor instantiates serviceFoo then so will Bar. If Foo relies on someone else to instantiate serviceFoo then Bar will do the same.

Existing instances of either Foo or Bar have no bearing on what goes on when a new instance is made. Only what code gets executed in the constructor (or what gets passed in as a parameter) has an impact on the new object.

Bill the Lizard
+1  A: 

When you say Foo foo = new Bar(), you are creating a brand new object. This means that Bar is created from scratch and any instance variables are also initialized. If it inherits from a super class, like Foo, then those inherited variables are also initialized.

There is no way the parameterless constructor Bar() can know about an outside Service serviceFoo and somehow set it to that value.

If you want to do that, you need to pass in the reference to serviceFoo in the constructor.

Foo foo1 = new Bar();
foo1.serviceFoo = new Service();
// do something with that serviceFoo

Foo foo2 = new Bar(foo1.serviceFoo);  // make sure you define this constructor
Phil
+1  A: 

Since serviceFoo is an instance variable (i.e. it's not declared static) any existing instances of Foo that have set this field will not have any effect on any new instances you create.

Assuming Bar doesn't set it, all you'll get is the field inherited and not instantiated with the new instance.

Paolo
+1  A: 

If you change your base class' code to

public abstract class Foo {

    Service serviceFoo = new Service(...);
    ......
}

Then bar will have an instance of Service when bar is instantiated.

wsxedc