Assume I have 4 classes: A, B, SA and SB where B extends A
and SB extends SA.
Class A has the following constructor:
private SA a;
public A() {
a = new SA();
}
Obviously when I'm calling the contructor for class B and since B extends A
constructor of class A is also called. But in such a case I would like the
constructor of A to do a = new SB(); instead of a = new SA();.
Is there an easy way to do this without
changing the public interfaces of both A and B?
Just have a public constructor and a protected constructor:
private SA a;
public A() {
this(new SA());
}
protected A(final SA a) {
this.a = a;
}
Then in B:
public B() {
super(new SB());
}
Yes it is. For example :
public A(YourEnum en) {
if (en == YourEnum.SA){
a = new SA();
} else {
a = new SB();
}
}
Also, depends on what you really need, it can be done by overloading constructors
public A(){
a = new SA();
}
public A(YourObjectYouNeed dataNeededForAnotherConstructor){
//doing initialization stuff
a = new SB();
}
Related
I have three classes, and I need to modify first class through the second that is extended :
my first class A :
public class A{
private String name;
public void setName(String name) {
this.name= name;
}
my second class B
public abstract class B {
public void init() {
A a = new A();
a.setHost("foo");
}
}
my third class C
public class C extends B {
// I want to use the method setName() of the a declared in class B
b.init.a.setName("bar");//compile error, I tried several syntax I don't know how to do it
}
expected output, in my third class :
a.Getname = "bar"
Your code has multiple issues:
1) Variable b is never declared.
2) Variable a is private to method init, so you can't access it outside the init method.
So the solution should be like:
Class B:
public abstract class B {
protected static A a = new A(); // Protected to make it visible to child class
public void init() {
a.setHost("foo");
}
}
Class C:
public class C extends B {
public static void main(String[] args) {
a.setName("bar");
System.out.println(a.getName()); //Output = bar
}
}
you can return a in the init method of B like below.
public A init() {
A a = new A();
a.setHost("foo");
return a;
}
Then you can set the value in C like below
public class C extends B {
public setNameinA() {
B b = new B();
b.init().setName("bar");
}
}
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 basic class structure like this:
public class A {
}
public class B extends A {
private C objC;
public B() {
this.objC = new C();
}
}
public class C extends A {
private B objB;
public C() {
this.objB = new B();
}
}
I need B and C to know about each other so they can access each other's methods but obviously at runtime this creates a cyclic dependency and results in a java.lang.StackOverflowError: null. I have read this and this but I can't seem to get a good resolution on what I should do in my case.
Is there a better way to approach this?
Edit 1: A more descriptive of my situation while keeping simplicity:
public class A {
}
public class B extends A {
private C objC;
public B() {
this.objC = new C();
}
public String foo1() {
int x = C.foo3();
//do something
return Integer.toString(int);
}
public int foo2() {
// do something
}
}
public class C extends A {
private B objB;
public C() {
this.objB = new B();
}
public int foo3() {
int y = B.foo2();
//do something
return y;
}
}
Use Mediator pattern if you want to establish communication among different objects.
Mediator - defines the interface for communication between Colleague objects
ConcreteMediator - implements the Mediator interface and coordinates communication between Colleague objects. It is aware of all the Colleagues and their purpose with regards to inter communication.
ConcreteColleague - communicates with other Colleagues through its Mediator
Have a look at this link : https://en.m.wikipedia.org/wiki/Mediator_pattern
Consider following situation. I want to achieve the different behavior for methoddA() of class A depending upon from where it is getting call like here from class D or class C. How this can be achieved, method overriding is not working here.
class A
{
public methodA(){ //some code }
}
class B
{
A a = new A()
public methodB()
{
a.methodA();
}
}
class C
{
B b = new B();
public methodC()
{
b.methodB();
}
}
class D
{
B b = new B();
public methodD()
{
b.methodB();
}
}
What you need here is Polymorphism. First create an interface -
public interface MyInterface
{
void methodA();
}
then create two different implementations for two different behaviors -
public class First implements MyInterface
{
public void methodA() {
// first behavior
}
}
public class Second implements MyInterface
{
public void methodA() {
// second behavior
}
}
Now create your other classes as follows -
class B
{
public void methodB(MyInterface m)
{
m.methodA();
}
}
class C
{
B b = new B();
public void methodC()
{
// Pass the corresponding behavior implementation
// as argument here.
b.methodB(new First());
}
}
class D
{
B b = new B();
public void methodD()
{
// Pass the second behavior implementation.
b.methodB(new Second());
}
}
This will result in a more maintainable code.
You can pass the class name to your method as a String and in your method check
if(className.equals("A") // or use isInstanceOf() if you are passing objects of A/B
//do something
if(className.equals("B")
// do something else.
Why do you need two different implementations?
This easy trick can work for you... Please correct me if i am wrong..
I following code I have modified the method signature of Class A1 and Class B1 to accept Object and similarly while calling the methods from Class C and Class D whereever we are calling this method of class B1 pass this as reference. In Class A1 we can then check instanceof object and identify the calling class.
class A1
{
public void methodA(Object c){ //some code }
if (D.class.isInstance(c)){
System.out.println("Called from Class D");
}else if (C.class.isInstance(c)){
System.out.println("Called from Class c");
}else{
System.out.println("Called from Some diff class");
}
}
}
class B1
{
A1 a = new A1();
public void methodB(Object c)
{
a.methodA(c);
}
}
class C
{
B1 b = new B1();
public void methodC()
{
b.methodB(this);
}
}
class D
{
B1 b = new B1();
public void methodD()
{
b.methodB(this);
}
}
public class Testnew{
public static void main(String args[]){
D d = new D();
d.methodD();
C c = new C();
c.methodC();
B1 b = new B1();
b.methodB(b);
}
}
Can one create an extensible class hierarchy in java whose methods are fluent and can be invoked in any order? (YES! see answer below), even for existing classes when you don't have access to the source, provided the methods are fluant!
I'm retrofitting an existing hierarchy and hope to use a factory or at least a generic constructor and (eventually) immutable builder patterns (JB P.14). The methods that set fields return void - it would be better for them to return a generic T instead - that way we will gain the ability to do method chaining (they all call super now).
Goals:
1. Avoid having to create a static getFactory() method in every class.
2. Simple method signatures.
3. Create a factory method that is generic, yet will catch problems at compile time.
4. Get compile time errors instead of run time errors when mistakes are made.
As requested, the non-generic code is very simple, but doesn't work.
public class A {
private String a = null;
protected A setA(String a){
this.a = a;
return this;//<== DESIRE THIS TO BE CHAINABLE
}
protected static A factory(){
return new A();
}
}
.
public class B extends A {
private String b = null;
protected Foo setB(String b){
this.b = b;
return this;//<== DESIRE THIS TO BE CHAINABLE
}
protected static B factory(){
return new B();
}
}
Now a caller could TRY to call B.factory().setA("a").setB("b")//won't compile
But that can't compile because setA() returns an A, not a B. You COULD make it work by overriding the setA() in B, calling setB() and returning B instead of the A. To avoid delegating for each of those methods is the point. I simply want an extensible group of chainable class methods that can be invoked in any order. B.getFactory().B("b").A("a") works obviously.
The answer (to my surprise and satisfaction) is YES. I answered this question myself:
You can do this with a little work if the method invocations return instances of the class in question (see chainable below). I also found an even easier way do this if you can edit the top level source:
In the top level class (A):
protected final <T> T a(T type) {
return type
}
Assuming C extends B and B extends A.
Invoking:
C c = new C();
//Any order is fine and you have compile time safety and IDE assistance.
c.setA("a").a(c).setB("b").a(c).setC("c");
Example 1 and 3 are ways to make a existing class hierarchy fluent and to allow methods to be called in any order so long as the existing classes are fluent (but you don't have access to or can't change the source). WAY2 is an example where you do have access to the source, and want the calls to be as simple as possible.
Full SSCCE:
import static java.lang.System.out;
public class AATester {
public static void main(String[] args){
//Test 1:
for(int x: new int[]{ 0, 1, 2 } ){
A w = getA(x);
//I agree this is a nasty way to do it... but you CAN do it.
Chain.a(w.setA("a1")).a(w instanceof C ? ((C) w).setC("c1") : null );
out.println(w);
}
//Test for WAY 2: Hope this wins Paul Bellora's approval
//for conciseness, ease of use and syntactic sugar.
C c = new C();
//Invoke methods in any order with compile time type safety!
c.setA("a2").a(c).setB("b2").a(c).set("C2");
out.println(w);
//Example 3, which is Example 1, but where the top level class IS known to be a "C"
//but you don't have access to the source and can't add the "a" method to the
//top level class. The method invocations don't have to be as nasty as Example 1.
c = new C();
Chain.a(c.setA("a3")).a(c.setB("b3")).a(c.setC("c3"));//Not much larger than Example 2.
out.println(w);
}
public static getA(int a){//A factory method.
A retval;//I don't like multiple returns.
switch(a){
case 0: retval = new A(); break;
case 1: retval = new B(); break;
default: retval = new C(); break;
}
return retval;
}
}
Test class A
public class A {
private String a;
protected String getA() { return a; }
//WAY 2 - where you have access to the top level source class.
protected final <T> T a(T type) { return type; }//This is awesome!
protected A setA(String a) { this.a=a; return this; }//Fluent method
#Override
public String toString() {
return "A[getA()=" + getA() + "]";
}
}
Test class B
public class B extends A {
private String b;
protected String getB() { return b; }
protected B setB(String b) { this.b=b; return this; }//Fluent method
#Override
public String toString() {
return "B[getA()=" + getA() + ", getB()=" + getB() + "]\n "
+ super.toString();
}
}
Test Class C
public class C extends B {
private String c;
protected String getC() { return c; }
protected C setC(String c) { this.c=c; return this; }//Fluent method
#Override
public String toString() {
return "C [getA()=" + getA() + ", getB()=" + getB() + ", getC()="
+ getC() + "]\n " + super.toString();
}
}
The Chain class
/**
* Allows chaining with any class, even one you didn't write and don't have
* access to the source code for, so long as that class is fluent.
* #author Gregory G. Bishop ggb667#gmail.com (C) 11/5/2013 all rights reserved.
*/
public final class Chain {
public static <K> _<K> a(K value) {//Note that this is static
return new _<K>(value);//So the IDE names aren't nasty
}
}
Chain's helper class.
/**
* An instance method cannot override the static method from Chain,
* which is why this class exists (i.e. to suppress IDE warnings,
* and provide fluent usage).
*
* #author Gregory G. Bishop ggb667#gmail.com (C) 11/5/2013 all rights reserved.
*/
final class _<T> {
public T a;//So we may get a return value from the final link in the chain.
protected _(T t) { this.a = t }//Required by Chain above
public <K> _<K> a(K value) {
return new _<K>(value);
}
}
Output:
A [get(A)=a]
B [get(A)=a, getB()=null]
A [getA()=a]
C [getA()=a, getB()=null, getC()=c)]
B [get(A)=a, getB()=null]
A [get(A)=a]
QED. :)
I've not ever seen anyone do this; I think it could be a new and potentially valuable technique.
P.S. With regard to the "elvis like usage", it is 1 or 2 lines vs 8 or more.
Book b = null;
Publisher p = null;
List books = null;
String id = "Elric of Melnibone";
books = Chain.a(b = findBook(id)).a(b != null ? p = b.getPublisher() : null)
.a(p != null ? p.getPublishedBooks(): null).a;
out.println(books==null ? null : Arrays.toString(books.toArray()));
vs:
Book b = null;
Publisher p = null;
List books = null;
String id = "Elric of Melnibone";
b = findBook(id);
Array[] books = null;
if( b != null ) {
p = b.getPublisher();
if(p != null) {
books = p.getPublishedBooks();
}
}
out.println(books==null ? null : Arrays.toString(books.toArray()));
No NPE, and if the chain completes you get all the books published by the publisher of "Elric of Melnibone" (i.e. all the books "Ace" publishers has published), and if not you get a null.
I believe there is a way to do this with generics... Syntax is a little less clean than the desired...
Here is the client code...
B<B> b = B.factoryB();
b.setA("a").setB("b");
A<A> ba = A.factoryA();
ba.setA("a");
Top level (real) class
public class A<S extends A> extends Chained<S> {
private String a = null;
protected A() {
}
public S setA(String a) {
this.a = a;
return me();
}
public static A<A> factoryA() {
return new A<A>();
}
}
Example Subclass
public class B<S extends B> extends A<S> {
private String b = null;
B() {
}
public S setB(String b) {
this.b = b;
return me();
}
public static B<B> factoryB() {
return new B<B>();
}
}
Helper
public abstract class Chained<S extends Chained> {
// class should be extended like:
// ... class A<S extends A> extends Chained<S>
public Chained() {
}
public final S me() {
return (S) this;
}
}
It's far from perfect and can be made not to work (if you really wanted to)
If source code is accessible, by extending what Alan wrote, I would add supplementary classes to hide generics while allowing inheritance and very compact syntax. BaseA and BaseB do the hierarchy while A and B do hide the generics.
BaseA
+- A
+- BaseB
+- B
public class BaseA<S extends BaseA<?>> {
private String a = null;
protected BaseA() {
}
#SuppressWarnings("unchecked")
public S setA(String a) {
this.a = a;
return (S) this;
}
}
public class A extends BaseA<A> {
public static A factoryA() {
return new A();
}
}
public class BaseB<S extends BaseB<?>> extends BaseA<S> {
private String b = null;
protected BaseB() {
}
#SuppressWarnings("unchecked")
public S setB(String b) {
this.b = b;
return (S) this;
}
}
public class B extends BaseB<B> {
public static B factoryB() {
return new B();
}
}
public class Main {
public static void main(String[] args) {
B.factoryB().setA("").setB("").setB("").setA("").setA("");
}
}
A fluent interface is a different concern from the normal set of command-query methods that you already have. Separation of concerns makes it a good idea to separate them.
Since you have an existing hierarchy of code: Write a fluent facade that does the dirty work for you.
See also Martin Fowler: Domain-Specific Languages, 4.2: The need for a Parsing Layer.