Cannot Implement or extend - java - java

I have a class C with lots of members(say 10 members) + members that are only in C
I have two more classes A and B which has exactly those above mentioned 10 members. (A and B each does not have those 10 members. Those 10 members are distributed among A and B and A and B has few other fields)
class C {
private int member1;
private String member2;
private String member3;
private float member4;
...
private String member10;
private member11_only_in_C;
private member12_only_in_C;
...
}
class A {
private String memeber10;
private float member4;
private double member6;
....
}
class B {
private int memeber1;
private String memeber2;
private String member7;
....
}
So when I have cObject I need to set the values of all members in A and B like
aObject.setMember10(cObject.getMember10());
bObject.setMember1(cObject.getMember1());
... and so on for all 10 members
This looks bad(long and in future If i add more members to C,A,B I need to write setters for them). So what I thought was If I have class C extend or implement A and B I can cast it like
A aObject = (A)cObject;
B bObject = (B)cObject;
But the problems are
Java does not allow multiple inheritance
I cannot make A and B as interfaces because I need to set their values. (If I make them as interfaces, their members would become final, which means that I cannot change their values)
I cannot extend one class and implement other. (I then cannot set values of members of the interface)
What can I do now?
Thanks..

As I understand it you have two classes A and B, both with a number of fields, and you want to create a third class C with all the fields of A and B.
As you point out you can't do this with inheritance in Java because multiple inheritance of state is not supported.
You can do something similar using composition instead.
public final class C {
private final A a;
private final B b;
public C(A a, B b) {
this.a = a;
this.b = b;
}
...
void setMember7(String s) {
b.setMember7(s);
}
String getMember7() {
return b.getMember7();
}
...
}
I'm not sure if this is a good idea or what you need though. We would need more information about your use-case.
EDIT
If A and B have fields that are not in C you could make a class A2 with all the fields common to A and C and a class B2 with all the fields common to B and C, like this:
public final class A {
private final A2 a2;
// other fields
public A(A2 a2) {
this.a2 = a2;
}
}
public final class B {
private final B2 b2;
// other fields
public B(B2 b2) {
this.b2 = b2;
}
}
public final class C {
private final A2 a2 = new A2();
private final B2 b2 = new B2();
...
public void setMember7(String s) {
b2.setMember7(s);
}
public String getMember7() {
return b2.getMember7();
}
...
public A getA() {
return new A(a2);
}
public B getB() {
return new B(b2);
}
}

I don't know exactly what you want but i think what you need can be accomplished in the constructor
Class A{
private member1;
private member10;
Class A(){
}
Class A(C cObject){
member1 = cObject.getMember1();
//the rest of member varaibles you want to set
member10 = cObject.getMember10();
}
}
Class B{
private member1;
private member10;
Class B(){
}
Class B(C cObject){
member1 = cObject.getMember1();
//the rest of member varaibles you want to set
member10 = cObject.getMember10();
}
}
to use it :-
B objectB = new B(objectC);
A objectB = new A(objectC);

Related

access variable of upper/wrapper class

I'm a beginner at Java so I don't know if what I'm trying to access is an upper/wrapper class. Basically, I have three classes, A, B and C.
CLASS A.java
public class A{
private String aName;
private B objectB;
}
CLASS B.java
public class B{
private String bName;
private C objectC;
}
CLASS C.java
public class C{
private String cName;
}
Basically, I have a Class A, which has an object of Class B, which in turn has an Object of class C.
I have an instance of an object of class C. How do I access the variables bName and cName from this instane of object C?
Why don't you use getter & setter method for accessing variable bName from instance of c. you can not directly access them as they are private.
"CLASS B.java"
public class B{
private String bName;
public String getbName() {
return bName;
}
public void setbName(String bName) {
this.bName = bName;
}
private C objectC;
}
You can directly access "cName" variable as this variable is the belong to same obejct of c which you are using to get bName.
The easiest solution for getting access to the instance of Class B from Class C would be to add a reference to B in C:
Class C
public class C {
private String cName;
private B bObj;
}
And then use getters and setters in class B:
Class B
public class B {
private String bName;
private C cObj;
public String getBName() {
return bName;
}
public void setBName(String newName) {
this.bName = newName;
}
}
However, do remember that this leads to a circular dependency, which usually is a code smell (it may be OK in this situation though, depending on the overall class hierarchy).
The better option would be to implement the Observer pattern between the classes:
Class C
public class C {
private String cName;
private List<Observers> observers; //if you only need one instance, then
//switch out for a single interface reference
public void requestWrapperName () {
List<String> names = new ArrayList<>();
for(observer: observers) {
names.add(observer.requestName());
}
// code to do what you want with wrapper name
...
}
public void addObserver(Observer observer) {
observers.add(obsersver);
}
}
Observer interface
public interface Observer {
String requestName();
}
Class B
public class B implements Observer {
private String bName;
private C cObj;
// Observer method
public String requestName() {
return bName;
}
}
Now, when you have the instance of C in class B, you can just inject B as an observer into C with cObj.addObserver(this); and then request B's name with the method requestWrapperName();. Thus avoiding having associations both ways :)

Reflect Annotation of an Instance of my own Class

I have several Classes A1,A2,A3 which extend the abstract class myA. These classes have x fields of class B. The fields of class B are annotated with the annotation Test.(Test is available at runtime) How can i get the annotation Test and its value from inside a method of class B.
public class A1 extends myA{
#Test("all")
private B b1;
#Test("none")
private B b2;
#Test("none")
private B b3;
//....
public void interact(){
b2.doSomethingBasedOnMyAnnotation();
}
}
public class A2 extends myA{
#Test("none")
private B b;
//....
}
public class B{
public void doSomethingBasedOnMyAnnotation(){
// How to reach the Annotation from here ?
}
}
#Retention(value = RetentionPolicy.RUNTIME)
#Target(value = ElementType.FIELD)
public #interface Test{
String value() default "all";
}
When you place an annotation on a variable, it becomes a static property of that variable, not of the object you can reach through that variable. Consider:
public class A1 extends myA{
#Test("all")
private B b1=new B();
#Test("none")
private B b2=b1;
//....
public void interact(){
// this
b2.doSomethingBasedOnMyAnnotation();
// is exactly the same as
b1.doSomethingBasedOnMyAnnotation();
}
}
It’s not even valid to assume that there is an annotated variable involved. What about
new B().doSomethingBasedOnMyAnnotation()?
Since fields are resolved at compile-time, there is no abstraction in your desired operation anyway. If you know that you are going to invoke, b2.doSomethingBasedOnMyAnnotation();, you already know which field you’re using and there’s no problem of providing the annotation value of b2 as parameter to the invoked method, rather than expecting the receiver to magically find out. E.g.
public class B{
public void doSomething(String arg){
}
}
public class A1 extends myA{
#Test("all")
private B b1;
#Test("none")
private B b2;
//....
public void interact(){
b1.doSomething(get("b1"));
b2.doSomething(get("b2"));
}
static String get(String fieldName) {
try {
return A1.class.getDeclaredField(fieldName)
.getAnnotation(Test.class).value();
} catch(NoSuchFieldException ex) {
throw new IllegalStateException(ex);
}
}
}
though we could happily work without Reflection:
public class A1 extends myA{
static final String TEST_B1="all";
#Test(TEST_B1)
private B b1;
static final String TEST_B2="none";
#Test(TEST_B2)
private B b2;
static final String TEST_B3="none";
#Test(TEST_B3)
private B b3;
//....
public void interact(){
b1.doSomething(TEST_B1);
b2.doSomething(TEST_B2);
}
}
If you want to make sure that the caller can’t pass the wrong argument by accident, use encapsulation instead:
public final class EncapsulatedB {
final String testValue;
B b;
EncapsulatedB(String value) {
this(value, null);
}
EncapsulatedB(String value, B initialB) {
testValue=value;
b=initialB;
}
public B getB() {
return b;
}
public void setB(B b) {
this.b = b;
}
public void doSomething() {
b.doSomething(testValue);
}
}
public class A1 extends myA{
private final EncapsulatedB b1=new EncapsulatedB("all");
private final EncapsulatedB b2=new EncapsulatedB("none");
private final EncapsulatedB b3=new EncapsulatedB("none");
//....
public void interact(){
b1.doSomething();
b2.doSomething();
}
}

Mockito - how to verify a method call made by an indirect private field object

I am trying to verify a method call made by an indirect private field object. For example
Code to Test:
class A
{
final private B b;
public A(C c, D d)
{
this.b = new B(c,d);
}
public void methodToTest()
{
b.wantToVerifyThisIsCalled();
}
}
class B
{
private C c;
private D d;
public B(C c, D d)
{
this.c = c;
this.d = d;
}
...
public void wantToVerifyThisIsCalled()
{
//do stuff
return;
}
}
I want to verify that b.wantToVerifyThisIsCalled() method was called when I run A.methodToTest();
I tried something like this but this doesn't work:
C c = mock(C.class);
D d = mock(D.class);
A a = new A(C,D);
B b = moc(B.class);
a.methodToTest();
verify(b).wantToVerifyThisIsCalled(); \\<-- This gives me error, wanted but not invoked
How should I verify that this b field object of class A is indeed making that method call ?
There is sadly no setter method and the field object is also marked as final :(
Thank you
That is happening because the B class object on which wantToVerifyThisIsCalled() method is invoked is not your mocked object. You should rather inject the mock object to A.
It would be better if your A class constructor directly takes a B instance rather than C and D, and relying on it to create B class object.
Try modifying your classes as such:
class A {
private final B b;
public A(B b) { this.b = b; }
public void methodToTest() {
b.wantToVerifyThisIsCalled();
}
}
class B {
private final C c;
private final D d;
public B(C c, D d) { this.c = c; this.d = d; }
public void wantToVerifyThisIsCalled() { ... }
}
And then test it like this:
C c = mock(C.class);
D d = mock(D.class);
B b = mock(B.class);// Find a way to set private fields (May be provide setters).
A a = new A(b);
a.methodToTest();
verify(b).wantToVerifyThisIsCalled();

Best way to share updated data between classes in java

I am working on a projects and I have run into a problem, I don't know the best way to share updated data between classes. The current way that I am doing this is by having a static instance of my class in it and having all the other classes change the instance and not the original class.
public class A{
public static volatile instance;
public B b = new B();
public C c = new C();
public D d = new D();
public A(){
this.instance = this;
b.changeData();
}
}
public class B{
public void changeData(){
A.instance.d.changeSomethingInD();
}
}
Now, all the changes that D made to its variables can be accessed by B and C. Is there a better way to do this?
Edit 1: The problem that I have is having updated variables accessible to all the other classes. This was what I was doing before:
public class MainClass extends JavaPlugin{
private RegionLoader rLoader;
private ClassesLoader cLoader;
private MessageHandler mHandler;
private PlayerDates pDates;
public MainClass(){
dirMaker();
mHandler = new MessageHandler(this);
pDates = new PlayerDates(this);
cLoader = new ClassesLoader(this);
rLoader = new RegionLoader(this);
}
//getters and setters
}
But the problem is if the RegionLoader changes somithing within itself, the ClassesLoader won't have the updated variables and will work with the old ones, or would it?
Why not just pass A into the constructor of B. This way you wouldn't need to use static data.
public class A{
public B b;
public C c = new C();
public D d = new D();
public A(){
b = new B(this);
b.changeData();
}
}
public class B{
private A a;
public B(A a){
this.a = a;
}
public void changeData(){
a.d.changeSomethingInD();
}
}
You could also checkout the observer pattern.

Java: how does a component know its owner

Suppose I have a class A and a class B.
public class A {
private B b;
public A() {
this.b = new B();
}
public B getB() {
return this.b;
}
}
public class B {
public String getSome() {
return "Get some!";
}
}
I know I can get B through A, because A has (or owns) B: new A().getB().
But if I have B, can I get A?
Sure, just add routine getA() in you class B, and change the line in your constructor to
public A() {
this.b = new B(this);
}
This of course assumes your class B has a constructor which accepts an A, e.g.,
public B(A a) {
this.a = a;
}
B needs an explicit reference to its owner:
public class B {
private final A owner;
public B(A owner) {
this.owner = owner;
}
public A getOwner() {
return owner;
}
}
And in A:
public A() {
b = new B(this);
}
Nope. There is no such thing as an 'owner' in Java. Any object can be referenced by any number of other objects.
If you need B to always be bound to an instance of A, make B an inner class of A:
class A {
B b = new B();
class B {
String getSome() {
// this will refer to the enclosing A
return A.this.toString();
}
}
}
An inner (non-static) class always has an implicit reference to the enclosing instance and cannot exist without it. In order to instantiate B from outside, you need a nasty syntax: B b = new A().new B();
No you cannot. B has no reference to A.
No.
Class a has reference to class B, but class B has no reference to class A. References are one way only.
No, that's not possible. You're looking for backreferences, but we have to create them in the code if needed.
If you want to collect all referencers to B, you could do this with a constructor or with a factory (pattern) that creates B's. I'll show the factory:
public class B {
private static Set<? extends Object> referencers = new HashSet<? extends Object>();
private B(){} // no public constructor
public static create(Object parent) {
// cooperative approach, the caller should pass "this"
referencers.add(parent);
}
public static remove(Object parent) {
referencers.remove(parent);
}
}
you can also use inner classes
package test;
public class A {
B b = null;
public B getB()
{
return b;
}
public class B {
public A getA()
{
return A.this;
}
}
public static void main(String[] args) {
B b = new A().new B();
}
}

Categories

Resources