I'm not novice in java, but I've got an example that made me confused.
Here it is:
class A {
public A() { System.out.print("O"); }
}
class B {
{ System.out.print("A"); }
public B() { System.out.print("D"); }
}
class C {
static { System.out.print("3"); }
public C() { System.out.print("P"); }
}
public class D extends C {
private A objA = new A();
private static B objB = new B();
public D() { System.out.print("T"); }
public static void main(String[] args){
new D();
}
}
So what is the result in system.out?
We know that static members are the first, so "3" will print first cause it is in the superclass and private static B objB = new B(); will initialize after it (instance initializer and then constructor).
We get 3AD in console.
Then the main method runs and create a new instance of class D, its ok.
But since this step the order is strange:
1 Constructor of the superclass public C() { System.out.print("P"); }
3ADP in console.
2 Then field of D.class private A objA = new A();
3ADPO in console.
3 And constructor of D.class is the last, so:
3ADPOT in console.
So the question is: why does superclass constructor run before field of subclass? I thought that constructors have lowest priority. Can anyone share a link on docs plz?
Simply if we think then its easy to understand that first the subclass inherits from the super class and then only can it override the behaviour or acess the properties defined in the super class.
Whenever we create an object of a class A , first it is checked if the class is loaded, if not then it is loaded which invokes its static initilizer if it is present, then all the static fields are initilized (with default value or the values defined). After this super constructor is called, all the properties as set by the super class are set. Then all the instance fields are initilized and then finally constructor code of A is executed.
Below is the execution ordering.
public class A{
static{
// 1
}
int x = 30; // 3
public A(){
//4
}
}
public class B extends A{
static{
//2
}
private int s = 60; //5
public B(){
//6
}
}
public class Test {
public static void main(String[] args){
new B();
}
}
Related
extending class B in Class A, now I am printing value of variable a in Class A.The result i am getting is a=0 . How can i get the value a=2
Class A
package testing;
public class ClassA extends ClassB {
public void print(){
System.out.println("a= " +a);
}
public static void main(String arg[]){
ClassA ca = new ClassA();
ca.print();
}
}
Class B
package testing;
public class ClassB {
int a;
public void send(){
a=2;
}
}
Initially the value of a is 0, as you have not set it to anything, and by default, when you call new ClassA(); it is initialized to 0. Hence you get 0 as the output.
You need to call the send method, to set the value of a to 2.
ClassA ca = new ClassA();
ca.send(); //Here
ca.print();
Another easier way to understanding of parsing of variables between classes is using the get-set methods.
Class A coding:
public class ClassA extends ClassB {
public static void main (String [] args)
{
ClassB ClassBValue = new ClassB();
System.out.println(ClassBValue.getA());
}
}
Class B coding:
public class ClassB {
int A = 2;
public int getA()
{
return A;
}
public void setAValue(int A)
{
this.A = A;
}
}
Hope this helps
You are calling ca.print() without assigning any value to it, so basically it is printing initialized value for int a which is 0.
Put a call to send() before the print function, Compiler will first check for function send in ClassA, when it does not find it there it will call send function of the SuperClass which is B, this will assign value '2' to your variable a, When you call print(), print function present in Class A is called, Now Class A has no variable called a, so the value of variable a is called from it's super class and you will get value of 2 printed.
Code should look like ->
public class ClassA extends ClassB {
public void print(){
System.out.println("a= " +a);
}
public static void main(String arg[]){
ClassA ca = new ClassA();
ca.send();
ca.print();
}
}
public class ClassB {
int a;
public void send(){
a=2;
}
}
Your int variables, by default, are initialized with 0.
Some options:
A) Alter your main method to call the send method
ClassA ca = new ClassA();
ca.send(); //set the value to 2
ca.print();
B) If don't want to alter your main method (for any reason), you can move the variable initialization to the class construtor:
ClassA() {
a = 2
}
Now, when you instantiate your the class (new ClassA()), 'a' gonna be equals 2.
I am thinking of an optimum design pattern which I can use to transfer objects to the methods in different classes other than passing them as arguments.
class A{
}
class B{
public A a;
public B()
{
a = new A();
}
}
class C
{
public void c()
{
//need to access "a" of class B other than passing "a" as argument;
}
}
Here, a in class A attribute needs to be accessed in many other class methods. Is there an optimum design pattern or any possible way other than passing this object (a) as arguments?
It's hard to say how your program is really structured but two options come to mind:
Pass an instance of B to C's constructor.
class A {};
class B {
public A a;
public B() {
a = new A();
}
};
class C {
public B b;
public C( B b ) {
this.b = b;
}
public void someMethod() {
System.out.println( b.a );
}
};
If only one instance of class A ever exists (ie a Singleton). That means that class B holds an instance of class A, not each instance of class B holds an instance of class A.
class A {};
class B {
public static final A a = new A();
};
class C {
public void someMethod() {
System.out.println( B.a );
}
};
class A
{
class B b;
B b = new b();
}
class B extends A
{
b.function();
}
Here can B use the same object created in A?
Following is your program:
class C {
public String cvariable;
public void cfunction(){
System.out.println("string");
}
}
class A {
public C c1;
public void funtiona(){
c1 = new C();
}
}
public class B extends A {
public void functionb(){
c1.cfunction();
}
public static void main(String args[]){
B b = new B();
b.functionb();
}
}
It is correctly throwing null pointer exception. It proceed as follows:
In the main method you call functionb()
In functionb() you call cfunction() with c1, but c1 is just an variable of type C(as not initialized yet) which contains null. So getting null pointer exception.
See the following program, It will throw java.lang.StackOverflowError
class B{
A a = new A();
public B(){
System.out.println(a.hashCode());
}
}
public class A extends B{
public void show(){
a.hashCode();
}
public static void main(String[] args){
new A().show();
}
}
This is because program goes in the infinite loop, As before creating a child class object it calls the parent class constructor and in parent class for hash code it again calls the child class constructor. so an infinite loop
So, one friend sent me this code and said that it had compiled successfully and returned 42.
But, the bothering thing is the method in parent class that "returns" 42 is private, and the method that is called on is in child class, and it's public. So, can anybody tell why and how this works?
static class A {
private int f() {
return 42;
}
}
static class B extends A {
public int f2() {
return super.f();
}
}
public static void main(String[] args) {
System.out.print(new B().f2());
}
It returns 42.
I tried to get rid of static, and
class A {
private int f() {
return 42;
}
}
class B extends A {
public int f2() {
return super.f();
}
}
public static void main(String[] args) {
Main m= new Main();
B b= m.new B();
System.out.print(b.f2());
}
it still returns 42.
Since both of the classes (A and B) are nested in Main, they can access the private int f() method.
If you extract the sources of A and B in top-level classes, this won't happen and you'll fail to compile.
The point of private is that "outside" classes should not be able to see private variables. But A and B are both part of the same class, or are nested within each other, so they can access each others private members.
So this will work:
public class A {
private void a() {
int bVal = this.new B().val; //! Accessing B private
}
class B {
A a = new A();
private int val = 10;
public void b() {
a.a(); // !! Accessing A private
}
}
BUT, this will fail, even if both A and B are in the same file but not within each other:
class A {
private void a() {}
}
class B extends A {
A a = new A();
public void b() {
a.a(); // can't see even if B extends A
}
}
This is because both classes A and B are nested inside another class, i.e both classes are inner classes of (or "part of") another same class. Since they (Data Members and Methods) are basically a member of the outer class,they are accessible within other inner classes even if private.
Java allows us Nesting of classes,If You Don't know about nested classes first read this :
http://docs.oracle.com/javase/tutorial/java/javaOO/nested.html
class Outer{
class A {
private int f() {
return 42;
}//Method f() is a private member of A and accessible by Outer
}
class B extends A {
public int f2() {
return super.f();
}//As class B is inner class of Outer it can access members of outer,thus indirectly member of A
}
public static void main(String[] args) {
System.out.print(new B().f2());
}
}
In the code below, myString is always initialized to null. I have to manually initialize in an init() or similar. As far as I can tell it is related to superclass/subclass but I don't understand the exact mechanism
public class A extends B {
private String myString = "test";
public static void main(String[] args) {
new A();
}
public A() {
super();
}
public void c() {
System.out.println(myString);
}
}
public class B {
public B() {
c();
}
public void c() {
}
}
The issue with your code is, that myString is initialized at the begin of the constructor of class A but right after the super constructor (i.e. class B). Since you access the variable before from the constructor of class B (indirectly via call to overriden methode c) your get this behaviour.
As a rule of thumb: if you want to avoid unexpected behavior do not call overriden methods before the constructor has been executed.
Add a call to c(); overidden method right after the object has been fully created and call to superclass constructor is done.
Change your code to this ..
public class A extends B {
private String myString = "test";
public static void main(String[] args) {
new A();
}
public A() {
super();
c(); // Include the call to c(); here ...
}
public void c() {
System.out.println(myString);
}
}
public class B {
public B() {
}
public void c() {
}
}
// Output : test
Thinking in Java Second Edition by Bruce Eckel, Behavior of polymorphic methods
inside constructors (p. 337-339).