What lines should be uncommented and why, inheritance - java

I have a code-snippet, and I should determine what line I should un-comment so it will compile.
Question: Why only lines 9,13 and 10,14 works? Why wont 9,14 work for example? I'm a bit confused. help is highly appreciated! (Btw, the options are only un-commenting two lines of code)
1. // Question 3.1
2. class Car {
3. private Car() { }
4. protected Car(int x) { }
5. }
6. public class MG extends Car {
7. // MG(int x) { }
8. // MG(int x) { super(); }
9. // MG(int x) { super(x); }
10. // private MG(int x) { super(x); }
11. // MG() { }
12. // MG() { this(); }
13. // MG() { this(6); }
14. // MG() { super(7); }
15. public static void main(String[] args) {
16. new MG(7);
17. new MG();
18. } }
I believe the lack of understand comes from not enough familiarity of private constructor and protected access modifier, so I'm reading on that and I will also continue trying figuring it out.
Edit: Well I almost got it now, first of all line 8 cant be called so options with 8 and 11-14 are gone. line 7 - why can't it be called for e.g. with line 11? I believe MG(){} will be called but first the private car() has to be called, error. with line 12 not possible, because than I need line 11, with line 13 no idea why, with line 14 no idea why..

I wrote it on Ideone, because i was pretty sure that line 9 and 14 should work and they do!
Check it here (code)
The only important thing to remember in this example is, that if you do not invoke parent constructor, Java will invoke it in that manner "super()". Since your parent class non-parameter constructor is private, it won't compile.
That's why lines 7,8,11 are plain wrong.

Inheritance
Subclass by default get the access of all parent class methods, variables, constructor.
When you are going to create object of child class then (jvm calls zero parameter constructor implicitly)first parent class constructor executed and then child class constructor.
In your case you are calling super class constructor explicitly.
Use print statement in constructor you will get clear idea ...

First of all Few things to notice:
First get some idea about access modifiers:
About private constructor:
prevent subclassing (extending). If you make only a private constructor(only have one constructor), no class can extend your class, because it can't call the super() constructor. read more
And little bit about constructor:
Constructors are never inherited - they are specific to the class in
which they are defined.
If no constructor implemented, default constructor will added by the
compiler implicitly.
In subclasses did not call the super() compiler automatically add those to all the constructors.
When a new object that is a subclass is constructed, the constructor
for the superclass is always called first.
Constructor invocation maybe implicit or explicit.
explicit call to a constructor of superclass: super() - has to be the first statement in the subclass constructor.
Without any constructor in MG:
In this line public class MG extends Car { eclipse show error:
Implicit super constructor Car() is not visible for default
constructor. Must define an explicit constructor.
Because of inheritance you need to pass values to parent class constructor.
And for this new MG(7);:
The constructor MG(int) is undefined
Because you donot have any parameterized constructor in MG class.
UPDATE:
You said in your question you only want to know about line number 7, 11, 12, 13 and 14. But I will answer for all the lines. Then others who looking for answer also can understand
If you uncomment line number 7:
When we create an object of a child class always the constructor of the parent get completed and the constructor of the child runs later.
When you run the program, First in the main method new MG(7); object looking for matching constructor in the MG, which is MG(int x) {}. Inside this has super() which is compiler added one. Then compiler look for default constructor in parent class, It cannot find since default constructor is private.
To fix this: MG(int x) {super(x);}
If you uncomment line number 8:
When you run the program, First in the main method new MG(7); object looking for matching constructor in the MG, which is found.
MG(int x) {super()}
If you added super() or not compiler will add this. There is no different between these two:
MG(int x) {}
MG(int x) {super()}
If you uncomment line number 9:
This line is fine(no errors). First compiler looking for constructor(MG(int x) { super(x); } for object(new MG(7);). Then inside the constructor have called super(x) which is have one argument and it is match with the parent class constructor. As I mentioned before, parent class constructor execute first, Then child class constructor execute.
If you uncomment line number 10:
private MG(int x) { super(x); }
Access modifier is not affected because this class is a subclass and it is not a parent class for any class. And we can create object from calling private constructor. read more about private constructor.
If you uncomment line number 11:
MG() { }
It is match with the new MG(); object. Compiler have added super() but no matching constructor found in the parent class.
If you uncomment line number 12:
MG() { this(); }
First, lets look at what is this():
this can be used inside the Method or constructor of Class.
this works as a reference to the current Object whose Method or
constructor is being invoked.
The this keyword can be used to refer to any member of the current
object from within an instance Method or a constructor.
this() keyword can be used inside the constructor to call another
overloaded constructor in the same Class.
This is also called the Explicit Constructor Invocation.
And this() and super() both cannot use in one constructor.
So this line is unnecessary because you don't have any other MG() constructors. learn more about this.
If you uncomment line number 13:
MG() { this(6); }
This is also unnecessary or cannot be called unless you have another MG() constructor. If you do like this:
MG(){
this(6);
}
MG(int x){
super(x);
}
What happen here is when you run the program new MG(); object find the default constructor and in it call the parameterized constructor(MG(int x){}). Then in the this constructor take the value and send it to the parent class.
If you uncomment line number 14:
MG() { super(7); }
new MG(); is matched with the costructor and in it you have passed value 7 to the parent class parameterized constructor.
Done.

Related

How is a child object constructed in Java?

In java, how is a child object constructed?
I just started inheritance and these few points are not very clear to me:
Does the child object depend only on the child class' constructor, or does it also depend on the parent's constructor? I need some details about that point.
Also, is super() always called by default in a child constructor?
Any other information regarding this topic is appreciated.
I don't think "A child object" is a good way to think about this.
You're making an object. Like all objects, it is an instance of some specific class, (After all, new SomeInterface() does not compile) and like (almost) all objects, it is made because some code someplace (doesn't have to be your code, of course) ran the java expression new SomeSpecificClass(args); somewhere.
We could say it is a 'child object' because SomeSpecificClass is a child class of some other class.
But that's rather useless. That means the only way to ever make a new 'non-child' object would be to write new Object(); - after all, all classes except java.lang.Object are a child class: If you write public class Foo {}, java will interpret that exactly the same as if you had written public class Foo extends java.lang.Object {}, after all.
So, barring useless* irrelevancies, all objects are child objects, and therefore as a term, 'child object', I'd not use that.
That also means that ALL object creation goes through this 'okay and in what order and how do the constructors work' song and dance routine.
How it works is probably most easily explained by desugaring it all. Javac (the compiler) injects things if you choose to omit them, because a lot of things that feel optional (such as a constructor, a super call, or an extend clause), at the class file / JVM level, aren't**.
Sugar #1 - extends clause
Already covered: if you have no extends clause on your class def, javac injects extends java.lang.Object for you.
Sugar #2 - no super call in constructor
A constructor must either call some specific super constructor on its very first line, or, it it must call some other constructor from the same class on its very first line (this(arg1, arg2);). If you don't, java will inject it for you:
public MyClass(String arg) { this.arg = arg; }
// is treated as:
public MyClass(String arg) {
super();
this.arg = arg;
}
Notably including a compiler error if your parent class has no zero-arg constructor available.
Sugar #3: No constructor
If you write a class that has no constructor, then java makes one for you:
public YourClass() {}
It will be public, it will have no args, and it will have no code on it. However, as per sugar #2 rule, this then gets expanded even further, to:
public YourClass() {super();}
Field inits and code blocks get rewritten to a single block.
The constructor isn't the only thing that runs when you make new objects. Imagine this code:
public class Example {
private final long now = System.currentTimeMillis();
}
This code works; you can compile it. You can make new instances of Example, and the now field will hold the time as it was when you invoked new Example(). So how does that work? That feels a lot like constructor code, no?
Well, this is how it works: Go through the source file top to bottom and find every non-static initializing code you can find:
public class Example {
int x = foo(); // all non-constant initial values count
{
x = 10;
// this bizarre constructor is legal java, and also
// counts as an initializer.
}
}
and then move all that over to the one and only initializer that classes get, in the order you saw them.
Ordering
So, via sugar rules we have reduced ALL classes to adhere to the following rules:
ALL classes have a parent class.
ALL classes have at least 1 constructor.
ALL constructors invoke either another constructor or a constructor from parent.
There is one 'initializer' code block.
Now the only question is, in what order are things executed?
The answer is crazy. Hold on to your hats.
This is the order:
First, set all fields to 0/false/null of the entire 'construct' (the construct involves every field from Child all the way down to Object, of course).
Start with the actual constructor invoked on Child. Run it directly, which means, start with the first line, which neccessarily is either a this() or a super() invocation.
Evaluate the entire line, notably, evaluate all expressions passed as arguments. Even if those are themselves invocations of other methods. But, javac will do some minor effort to try to prevent you from accessing your fields (because those are all uninitialized! I haven't mentioned initializers yet!!).
Yeah, really. This means this:
public class Example {
private final long x = System.currentTimeMillis();
public Example() {
super(x); // x will be .... 0
// how's that for 'final'?
}
}
This will either end up invoking the first line of some other constructor of yours (which is itself also either a this() or a super() call). Either we never get out of this forest and a stack overflow error aborts our attempt to create this object (because we have a loop of constructors that endlessly invoke each other), or, at some point, we run into a super() call, which means we now go to our parent class and repeat this entire song and dance routine once more.
We keep going, all the way to java.lang.Object, which by way of hardcoding, has no this() or super() call at all and is the only one that does.
Then, we stop first. Now the job is to run the rest of the code in the constructor of j.l.Object, but first, we run Object's initializer.
Then, object's constructor runs all the rest of the code in it.
Then, Parent's initializer is run. And then the rest of the parent constructor that was used. and if parent has been shifting sideways (this() invokes in its constructors), those are all run in reverse order as normal in method invocations.
We finally end up at Child; its initializer runs, then the constructor(s) run in order, and finally we're done.
Show me!
class Parent {
/* some utility methods so we can run this stuff */
static int print(String in) {
System.out.println("#" + in);
return 0;
// we use this to observe the flow.
// as this is a static method it has no bearing on constructor calls.
}
public static void main(String[] args) {
new Child(1, 2);
}
/* actual relevant code follows */
Parent(int arg) {
print("Parent-ctr");
print("the result of getNow: " + getNow());
}
int y = print("Parent-init");
long getNow() { return 10; }
}
class Child extends Parent {
Child(int a, int b) {
this(print("Child-ctr1-firstline"));
print("Child-ctr1-secondline");
}
int x = print("Child-init");
Child(int a) {
super(print("Child-ctr2-firstline"));
print("Child-ctr2-secondline");
}
final long now = System.currentTimeMillis();
#Override long getNow() { return now; }
}
and now for the great puzzler. Apply the above rules and try to figure out what this will print.
#Child-ctr1-firstline
#Child-ctr2-firstline
#Parent-init
#Parent-ctr
#the result of getNow: 0
#Child-init
#Child-ctr2-secondline
#Child-ctr1-secondline
Constructor execution ordering is effectively: the first line goes first, and the rest goes last.
a final field was 0, even though it seems like it should never be 0.
You always end up running your parent's constructor.
--
*) You can use them for locks or sentinel pointer values. Let's say 'mostly useless'.
**) You can hack a class file so that it describes a class without a parent class (not even j.l.Object); that's how java.lang.Object's class file works. But you can't make javac make this, you'd have to hack it together, and such a thing would be quite crazy and has no real useful purpose.
In inheritance, the construction of a child object depends on at least one parent constructor.
Calling the super () method is not mandatory. By default, Java will call the parent constructor without argument except if you precise a custom constructor.
Here an example
Mother
public class Mother {
int a;
public Mother() {
System.out.println("Mother without argument");
a = 1;
}
public Mother(int a) {
System.out.println("Mother with argument");
this.a = a;
}
}
child
public class Child extends Mother {
public Child() {
System.out.println("Child without argument");
}
public Child(int a) {
super(a);
System.out.println("Child with argument");
}
}
If you do this :
Child c1 = new Child();
you will get :
Mother without argument
Child without argument
If you do this :
Child c1 = new Child(a);
You will get :
Mother with argument
Child with argument
But if you change the second child constructor to and remove the super(arg) the parent constructor without argument will be called :
public Child(int a) {
// super(a);
System.out.println("Child with argument");
}
You will get :
Mother without argument
Child with argument
May be this course for beginners can help you Coursera java inheritance

OOP - Are constructors required?

So I was watching a youtube video and the youtuber said: "When you are creating 'this' object, you are going to need to set it to a new ' type ' of this object"...
The class was called objectIntro and the constructor was:
public objectIntro(){
//Object Constructor (Method)
}
So here's my question...
I tried to create an object which basically tells me about the level of petrol with in a car...
public class car {
double petrolLevel;
double tankSize;
public void refillPetrol(double I){
if(I>tankSize){
I = tankSize;
petrolLevel = petrolLevel + I;
}
else{
petrolLevel = petrolLevel + I;
}
}
public void fuelConsumption(double O){
if(O>tankSize){
O=tankSize;
petrolLevel = petrolLevel - O;
}
else{
petrolLevel = petrolLevel - O;
}
}
public String returnPetrolLevel(){
return String.format("%sL", petrolLevel);
}
}
Then the class in which the object is created is...
public class carObject {
public static void main(String[] args){
car object1 = new car();
object1.tankSize = 50;//Litres
object1.petrolLevel = 0;
object1.refillPetrol(50);
object1.fuelConsumption(20);
object1.returnPetrolLevel();
System.out.printf("Petrol Level: %s", object1.returnPetrolLevel());
}
}
My question is, how come my object works without a constructor?
In the car class, I do not have a method which says "public car(){
}", whereas the youtuber stated this would be required?
Could someone clear this up, also I think I am not using the term constructor and method in the write context, could someone explain the definition of these terms, along with some examples.
Thanks
It's all in the Java tutorial
You don't have to provide any constructors for your class, but you must be careful when doing this. The compiler automatically provides a no-argument, default constructor for any class without constructors.
Also the convention is to uppercase your class names, lowercase your method parameters and use getters/setters for member variables which usually are private.
Sometimes you actually might notice that you cannot do new MyClass() or well that you cannot instantiate and object with new at all. This sometimes happens because the coder provided a no-arg private constructor. This is done when for instance you want the user to instantiate the object using a factory method (that you provide in that class) etc. But still doesn't change the fact that the constructor has to be there (that's part of the language spec).
If you want to know more about the default constructor you can consult the java language spec.
If you do not have a constructor there is an implicit constructor that sets all the members to their default value, e.g. 0 for int
The difference between a constructor and a method is the constructor creates and initializes an object while a method is for an object that already exists. You can think of a constructor as a function that is being called on your newly created object to initialize the data in some way.
JLS takes a special care of a class without constructor:
If a class contains no constructor declarations, then a default
constructor with no formal parameters and no throws clause is
implicitly declared.
This means that if you don't write any constructor for your class, one will be provided for you by the compiler and all class members will be initialized to default values by Java Virtual Machine.
But once you write a constructor, only that one will be used to create a class instance.
This behavior is usually good for a class that serves as a data structure, while normal class will have some constructor defined with default initialization code.
The answer to your question is, if you do not provide a constructor to a class the JVM will implicitly call the default constructor which has no parameter.
For detailed information about constructor you can refer below link
https://docs.oracle.com/javase/tutorial/java/javaOO/constructors.html
Even if you do not explicitly create a constructor in the class, a default constructor will be created during compile time and used.
https://msdn.microsoft.com/en-us/library/aa645608(v=vs.71).aspx

Constructor - order of execution [duplicate]

This question already has answers here:
Calling method from constructor
(2 answers)
Closed 9 years ago.
class Alpha
{
String name = "Alpha";
Alpha()
{
print();
}
void print()
{
System.out.println("Alpha Constructor");
}
}
class Beta extends Alpha
{
int i = 5;
String name = "Beta";
public static void main(String[] args)
{
Alpha a = new Beta();
a.print();//Line1 executes Beta constructor
System.out.println(a.name);//Line 2 displays Alpha instance variable
}
void print()
{
System.out.println(i);
}
}
This program compiles successfully and displays the following output.
0
5
Alpha
Questions
a) I dont understand why Alpha's constructor did not get executed first.
I believe "super()" will be called implicitly by every child constructor first ...right ?.
b) If Beta's constructor is already executed then why "5" is printed ? (Second Line in Output)
The third line I kinda understand (i.e Alpha's own variable will be displayed because casting is not yet done on "a" instance variable)
You are committing two "felonies" here:
calling an overridable method from the constructor;
declaring an instance variable in the subclass with the same name as the one in the superclass.
Both idioms result in surprising behavior. Specifically, 1. results in Beta#print being called from the Alpha's constructor, which results in printing 0 because you are invoking print on an unititialized instance of Beta. And this happens precisely because the superconstructor runs before the subclass constructor.
In summary, calling an overridden method from the constructor results in an unwanted reversal of the order of execution: control is transferred from the superclass constructor into the subclass method.
As for your question about why 5 is printed: a.print(), unlike a.name, is a method invocation subject to dynamic dispatch. So regardless of a's declared type (which is Alpha), the Beta#print method is invoked (the same happens in Alpha's constructor, but before the i variable is initialized).
class Alpha
{
String name = "Alpha";
Alpha()
{
print();
This one here actually invokes Beta.print(), because it #Overrides Alpha.print(). Since base class constructors are called first, the Beta part has not yet been initialized here, thus it prints 0 since...
}
void print()
{
System.out.println("Alpha Constructor");
}
}
class Beta extends Alpha
{
int i = 5;
this line of code has not yet been executed. Initialization within the class body is executed after the super class constructor (super()) but before the constructor body of the same class.
String name = "Beta";
public static void main(String[] args)
{
Alpha a = new Beta();
a.print();//Line1 executes Beta constructor
Here, it will print 5, as initialization of Beta (a) is finished.
System.out.println(a.name);//Line 2 displays Alpha instance variable
}
And this is said method actually beeing called:
void print()
{
System.out.println(i);
}
}
Init/Invocation order:
Object.Object()
Alpha.<instance vars>
Alpha.<constructor body>
Beta.print() which overrides Alpha.print() (prints Beta.i, which is still 0 (default) )
Beta.<instance vars> (Here Beta.i will be initialized to 5)
Beta.<constructor body>
Beta.print() which overrides Alpha.print() (prints Beta.i, which finally is 5, since initialization is finished)
I dont understand why Alpha's constructor did not get executed first.
It did execute first. I don't know what made you think it didn't. Perhaps the output 0. That is because you invoked the overridden method in constructor, which will call the method print() in Beta class. Now, since at that point of time, the variable i hasn't been initialized yet, it will print 0. See this answer for more details. I've also written a blog post on this topic.
I believe "super()" will be called implicitly by every child constructor first ...right ?
Not always. When you chain the constructor of the same class using this(), super() won't be added. Else super class constructor will be chained.
If Beta's constructor is already executed then why "5" is printed ?
Why wouldn't it? Beta constructor will initialize i with 5. The initialization which you do at the point of declaration is moved to every constructor of your class by the compiler, after the super() or this() statement, whatever is there.
Alpha's constructor does get executed first. If you put System.out.println("Alpha Ctr"); in Alpha() method you will notice Alpha Ctr getting printed.
The fact is that you've overridden print() method in child class Beta. Therefore Beta#print() gets executed instead of Alpha#print().
If you change Beta#print() little bit this behavior will be more clear:
void print() {
System.out.println(name + ": " + i);
}
This will now print:
null: 0
Beta: 5
Alpha
Here it is prints null: 0 because variable name & i are uninitialized at the time of construction of parent class Alpha.

Constructor overloading in java

I am getting an error with this following code fragment
The error is : cannot reference x before supertype constructor has been called (and pointing out the statement at comment 1)
class Con{
int x =10;
Con(){
this(++x); //1
System.out.println("x :"+x);
}
Con(int i){
x=i++;
System.out.println("x :"+x);
}
}
In the main method I have this statement
Con c1=new Con();
I don't understand the error. Can someone explain what is actually happening here?
When creating an instance of a class, the constructor first calls it's super class constructor to initialize the super class fields. Once all the super class constructors have run, then only the current constructor continues to initialize it's own field.
Now, when you add a this() call in your constructor, it doesn't call the super class constructor. This is because, the first statement in a constructor is either a chain to super class constructor - using super(), or a different constructor of the same class - using this().
So, you can't pass the field in this(), because the field is isn't initialized yet. But it doesn't really make sense, why you are trying to do something like that?
Remember, the compiler moves the field initialization code inside each constructor of your class. So, your constructor is effectively equivalent to:
Con() {
this(++x); //1
// This is where initialization is done. You can't access x before it.
x = 10;
System.out.println("x :"+x);
}
This is true even with super() call. So, the below code will also give you the same error (considering Con extends another class with a parameterized constructor):
Con() {
super(++x); //1
System.out.println("x :"+x);
}
Con(){
this(++x); //1
System.out.println("x :"+x);
}
At this very moment, Con does not yet exist. It first instantiates by calling the other constructor. That means that x does not exist yet (it is created as soon as the other constructor instantiates). So you can't reference it yet.
If you really need to reference it, you have to use a static variable
private static int x = 10;
First call inside a constructor can only be this() or super() , if their is none of them then compiler automatically insert a call to super but in your constructor you called other constructor by using this() . basically whenever you construct an object the superclass is first initialized then the subclass's members gets initialized.So you can not refer to uninitialized members as they gets initialized after superclass's members and superclass itself.

Calling an overridden method from a constructor

In the following example:
class Base {
int x=10;
Base() {
show();
}
void show() {
System.out.print ("Base Show " +x + " ");
}
}
class Child extends Base {
int x=20;
Child() {
show();
}
void show() {
System.out.print("Child Show " + x +" ") ;
}
public static void main( String s[ ] ) {
Base obj = new Child();
}
}
Why is the output as shown below
Child Show 0 Child Show 20
I thought constructors can only access instance members once its super constructors have completed.
I think what is happening here is that the super constructor is calling the child's show() method because this method was overridden in Child. as it has been overridden but why is the value of x 0 and why is it able to access this method before the super constructor has completed?
I think what is happening here is that the super constructor is calling the child's show() method because this method was overriden in Child.
That is correct
but why is the value of x 0
because it's not initialized yet (x of Child)
and why is it able to access this method before the super constructor has completed?
That's exactly why in a constructor you should never call a method, which can be overridden (non-final public and protected).
Edit:
The strange thing here is that everything has default/ package-private visibility. This can have some strange effects. See: http://www.cooljeff.co.uk/2009/05/03/the-subtleties-of-overriding-package-private-methods/
I recommend to avoid overriding methods with default visibility if possible (you can prevent this by declaring them final).
You can call overriden methods from constructors, but it's bad and you shouldn't. You illustrated the reason why this is bad: the derived class doesn't get a chance to get initialized, so uninitialized fields will be used - in your example, the default for int x is 0, that's why it's printing 0.
constructor chaining it makes sense to explain exactly what that is. A subclass constructor method's first task is to call its superclass' constructor method. This ensures that the creation of the subclass object starts with the initialization of the classes above it in the inheritance chain.
http://java.about.com/b/2009/02/07/java-term-of-the-week-constructor-chaining.htm
http://javahours.blogspot.com/2008/12/constructor-chain.html
Childs override of the show method is invoked because that's what the Java spec calls for. Here is a great discussion of why you should not do it. The value of x is zero because Child has not finished initializing yet.

Categories