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
}
Related
Hi this is a basic question, but kindly bear with me.
I have two classes and on class has a reference of another class. How can i create the instance of second class which is present in first class at the time creation of instance of first class. Are any utility present for this.
Code ::
class A {
B b;
}
class B {
int member;
}
In a Contructor (like Robert Kock already said)
class A {
B b;
public A(){
b = new B();
b.member = 5;
}
}
Directly as Attribute
class A {
B b = new B(5);
}
With Initializer
class A {
B b;
{
b = new B();
b.member = 5;
}
}
Within the constructor of the first class:
class A
{
public A()
{
b = new B();
}
B b;
}
Or even like this:
class A
{
public A()
{
}
B b = new B();
}
A general solution would be:
public class A {
private final B b;
public A(B b) {
this.b = b;
}
}
...
A a = new A(new B());
It becomes interesting when both instances refer to each other, then you need to use a setter in at least one of the classes:
public class B {
private A a; // the field cannot be final in this case
public void setA(A a) {
this.a = a;
}
}
....
B b = new B()
A a = new A(b);
b.setA(a);
The answers where the class is creating the other instance itself are not a general solution.
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();
}
}
Given this Java code:
class A {
public void foo (Object o) { System.out.println("A"); }
}
class B {
public void foo (String o) { System.out.println("B"); }
}
class C extends A {
public void foo (String s) { System.out.println("C"); }
}
class D extends B {
public void foo (Object o) { System.out.println("D"); }
}
class Main {
public static void main(String[] args) {
A a = new C(); a.foo("Java");
C c = new C(); c.foo("Java");
B b = new D(); b.foo("Java");
D d = new D(); d.foo("Java");
}
}
why is the result ACBB?
I wil try to explain what I think, and I would appreciate if someone lets me know where my gap is.
So what I thought with the first two calls is:
a has static type A, but dynamic type C so Java should dispatch the method call dynamically and call foo() in C printing "C".
c has static and dynamic type C, so now since we inherit from A, it has to choose the most specific method, which is public void foo(String s) and thus printing "C"
b has static type B but dynamic type D so also in this case it should dynamically dispatch and call foo() in D printing "D".
d has static and dynamic type D, so now since we inherit from B, it has to choose the most specific method, which is public void foo(String o) and thus printing "B"
What is wrong in this explanation I've given here?
foo(Object) doesn't override foo (String) but overloads it. Hence D has 2 methods and since the most specific one will be used it will be foo(String) when you pass a string parameter.
From JLS 15.12.2 (emphasis by me):
This step uses the name of the method and the argument expressions to locate methods that are both accessible and applicable, that is, declarations that can be correctly invoked on the given arguments.
There may be more than one such method, in which case the most specific one is chosen.
A a = new C(); a.foo("Java"); calls foo(String) method from a which is a A
C c = new C(); c.foo("Java"); calls foo(String) method from c which is a C
B b = new D(); b.foo("Java"); calls foo(String) method from b which is a B
D d = new D(); d.foo("Java"); calls foo(String) method from d which only exists on B (D contains foo(Object))
I have two classes (say B & C) that both derive from a class (say A). Now I need to write a class (say D) that should dynamically derive either from B or C at runtime.
B, C & A are classes provided to me through libraries and the only class in my control is D class. How do I write D with respect to constraints mentioned above. Obviously B and C have come from different vendors and hence would need different methods to be overridden in D depending on which is its parent class.
I cannot write different versions of D that would subclass from B & C since the override methods would have same code under different method names.
You should define an interface I, then define concrete implementations that correspond to B and C. At runtime you can determine which implementation of I is necessary, perhaps using a factory method. Then your code need only call methods of I instead of methods of B or C.
EDIT
There seems to be some confusion about how this works. What you want is for your business logic to operate on a consistent, stable API that belongs to you. For this you create an interface which we'll call I. Now you need implementation classes for the different external classes you need to adapt to (A, B, and C). It might look something like this:
public interface I {
void doSomething();
}
public class IA implements I {
private A a;
public IA(A a) {
this.a = a;
}
public void doSomething() {
// specific to A
a.doSomethingUnique();
}
}
// similar implementation classes for B and C
Now you need to obtain an instance of I at runtime specific to your current situation. Whatever informs you about which specific class is in use at runtime can be used for this purpose. At worst, you can do this:
// in some util class
public static I getI(Object obj) {
if (obj instanceof A) {
return new IA((A) obj);
} else if (obj instanceof B) {
return new IB((B) obj);
} else if (obj instanceof C) {
return new IC((C) obj);
}
// maybe throw an exception? or return a mock I implementation?
}
Now all your business logic refers only to instances of I and calls methods defined in your interface, abstracting away the different concrete classes you have no control over.
You can do it with private inheritance.
If you have :
class A
{
public void methodA() {...}
}
class B extends A
{
public void methodB() {...}
}
class C extends A
{
public void methodC() {...}
}
D would be implemented as :
class D
{
private B b;
private C c;
private D() {}
public static D instantiateAsB()
{
D res = new D();
res.b = new B();
}
public static D instantiateAsC()
{
D res = new D();
res.c = new C();
}
public void methodA()
{
if ( b!=null )
b.methodA();
else
c.methodA();
}
public foid methodB()
{
if ( b==null )
throw new MethodNotImplementedException();
else
b.methodB();
}
public foid methodC()
{
if ( c==null )
throw new MethodNotImplementedException();
else
c.methodC();
}
}
Private inheritance has some drawbacks. One is that D would not be an A. So you can't pass a D object as a parameter to a method which requires an A. This code would not compile :
void method( A a ) {...}
D d = D.instantiateAsB();
method( d );
You can work around that using cast methods in D's definition :
// inside D class :
public A castAsA()
{
if ( b!=null )
return (A)b;
else
return (A)c;
}
public B castAsB()
{
if ( b==null )
throw new ClassCastException();
else
return b;
}
public C castAsC()
{
if ( c==null )
throw new ClassCastException();
else
return c;
}
And the previous non compiling code would be rewritten as :
D d = D.instantiateAsB()
method( d.castAsA() );
I have a Java class B with an inner class C. Some methods of B accept an instance of C as parameter but I only want to accept C instances created by the proper instance of B. Is there a way to do this validation at compile time?
Example
C c1 = new C();
B foo = c1.getB(); // foo was created by instance c1
C c2 = new C();
c2.method(foo); // I want a compiler error here.
My case
Have a class names Map which hold a matrix of instances of the inner class MapArea. The nice thing about this scheme is that I can validate the xPos, and yPos fields at the constructor so no invalid Areas for a given map are built. The map as a method distanceFrom(MapArea startingPos, MapArea toLocation, MapArea... otherLocations) and I was trying to avoid to validate the map area arguments again.
If this is really the behavior you want, method() should really be defined in the inner class.
In other words, instead of:
public class C {
//...
public void method(B b) {
this.x = b.y;
//...
}
//...
public class B {
//...
}
//...
}
It should be:
public class C {
//...
public class B {
//...
public void method() {
C c = this.C;
c.x = this.y;
//...
}
//...
}
//...
}
Of course, this wouldn't solve the problem if, for example, you wanted public void method(B b1, B b2, B b3), where all three instances of B are enclosed by the same instance of C.
A compile error won't work, but you can at least throw an exception:
public class C
{
public static void main (String [] args)
{
C c1 = new C();
B b = c1.getB();
c1.useB(b); //OK
C c2 = new C();
c2.useB(b); //throws IllegalArgumentException
}
public B getB() { return new B(); }
public void useB(B b) {
if(b.getC() != this)
throw new IllegalArgumentException();
//...
}
private class B
{
public C getC() { return C.this; }
//...
}
}
There's no way (AFAIK) of doing this at compile time.
At runtime you can do it by having the outer instance's factory method pass a reference to itself to the inner instance's constructor.
The inner class would need to store that reference, such that the outer class can check whether it created that instance or not:
public class C {
public class B {
private C parent;
private B(C parent) {
this.parent = parent;
}
public C getParent() {
return parent;
}
}
public B getB() {
return new B(this);
}
public void method(B b) {
assert(this == b.getParent());
}
}
Actually, as Kip's concurrent answer shows, B can access C.this to get the parent object so there's no need to store the parent reference. However the method above would be necessary if C wasn't actually an inner class.
If you make the constructor of the inner class (C) private, I believe the enclosing class (B) can still instantiate it while other classes cannot. This ensures that only B and C can instantiate C.
Edit: I've verified that with a small mockup. Make the inner class constructor private, and then only the inner class (C) or the enclosing class (B) can instantiate it.
See http://tns-www.lcs.mit.edu/manuals/java-1.1.1/guide/innerclasses/spec/innerclasses.doc6.html for more. In particular: "Access protection never prevents a class from using any member of another class, as long as one encloses the other, or they are enclosed by a third class.".
There's no compile-time way to guard against instance-specific usage. Your best bet is probably throwing an Exception when the usage in incorrect. Another option you have is to have the parent class to have a Map of instances of the inner class, and to have other classes tell the outer class to operate on the inner class not by the instance but by some other references. This will work with other classes don't need to do anything directly with the inner class.