Here are two classes,
class A
{
}
class B extends A
{
}
and A is inherited from B.What confuses me is that How many objects were created when I use the following code
A a = new B();
I know when I create an instance of B ,it will first call A's constructor and then call the constructor of B's.
Was there an instance of A been created when call A's constructor?
How many objects were created in
A a = new B();
It creates a single object, which is an instance of B. It's already a B when the A constructor executes, as you'll see if you change your code to:
class A {
public A() {
System.out.println(getClass());
}
}
class B extends A {
}
...
A a = new B(); // Prints B in the A constructor
Basically, the constructor isn't what creates an object - it's what initializes an object in the context of that class.
So you can think of the steps as:
Create object of type B
Initialize the object in the context of A (field initializers, constructor body)
Initialize the object in the context of B (field initializers, constructor body)
(with constructor chaining up the inheritance tree evaluating constructor arguments, of course... while the constructors are sort-of called going up the chain too, as the first part of any constructor has to chain to the same class or a superclass, the main part of the constructor body happens top-down).
For rather more detail about exactly what happens, see JLS 15.9.4 and JLS 12.5.
One object is created, which is a B object, which has both the aspects defined by A and the aspects defined by B. Since it incorporates all of the aspects defined by both of them, it's instanceof both A and B.
...and A is inherited from B
A is inherited by B, not from it. (The little words are the hardest in a non-native language.) B inherits from A. Some usual terms around this: "B derives from A", "B is derived from A", "A is a superclass of B", "B is a subclass of A".
Was there an instance of A been created when call A's constructor?
Despite their name, constructors don't create objects; they initialize them; and this question is why: Sometimes to correctly initialize the object, you have to call multiple constructors (one for each level in the object's inheritance hierarchy). In new B(), the JVM creates the object, then calls B with this set to that new, blank object so B can initialize it. The first thing B does is call A to let it initialize the A aspects of the object, then B initializes the B aspects of the object. E.g.:
JVM creates object.
JVM calls B
B calls A
A initializes the aspects of the object it's responsible for and returns
B initializes the aspects of the object it's responsible for and returns
Only one instance of B is created.
Constructors can be called up the chain, but each call only acts on the single instance that you're creating.
As those above me already said: Only one object is created. To clarify this you might think of the three parts of the statement you just wrote down:
A a = new B(). These are the part of declaration A a, the part of instantiation new and the part of initialization B().
If you want to read up on this topic (because perhaps not everything got clear to you), consider visiting https://docs.oracle.com/javase/tutorial/java/javaOO/objectcreation.html
Related
Why can't I do this/is there a workaround to accomplish this:
package myPackage;
public class A {
public class B {
}
}
package myPackage;
import myPackage.A.B;
public class C extends B {
}
package myPackage;
public class Main {
public static void main(String[] args) {
A myA = new A();
C myC = myA.new C();
}
}
The two compilation errors are
On public class C extends B, No enclosing instance of type A is available due to some intermediate constructor invocation
On C myC = myA.new C();, A.C cannot be resolved to a type
Frankly, I think the conceptual idea is sound: I want to make a subclass of B so that when I make a B for A, I have the option of making it have the functionality in B or the functionality in C.
Four workarounds/solutions that I don't want, and why I don't want them:
"Solution: Put C inside of A." I don't want this because what if I can't modify the code for A.java (there are applications that have this restriction)? What if A is part of another API? Then I have to create a new file for C, as I've done here.
"Solution: Put C inside of a class D that extends A." I don't want this because then C is restricted to only being instantiated on instances of type D. I want to make a class that extends B that can be instantiated on all instances of type A (there are applications that need this). Therefore, I need C to not be enclosed by another class, as I've done here.
(Added as a question edit - see JoshuaTaylor's answer for a code sample) "Solution: Make B static." I don't want this because what if functionality in B needs to access its enclosing instance of A (there are applications that need this)? Therefore, I need B to not be static, as I've done here. (2nd question edit: You could make B static and have its constructor take in its enclosing instance, saving it in a protected variable for access in its children, but this is less elegant than the accepted answer by RealSkeptic)
Removed. See edit at bottom.
So, if your answer suggests that I do one of the above, it is not an answer to this question, even though it might be useful for other people.
If your answer is "This is just a flaw of the Java language, you simply can't accomplish that conceptual idea", that is an okay answer, and you should post it. Just a warning though: I will hold off on marking your answer as accepted in case you are wrong. If this is your answer, I would highly appreciate if you have an explanation for why this restriction on the language is in place (as that's the title of this question).
Thank you for any and all help.
EDIT: JoshuaTaylor's answer brings up a valid option: you can extend B anonymously and avoid having to write a constructor as in RealSkeptic's accepted answer. I originally discarded this idea because it does not allow you to access C's enclosing instance of A via "A.this". However, I have since learned that C does not have an enclosing instance of A unless it is specifically defined within the definition of A as a nested class. So please note: none of the solutions below allow you to access the enclosing instance of A that encloses C's ancestor of B via writing "A.this" in a method of C. Classes can only use ".this" to access types which they are specifically nested in. However, if B has functionality that accesses the enclosing instance of A, either an anonymous class via JoshuaTaylor's method or any other class via RealSkeptic's method is required.
Well, it can be done, but you have to remember that each constructor needs to call its super constructor, explicitly or implicitly. That's why you get the "No enclosing instance of type A is available due to some intermediate constructor invocation" error. C's no-args constructor is trying to implicitly call B's no-args constructor, and it can't do that without an A.
So you fix your C to be:
public class C extends B {
public C(A enclosing) {
enclosing.super();
}
}
And then you can create a new C by using:
A myA = new A();
C myC = new C(myA);
Answers to the questions in the comments
#Andi Turner asked:
If you are explicitly passing in an A to the constructor of C, can't C now be static, and have A as a "plain old" member variable in C on which you invoke the required methods?
It should be noted that C is neither static nor an inner class. It is an individual public class which is extending an inner class B. The implementation of the class B may not be known to the author of C, so it cannot know what methods would be using A, nor does it have access to any private members of A, as C is not a member of A. But B does, and B requires the A instance. An alternative approach would be composition rather than inheritance (where C holds a B instance and delegates operations to it), but if it wants to create that B instance rather than have it passed inside, it will still need an A instance, although it will use enclosing.new B rather than enclosing.super.
#rajuGT asked:
Is C is an individual entity? if so, why does it need A object? and what is the association between myA and myC in this case?
Yes, C is an individual entity. It wouldn't need A for any of its own methods. But if it tries to call (or inherits and doesn't override) methods from B that involve access to A - then that A is required by the implementation of B. Formally, of course, any instance of B requires a reference to A even if it doesn't actually make use of it. The association between myA and myC are is that myA is the immediate enclosing instance of myC with respect to B. This term is taken from section 8.1.3 of the JLS:
For every superclass S of C which is itself a direct inner class of a class or interface SO, there is an instance of SO associated with i, known as the immediately enclosing instance of i with respect to S. The immediately enclosing instance of an object with respect to its class' direct superclass, if any, is determined when the superclass constructor is invoked via an explicit constructor invocation statement (§8.8.7.1)
Official reference for this usage
This usage is known as a qualified superclass constructor invocation statement, and is mentioned in the JLS, section 8.8.7.1 - Explicit Constructor Invocations.
Superclass constructor invocations begin with either the keyword super
(possibly prefaced with explicit type arguments) or a Primary
expression or an ExpressionName. They are used to invoke a constructor
of the direct superclass. They are further divided:
Unqualified superclass constructor invocations begin with the
keyword super (possibly prefaced with explicit type arguments).
Qualified superclass constructor invocations begin with a Primary
expression or an ExpressionName. They allow a subclass constructor to
explicitly specify the newly created object's immediately enclosing
instance with respect to the direct superclass
(§8.1.3).
This may be necessary when the superclass is an inner class.
At the end of that section, you can find examples for explicit constructor invocation statements, including this usage.
You can easily extend nested static classes
Update: You've mentioned that you don't want this first solution, but the phrasing of the question may lead people to it who are willing to have the inner class be static, so I'll leave this in the hopes that it's useful to them. A more proper answer to your exact question is in the second section of this answer.
You can, but the inner class has to be static, because if it's not, then every instance of the inner class has a reference to the enclosing instance of the outer class. A static nested class doesn't have that reference, and you can extend it freely.
public class Outer {
public static class Inner {
}
}
public class InnerExtension extends Outer.Inner {
}
But you can also extend nested non-static classes
package test;
public class Outer {
public class Inner {
public String getFoo() {
return "original foo";
}
}
}
package test;
public class Extender {
public static void main(String[] args) {
// An instance of outer to work with
Outer outer = new Outer();
// An instance of Outer.Inner
Outer.Inner inner = outer.new Inner();
// An instance of an anonymous *subclass* of Outer.Inner
Outer.Inner innerExt = outer.new Inner() {
#Override
public String getFoo() {
return "subclass foo";
}
};
System.out.println("inner's class: "+inner.getClass());
System.out.println("inner's foo: "+inner.getFoo());
System.out.println();
System.out.println("innerExt's class: "+innerExt.getClass());
System.out.println("innerExt's foo: "+innerExt.getFoo());
}
}
inner's class: class test.Outer$Inner
inner's foo: original foo
innerExt's class: class test.Extender$1
innerExt's foo: subclass foo
According to the definitions of constructors they don't have any return types,but while creating object we often do A a = new A(); which is responsible for creating the object a.
A a=new A();
Can anyone help me understanding the issue,what is actually happening in the case of constructors while creation of Object.
Constructors don't have return types, correct. But the expression new A() does have a result: A reference to the newly-created object.
Here's what happens with new A():
An object is created
It's given the type A
The relevant A constructor is called with this referring to that new object
Once initialization is done, the expression completes
The result of the expression is the reference to the new object
This process is described in this tutorial on the Oracle Java site.
In many ways, it would be more accurate to call constructors initializers: The construction happens because of the new operator, not the constructor.
The fact that constructors don't actually do the construction is made particularly clear when an object is processed by multiple constructors, as is very common. Consider:
List<String> m = new LinkedList<String>();
One object is created (ignoring any fields the list may need to initialize), but five different constructors get called to initialize that one object, because LinkedList<E> subclasses java.util.AbstractSequentialList<E> which subclasses java.util.AbstractList<E> which subclasses java.util.AbstractCollection<E> which subclasses java.lang.Object, and each of those classes has to get its chance to initialize its part of the object that was created. So in order:
JVM creates the object
Object() is called to initialize Object stuff
AbstractCollection() is called to initialize its stuff
Then AbstractList()
Then AbstractSequentialList()
Then LinkedList()
And then finally the resulting (one) object's reference becomes the result of the new expression
One object, but five constructors required to initialize it. :-)
Constructors need not to return anything. They just constructs the current instance. That's all their job, part of object creation.
Creating objects:
A a = new A();
Declaration: The code set in bold are all variable declarations that associate a variable name with an object type.
Instantiation: The new keyword is a Java operator that creates the object.
Initialization: The new operator is followed by a call to a constructor, which initializes the new object.
Constructor declarations look like method declarations—except
that they use the name of the class and have no return type - from
the java constructor docs
To understand the constructor, it is similarly important to understand how it differs from a method.
Constructors have one purpose in life: to initialize the new object and it's fields. Nothing more. The new keyword handles the creation of memory space.
You shouldn't consider new A() to be a call to the constructor, because there are more things that happen, than just the constructor running. The major steps, when you run new A() are these.
A chunk of memory is set aside - just enough for storing an object of class A.
The constructor is run.
A reference to the chunk of memory that was set aside is returned.
So the constructor itself isn't actually returning anything - and it's an error to have return this; or anything similar inside the constructor.
Return statement inside a constructor doesn't logically makes sense because the purpose of the constructor is to perform initialization. The object has not been created yet, the actual construction of the object happens in JVM.
I am trying to understand how inheritance is realized inside JVM. It seems to me, that if we have the following code:
class A {
int aa;
}
class B extends A{
int bb;
}
....
B b=new B();
Inside the JVM three objects will be created:
object of B (with field int bb),
object of A (with field int aa)
object of Object.
Of course the programmers see only one object of class B. Am I right? Or is only one object created inside JVM?
What I think:
The new returns the reference to B. Why I think so is (for example) that if we override some method from A in B we can always get it using super. Besides in default constructor B the first line will be call to default constructor A in which we can call the constructor on certain object ONLY IF this object exists. Therefore a separate A object exists?
At first, the spec says that the internal structure of objects is not specified, so in theory, a JVM could internally create more than one object, where B contains only fields new to B, and a link to an A object, which contains the fields of A.
It also says something about the Oracle JVM implementation: A class instance contains three pointers. One to a method table, one to some space in heap where the data of the instances fields is, and one the Class object that instance belongs to.
You can conclude from that, that there is only one instance per object created, namely the instance of B. The method table for this instance contains all methods from B, A and Object, as well as the heap space contains all data from fields from B, A (and Object).
Here only one object will create. it is B object. But B object has state and behaviors of A object. As super type of every class is Object class, B object has Object's state and behavior too. Thanks
Classes represent a type of objects, but only instances create real objects. So only one object is created and it corresponds the result merge of class B with class A.
I have a question about inheritance in Java.
I have two classes A and B , and class B, inherits from A:
public class A {
public A() {
System.out.println("Hi!");
}
}
public class B extends A {
public B() {
System.out.println("Bye!");
}
public static void main(String[] args) {
B b = new B();
}
}
When I run program B, the output is:
Hi!
Bye!
Question : why the constructor of class A is invoked, when I create and object of class B ?
I know that B inherits everything from A - all instance or class variables, and all methods, and in this sense an object of B has all characteristics of A plus some other characteristics defined in B. However, I didn't know and didn't imagine that when I create an object of type B, the constructor of A is also invoked.
So, writing this:
B b = new B();
creates Two objects - one of type B, and one of type A.
This is getting interesting,
can somebody explain why exactly this happens?
It doesn't create two objects, only one: B.
When inheriting from another class, you must call super() in your constructor. If you don't, the compiler will insert that call for you as you can plainly see.
The superclass constructors are called because otherwise the object would be left in an uninitialized state, possibly unbeknownst to the developer of the subclass.
Your subclass actually looks like this after the compiler inserts the super call:
public class B extends A {
public B() {
super();
System.out.println("Bye!");
}
}
It doesn't create 2 objects, it only creates one instance of B. The reason the super class constructor is invoked is because, like you said, B has all of the fields of A, and these fields need to be initialized.
Remember inheritance is an "is a" relationship between the base class and the subclass, thus every time you have an instance of a subclass, by definition you will also have an instance of the base class (as part of the instance, not as two separate instances). To initialize the base class properly the constructor is called.
Additionally, think about what would happen if you subclass depended on some internal state of the base class. Wouldn't you want the instance of the base class to be initialized then?
This is done because the constructor is used to initialize the object. Since B is also an A, it calls the constructor for A first, then the constructor for B.
As a side note, you can use super(arg1, etc) to choose which constructor of A is called based on the parameter types you pass... but it must be the first line in the constructor.
The constructor contains all of the initialization for A. You are not creating two objects. You are creating one object, then running the initializer for the superclass to initialize its members, and then running the initializer for the deriving class to initialize its members.
It does not create two objects, it just creates one object b. b is of type B and of type A. A constructor is basically saying here is what you need to do to construct me. So when you are creating a new "B" instance, you are building an object that is both a B() and an A(). Imagine the following scenario:
class Q {
int i;
public Q() {
// set default value
i= 99;
}
}
class Z extends Q {
public Z() {
}
}
If the constructor for Q WAS NOT called, how would i get its default value?
The creation of B does not create an extra A.
But by creating B, you create a kind of A, because B is a A.
Java/C++ call the constructor of A for your implicitly. Why? Language design. But doing so is fine, because the constructor of A might contain some initializations. And as B uses all the features and bugs of A, these features better be initialized properly.
The constructor of a class is very important concept in most OOP
Classes, by providing state and the means to manipulate that state, allow the easier maintenance of invariants. The constructors role is to get the class into a state that conforms to those invariants (or throws thus forbidding usage of an invliad object).
this is somewhat looser than intended in many languages since the constructor is allowed to pass its own 'this' reference elsewhere but this is at least under the control of the class (as such it can know that it is in a sufficiently stable and valid state for it to be accessible to the rest of the world)
Inheritance makes this complex since B is-a A in a very real sense and thus can invoke any of the methods provided by A. The parts of B that are A should therefore get their chance to initialize themselves before B gets a look in, thus the constructor for A is called before the real work of the B constructor begins.
If A intializes members in it's constructor and you forget to call super in your derived class then the members of A could be in a bad state. Java is trying to stop you from shooting yourself in the foot.
Only one object is created, both contractors are running on the same object.
The reason is simple, as you know B has all the variables and methods of A, so if some variable of A needs initializing so methods of A can work someone has to initialize it - and that someone is A's constructor.
for example:
public class A {
public A() {
x = 1;
}
private int x;
public int getX() {
return x;
}
}
public class B extends A {
public B() {
}
public static void main(String[] args) {
B b = new B();
System.out.println(b.getX()); // should print 1
}
}
When new object is create(B), inside B A object is created(because of extends keywords) . In B class JVM search B class constructor, but due to extends keywords it goes to super class constructor. inside A class x value is initialized. But x is private so that we can access outside class throw getXxx() method and get the result.
When sub class object is created then internally it was not created for super class object.But the memory should be allocated for super class members.
In java when you create an object of child class the constructor of parent class is always called because Object class is the parent of every super class and when you call the constructor of Object class then only your object is created and java does not support multiple inheritance in case of class so if you extends any other class then the relationship between you child class and the Object class is through the Parent class so to call the constructor of the Object class the constructor of Parent class must be called.
Every superclass has a constructor and each constructor up the hierarchy runs at the time an object of a subclass is created.
if super class object is not created then how sub class is accessing super class non static methods and variables.
I studied that non-static methods and variables can be accessed only through objects..
In a nutshell, how and why is this possible:
Object obj=new MyClass();
Object is the superclass of all objects, therefore MyClass is a child class of Object. In general, in Java, Why is it possible to use the constructor of a child class in the parent class?
I understand how it could go the other way around, since the child has all the variables/methods of the parent class, so when you initialize them you are just initializing the variables specified in the parent constructor, that exist by definition in the child. The problem is, when you go the other way around, it is not necessarily true. A child can have variables the parent doesn't, so how is it possible to use the child constructor with the parent, when the parent does not even have the variables in the first place?
What uses does this feature have in development? I would think that if you want an instance of class B, you would declare it as B thing=new B(), and not A thing=new B(). This is probably my inexperience talking, so I would appreciate enlightenment on why and how a parent class can be initialized as one of its children.
Why is it possible to use the constructor of a child class in the
parent class?
This is not correct. When you do
Object obj = new MyClass();
Object obj; declares a reference of the type Object
and new MyClass(); returns a reference to the object it created.
So, you are instantiating a MyClass and assigning the reference to the object created to a reference of the type Object, and this is possible because MyClass is an Object.
As you say,
A child can have variables the parent doesn't
That's called extending the parent functionality (inheritance).
For your second question think about the classic Animal example: Suppose you create a Animal class and you create a method makeSound() on it.
Now you create two subclasses of Animal, Dog and Cat, that overrides the makeSound()method of Animal (a Dog barks and a Cat meows).
Imagine that you represent a room full of Animals (Dogs and Cats) using a List, and you want to make all of them makeSound(). Your list will be declared as List<Animal> because you don't know the kind of Animals that you will store.
And then you iterate over the List to call makeSound() for each Animal. It doesn't matter if the Animal is a Dogor a Cat, it will make it's sound.
And then imagine you want to add Birds to the List. Easy, isn't it?
You are thinking in terms of C++ semantics, but this is Java. In Java, all non-primitive type variables are references, not instances.
In C++, when you say
Object obj;
you allocate a new Object instance on stack or in static memory.
When you say
Object obj = new MyObject;
you invoke a constructor of Object class that takes MyObject pointer (or may be something else that MyObject can be converted to).
In Java,
Object obj;
does not create any instances of Object. It simply creates a variable that can have a reference to an Object instance, but at the moment does not refer to any. It is initialized to null.
Object obj = new MyObject();
allocates an instance of MyObject. It does not allocate a new instance of Object. It simply sets the variable to refer to the new instance. In C++ terms this is much more similar to
Object *obj = new MyObject();
So we're not constructing a parent instance from child instance. We're changing a value the variable is set to, from null to a new child instance.
First, you must get a clear understanding of things. Your example expression:
Object obj = new MyClass(); is actually a compound of two elementary operations.
The first one is creating an instance of MyClass: new MyClass(). The new keyword is basically the only way of actually obtaining an instance of a class (lets ignore runtime reflection to keep this simple), and you are literally naming what you want to create (MyClass) here by its constructor. There is no way to create anything other than what you literally named with the new keyword. The result of new is (implicitly) an instance of MyClass, but the explicit result of a new X is a reference of type X (the reference referring to the newly created instance).
Now the second operation is assigning the reference to your (new) MyObject to another reference of type Object. And this is valid because MyObject is an Object (due to inheritance).
Why would you need this?
This is an essential feature to actually make use of polymorphism. The ability to refer to any child class as its superclass is what makes polymorphism so powerful. You basically will use it everywhere where there is an aspect common to two classes, but there are also differences.
A real world example would be graphical user interfaces. There are buttons, lists, tables and panels in a window, which are all user interface elements, but each does a different thing. To present them neatly organized in a window, these elements are often nested into panels, more abstractly said into containers. Now a container doesn't care what kind of elements go into it, as long as they are components. But to handle them properly a container does need some basic information about these components, mostly how much space they occupy and how to actually draw them. So this is modelled as something like:
public abstract class Component {
public int getWidth() { ... }
public int getHeight() { ... }
public void paint(Graphics g) { ... }
}
public class Container extends Component {
public void add(Component child) { ... }
public void paint(Graphics g) {
for (Component child : children) {
child.paint(g);
}
}
}
Thats almost straight lifted out of the JDK, the point is, if you needed to refer to each Component as its concrete type, it would be impractical to build a Container, it would need extra code for each Component you decide to make (e.g. there would be an addButton, addTable and so on). So instead, Container just works with reference to Component. No matter what Component is created (e.g. Button, CheckBox, RadioButton etc.), since Container just relies on them to all be Component's, it can handle them.
Every class in Java is descended from Object. So MyClass is an Object, by definition, but a more specialized version of it. Think of it like this: every living creature is an Animal. A Cat is a special kind of animal; a specific type. Since the Cat is an Animal, you can still just call it an Animal:
Animal a = new Cat();
But doing so, with a, you can't do anything specific to a Cat, like meow() or purr(), but you can call methods which are valid for all Animals, such as breathe().
HTH
class myMobile{
public void call{
System.out.println("Mobile");
}
}
public class mainClass{
public static void main(){
Object o=new myMobile();
//here we can call methods which are common to all
// objects not specific to
// myMobile object
}
}
Because a MyClass is a Object. Note that java is special because Object is the superclass of every other class type (there is no equivalent in C++).
A more interesting example would be if you had a class or interface and one or more subclasses. This comes up all the time in OOD. Consider for example java's jdbc API: a common set of interfaces to connect and query a database that can be implemented by different concrete classes. You only need to code to the API and then at runtime use the implementation for your DB of choice.
http://docs.oracle.com/javase/7/docs/api/java/lang/Object.html
Class Object is the root of the class hierarchy. Every class has Object as a superclass. All objects, including arrays, implement the methods of this class.
i.e. every Java class is an Object. This is why.
http://docs.oracle.com/javase/tutorial/java/IandI/subclasses.html
The Object class, defined in the java.lang package, defines and implements behavior common to all classes—including the ones that you write. In the Java platform, many classes derive directly from Object, other classes derive from some of those classes, and so on, forming a hierarchy of classes.
You have two separate things here:
The construction of a new instance
The assignment of that instance to
a variable
Since your instance of MyClass is also an instance of Object, this works well.
Consider the following, generic situation:
class A extends B implements C,D {
}
As your A is a B and also a C and a D and an Object, once you created an instance, you can (directly or indirectly) assign it to variables of all those types:
A a = new A();
B b = a;
C c = a;
D d = a;
Object o = a;
Your view on the fields or methods is limited by the type of the variable (i.E. as variable of type C, you only see the methods declared by C).
Nevertheless, your instance is always of the type you instanciated using the constructor, regardless of the variable type.