Instance of child in parent class - java

I have class In java: A. And class B which extends class A.
Class A hold instance of class B.
I notice that when I call the constructor of class B (when I init this parameter in class A), It does super(), create a new instance of A and init all it fields.
How I can tell class B that the concrete instance of class A (which init it field) - it his parent class?

Your question is really hard to understand, but I guess the problem is this this (your approach):
public class A {
public B b = new B();
}
public class B extends A {
}
So, when you run new A() you get a StackOverflowError.
In my practical experience, I never needed a design like that, and I'd strongly recommend to re-think your approach. However, if it is really needed, you could use a dedicated init() method, e.g.:
public class A {
public B b;
public void init() {
b = new B();
}
}
A a = new A();
a.init();

If you needed A within B you could just do it with a custom constructor for B:
class B extends A {
A a;
public B() {
super();
this.a = this;
}
}
This case is harder though so you need:
class A {
B b;
}
class B extends A {
public B() {
super();
b = this;
}
}
Note that you should not pass the B into the call to super() as B will not be initialized, you should do it as the last step in the constructor of B.

Related

Is this correct to pass this keyword as parameter for member objects creation in java?

Here is my definition of class
class A {
B b = new B(this);
}
Is it correct to pass this keyword as parameter for member
objects creation in the class' definition?
if yes where can we use this?
It is correct in the sense that it compiles and runs.
It may be dangerous because your object is not fully initialized, so using it inside the member object's constructor may not be safe.
At a higher level, it's a bad practice to create new objects in constructor, see Injection of Dependencies pattern.
Update: this code certainly compiles:
class B {
B(A a) {
}
}
class A{
B b = new B(this);
}
If you had some kind of context object which is always created, you could use this pattern to avoid using an inner class.
So instead of this:
class A {
B b = new B();
class B {
void printA() { System.out.println(A.this); }
}
}
You could have two separate files:
class A {
B b = new B(this);
}
class B {
A a;
B(A a) { this.a = a; }
void printA() { System.out.println(a); }
}

Transferring an object over multiple class instances

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 );
}
};

Java Generics and Inheritance recursion

I came across the following Java code that uses generics and inheritance. I truly do not understand what the following snippet does:
class A<B extends A<B>> {
...
}
What does this code do?
(I got this from DBMaker in MapDB)
It is almost clear and the question actually conists in two parts:
1) why B extends A?
2) why A inside B extends A<B> has generic type B?
Answers for these parts will be:
1) In particular example this class (A) is builder class (called DBMaker), so most of its methods return some type, which extends this builder's class type. This explains, why B should extend A class.
2) But, actualy, if we will hide for the second part ...extends A<B>, we will receive just class A<B>. So A has type variable of type B. That is why in ...extends A<B> A is marked as type A having type variable B.
This tells that A needs derived definitions to be able to do some work:
public abstract class A<T extends A<T>> {
protected T instance;
T getOne() {
return instance;
}
}
public class B extends A<B> {
public B() {
instance = this;
}
}
public static void test() {
B b = new B();
b.getOne();
}
This is most commonly used in interface definitions, where one wants to explicitly use instances of classes implementing an interface in return types or in arguments and not the interface itself:
public interface TimeSeries<T extends TimeSeries<T>> {
T join(T ts);
}
public class DoubleTimeSeries implements TimeSeries<DoubleTimeSeries> {
#Override
public DoubleTimeSeries join(DoubleTimeSeries ts) {
return null;
}
}
So I did some tests to figure this one out, and here is my test cases to see how one could use such a generic case:
public class A<B extends A<B>> {
int x = 10;
B test;
void printX() {
System.out.println(x);
}
void setB(B b) {
test = b;
}
void printB() {
System.out.println(test);
}
}
public class B extends A<B> {
}
public class Run {
public static void main(String[] args) {
A<B> test = new A<B>();
B myB = new B();
test.printX();
test.setB(myB);
test.printB();
myB.printB();
}
}
I hope the code might be self explanatory. If not leave a comment and I will try and explain what is going on. Look at the last line, myB.printB(), here we will get a null, because B has not yet been set for myB, but only for test. This demonstrates that we can have an infinite recursion into classes of B inside A (and inside B for that matter).
we can say:
myB.test.printB();
This will get an error (null pointer), but shows that we now have access to test in the A class from B, and we can go as deep as we want recursively with as many cases as we like. So the A class kind of functions as a wrapper of infinitely many B classes. Does this make sense?
This makes it easier when defining method return types such as this:
class A<B extends A<B>> {
public B getMe(){
return (B) this;
}
}
This tells Java compiler that you are in getMe() method returning a subclass of class A.
class C extends A<C> {
}
C c = new C();
c.getMe(); //returns C

(Java) Difference ways of instantiating subclasses

I have these two classes:
public class A {}
public class B extends A {}
In the main class, I would declare:
A a = new B();
B b = new B();
What is the difference between a and b ? Is this what we called a subtyping in java?
The difference between a and b is that with a you can only use the public API that the A class provides even though its really a B type object, but with b, you can use both the A's public API as well as B's public API.
For example:
Suppose A and B are defined as follows:
// A.java
public class A
{
public void x()
{
z("X");
}
public void y()
{
z("Y");
}
protected void z(String message)
{
System.out.println(message);
}
}
// B.java
public class B extends A
{
public void a()
{
z("A");
}
public void b()
{
z("B");
}
}
And here's a demo:
// Demo.java
public class Demo
{
public static void main(String[] args)
{
A a = new B();
B b = new B();
// Can only call A's public methods
a.x();
a.y();
// a.a(); Can't use
// a.b(); Can't use
// Can call all public methods
b.a();
b.b();
b.x();
b.y();
}
}
Yes, there is difference between them. Accssibility of methods are different depends on what kind of reference you use.
A a = new B();
B b = new B();
a is a reference of Class A and b is a reference of class B. super class always can be used to point subclass object.
reference a able to access only super class method and properties
reference b able to access super class and it's own method and properties
one important thing is, ability of accessibility of function and properties will decided at runtime.
In below two cases
A a = new B();
a is an instantiation of B and of type A.
whereas in
B a = new B();
a is an instantiation of B and of type B.
The important thing to note here is that (in the first case) if you call a.someMethod(), the method of B will be called, not the method of A (this is called dynamic binding, as opposed to static binding).
This is basic inheritance. In the B b = ... case you can access all methods and variables provided from A and B but in the A case you can only use the methods and variables in the A case.
B gets typecasted into A when it is created, but that information is not required by the compiler.
public class A {
int x;
}
public class B extends A {
int y;
}
A a = new B();
B b = new B();
int c = a.x; //works
int c = a.y; //doesn't work
int c = b.y; //works
int c = b.x; //works
Remember, that you can always cast an object "downwards" in the inheritance chain. But you should not cast a object upwards because the variables for the subclass might be used even though they dont exist, for exmaple B b = new A(); So b.y is dangerous since the B object doesn't have an y variable defined.

How can I call the constructor of the grand parent class?

How can we call the constructor of grand parent.
eg: B inherits from A and C inherits from B.
I need to call the constructor of A in C. Is it possible without creating an instance of B?
If i need this how this can be implemented in Java.
You can't invoke the constructor of A directly in the constructor of C.
You can (and actually must) call it indirectly, 'though. Each constructor of B has to call a constructor of A (either explicitly or implicitly). Since every constructor of C needs to call one of the constructors of B you will always call one of As constructors.
use super() from C and from B to access A's constructor
class A {
public A() {
System.out.println("A");
}
}
class B extends A {
public B() {
super();
System.out.println("B");
}
}
class C extends B {
public C() {
super();
System.out.println("C");
}
}
public class Inheritance {
public static void main(String[] args) {
C c = new C();
}
}
Output :
A
B
C
Note:
If all are default constructor then no need to write super(); it will implicitly call it.
If there is parametrized constructor then super(parameter.. ) is needed
C will have to call B's constructor and in turn B will call A's constructor...
there is No other option to call Grand parent's constructor
An example to Joachim's answer:
class A {
A() { System.out.print("A()")};
A(Object o) { System.out.print("A(Object)")};
}
class B {
B() { super(); System.out.print("B()")};
B(Object o) { super(o); System.out.print("B(Object)")};
}
class C {
C() { super(); System.out.print("C()")};
C(Object o) { super(o); System.out.print("C(Object)")};
}
Now calling:
C c = new C();
will produce: A()B()C(), while calling:
C c = new C(new Object());
will produce: A(Object)B(Object)C(Object).
As you can see, by manipulating super() call you can actually call explicit parent constructor.
Actually, if you have class B extending class A, you can't avoid to call the constructor method for A when you create an instance of the class B. If this mechanism doesn't seems clear to you, I recommend this reading about Java's inheritance system: http://download.oracle.com/javase/tutorial/java/IandI/subclasses.html .
Here's an example:
class A {
public A() {
doSomethingA();
}
}
class B extends A {
public B() {
super(); // this is the call to the A constructor method
doSomethingB();
}
}
class C extends B {
public C() {
super(); // this is the call to the B constructor method
doSomethingC();
}
}
Creating a new object with new C() will involve, in order, the calling of A() - B() - C()

Categories

Resources