I have a question which might be a very simple one but I can't find the way out.
Here are the Parent and Child classes which will work without a problem.
public class Parent {
private A a;
private B b;
Parent (A a, B b){
this.a = a;
this.b = b;
}
public class A {}
public class B {}
private class C {}
public class Child extends Parent {
private final C c;
Child(A a, B b, C c,) {
super(a, b);
this.c = c;
}
}
}
Here is the problem: Fields b and c are fields of some other class ClassBC and ClassBC is one of the argument of class Child. i.e.,
public class Child extends Parent {
private D d;
Child(A a, C c) {
// I must call super(...) here; but can't do that without `b`
ClassBC classBC = new ClassBC(c);
B b = classBC.getB();
D d = classBC.getD();
}
// some methods
}
private class ClassBC{
private D d;
ClassBC(C c){
// do something here to get 'B' and 'D'
}
public D getd(){
return d;
}
public B getB(){
return b;
}
}
So:
Am I being stupid or breaking some rules here?
I tried to use Builder in Parent class such that it can be used in the constructor of Child class. As expected, it compiled but failed because fields of Parent classes are not available in Child class.
I want to avoid using builder in Child class because it will lead to too may changes in the repository. What else I can try?
This is a minimal example, actual classes are complex with couple of more arguments.
Cant you do it with factory method. Make Child constructor private, and add static method createChild create child objects from this factory method.
Create your ClassBC objects before calling Child constructor.
I think that should work for you
public class Child extends Parent {
private D d;
private ClassBC bc;
Child(A a, C c) {
// Inline
this(a, new ClassBC(c));
}
Child(A a, ClassBC bc) {
super(a, bc.getB());
this.bc = bc;
this.d = bc.getD();
}
}
Related
class abstract Parent ()
{
private int a;
private final int b = a + 1; // a is null at that point
}
class Child extends Parent
{
public Child()
{
a = 2;
}
}
That wouldn't really be a problem in C++ (because pointers), but I'm not sure how to handle this issue in Java. Obviously a is equal to 0 when Parent tries to initiate b.
I initially tried calling super() after setting a, but apparently super() has to be called first in child's constructor. I don't want to set b in Childs and I'd prefer b to be final too. Any ideas?
What you want cannot be done like this, what you need to do is pass the value of a to a constructor of Parent:
abstract class Parent {
private int a;
private final int b;
protected Parent(int a) {
this.a = a;
b = a + 1;
}
}
And define Child as:
class Child extends Parent {
public Child() {
super(2);
}
}
Recently in an interview for Java Developer role, I was asked how do I make Class A immutable if it has a member variable, which is an object of Class B and in a situation where Class B is external to the project and cannot be edited by the programmer moreover class B might even have a member variable of its own which is an object of another user defined class. I gave it a lot of thought and told the interviewer there is no way unless class B has implemented and exposed a method to deep clone itself.
The interviewer though wasn't convinced. Is there really a way to make such a class immutable?
If I can remember correctly this was the situation he explained. He wanted me to make class A immutable, what would have been the best answer?
final public class A {
final private B b;
A(B b) {
this.b = b; // Class b might/might not be cloneable
// this.b = (B)b.clone();
}
public B getB() {
return b;
// return (B)b.clone();
}
}
class B // external cannot edit
{
C c;
public C getC() {
return c;
}
public void setC(C c) {
this.c = c;
}
}
class C // external cannot edit
{
int i;
String j;
public int getI() {
return i;
}
public void setI(int i) {
this.i = i;
}
public String getJ() {
return j;
}
public void setJ(String j) {
this.j = j;
}
}
Don't expose B to the world. So do not have a method which return B.
Instead identify the methods in B, which don't mutate B and let A implement these methods by calling the same method in b.
So if B has a method calcSomething() a should have a calcSomething() methocd which just does return b.calcSomething().
You may use something like this:
final public class A {
final private B b;
A(B b) {
this.b = cloneB(b);
}
public B getB() {
return cloneB(b);
}
private static B cloneB(b){
B newB = new B();
C c = new C();
c.setI(b.getC().getI());
c.setJ(b.getC().getJ());
newB.setC(c);
return newB;
}
}
It that case Class A is 100% immutable.
Update: Also you can use reflection or seralization to get deep copy of class (if class has deep hierarchy), for example using GSON for seralization:
private static B cloneB(b){
String tmp = new GSON().toJson(b);
return new GSON().fromJson(tmp, B.class);
}
or so on
I'm working on a project using JavaFX and classes have typically as many as 800-1200 lines . We are using fxml for displaying Node elements, still this classes are very complex. Here is concretely what I ask:
A class ReservationUI contains sub parts , which are modulerized as inner classes at the moment.which again has sub parts. And this classes has access to fields of ReservationUI . Now I like to extract them to their own classes but now I need to have access to parent class .
class A{
int x; int y;
B b;
public A(){
b = new B();
b.display();
}
private class B{
private C c;
/* modify x */
}
private class C{
/* modify x and y */
}
}
And when i extract them now I have dependencies even worse :
class A {
int x; int y;
B b;
public A(){
b = new B(this);
b.display();
}
}
class B {
C c;
A a;
public B ( A parent ){
c = new C(this, parent);
a = parent;
/* call A.modifyX(c.get) */
}
class C{
A a;
B b;
public C( B parent , A root){
a = root;
b = parent;
}
}
What I think is here the modularization is gone terribly wrong. Especially when I have relations long as this one : root -> child -> child -> child ... .
Is there a design pattern to address this issue. As far as I know there is Mediator pattern but use of it, still doesn't bring much since I still need to basically do the same thing .
The best way to do this, is to use some kind of dependency injection. The controller then resolves dependencies automatically. I assume that you don't need any enterprise framework that provides it, so you have to resolve dependencies manually somehow.
The purpose of mediator pattern is to simply encapsulate dependency mamagement in one single place. In my solution, root element A acts just as mediator. Side offect of it, is that child elements exist in short period in an uninitialized state. To solve this issue you can also introduce Builder pattern.
interface IA{
/*...*/
void modifyX(int x);
}
class A implements IA{
int x; int y;
IB b;
IC c;
public A(){
b = new B();
c = new C();
resolveDependencies();
b.init();
b.display();
}
public void resolveDependencies(){
b.setC(c);
b.setA(this);
c.setA(this);
c.setB(b);
}
}
interface IB {
void setC(IC c);
void setA(IA a);
void init();
void display();
}
class B implements IB{
IC c;
IA a;
public B (){
}
#Override
public void setC(IC c){
this.c = c;
}
#Override
public void setA(IA a){
this.a = a;
}
#Override
public void init(){
/* call A.modifyX(c.get) */
}
}
interface IC {
void setA(IA a);
void setB(IB b);
}
class C implements IC{
IA a;
IB b;
public C( ){
}
#Override
public void setA(IA a){
this.a = a;
}
#Override
public void setB(IB b){
this.b = b;
}
}
if i have group of classes let say class A,B,C and D and Class A initiate class B, class B initiate class C and class C initiate class D and their is arguments must be passed from A to D, what is the best way to passing??do i have to pass the arguments across all the classes i have ??
i tried this solution but i search for one easier.
class A
{
B b=new B(the_arguments);
}
class B
{
C c=new C(the_arguments);
}
class C
{
D d=new D(the_arguments);
}
thanks in advance .
Can you create a constructor in each successive class that takes a single argument of the previous class type? You'd need to make appropriate getters, or expose the arguments to the other classes (which wouldn't be too bad if they derived from each other).
class A
{
B b = new B(this);
}
class B
{
B(A a) { this.foo = a.foo; ... } // Constructor
C c = new C(this);
}
class C
{
C(B b) { this.foo = b.foo; ... } // Constructor
D d = new D(this);
}
class D
{
D(C c) { this.foo = c.foo; ... } // Constructor
}
I have a method dummy with A as class parameter, but i need to pass instance of subclasses B to that method. I know from:
Does Java casting introduce overhead? Why?
that downcasting in java have overhead. Most of my code deal with subclass B so i dont use downcasting for this purpose. Instead i use temporal instance variable cc for that purpose. But this is not make a change for object of subclass m. I need change in variable cc avaliable too for instance variable m. This is my code:
public class TestCast {
public TestCast() {
B m = new B(12, 3);
dummy(m);
A cc = m;
dummy(cc);
System.out.println(m.a);
System.out.println(cc.a);
}
public void dummy(A t) {
t.a = 22222;
}
public static void main(String[] args) {
new TestCast();
}
}
class A {
public int a = 0;
public A(int a) {
this.a = a;
}
}
class B extends A {
public int a;
public int b;
public B(int a, int b) {
super(a);
this.a = a;
this.b = b;
}
}
with output
12
22222
In your particular example, both the parent and child classes declared a field with name a. In this case, the child variable hides the parent variable.
Also, variables/fields are not polymorphic entities like methods. They are accessed by the static type of a reference.
In other words, the field access
A var = new A(10);
var.a; // returns 10
And the field access
A var = new B(1501, 10);
var.a; // also returns 10
but
A var = new B(1501, 10);
var.a; // returns 10
((B)var).a; // returns 1501
because you access a on a reference with static type B.
In your method
public void dummy(A t) {
t.a = 22222;
}
The static type of t is A so you will modify the value of the parent class variable.
Casting is telling the compiler that a reference variable is of specific Type at runtime
Because B is extending A you do not want to re-define the variable a
In answer to your comment, you code should be something like:
class B extends A {
public int b;
public B(int a, int b) {
super(a);
this.b = b;
}
}
IMO, your example code is not perfect implementation of inheritance. Inheritance enables you re-usability of code. In other words, you don't need to declare int a again in class B.
I need change in variable cc avaliable too for instance variable m:
However, if you want to change in variable cc as well, then declare variables a, b as private/protected in both A and B. And provide setters and getters in both classes.
And in class B call super.setA(a) like below.
class B extends A {
private int a;
private int b;
public B(int a, int b) {
super(a);
this.a = a;
this.b = b;
}
public setA(int a) {
super.setA(a);
this.a = a;
}
}