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 :)
Related
I have two objects A and B:
public class A {
#SerializedName("idProject")
private int id;
#SerializedName("nameProject")
private String name;
//with setter and getters and other methods
}
///////////////////////////////////////////////
public class B {
#SerializedName("idMenu")
private int id;
#SerializedName("nameMenu")
private String name;
//with setter and getters and other methods
}
These objects are filled from a json, which comes from a service. I have no problems to consume the service.
But in another part of my code, I have a method that requires an object like this:
public void method(C c){
....
}
public class C {
private int id;
private String name;
//with setter and getters and other methods
}
How can I pass an object A or B to this method that accepts only objects of type C ?
From what I can see, you want a type casting behavior here. Since you can't cast object A or B to C in Java, you will have to implement methods in A and B that give you the equivalent C object.
class A {
//...
C C() {
return new C(id, name);
}
}
class B {
//...
C C() {
return new C(id, name);
}
}
class C {
//...
C(int id, String name) {
this.id = id;
this.name = name;
}
}
Now you can easily call C() method to get the equivalent class C instance and pass it to the specified method.
method(objA.C());
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();
}
}
//Class defined in external jar
class A{
many methods...
public getId() {};
}
//I want to extends this class and overwrite single method
class MyA extends A{
private int myId;
public getId() {return myId};
}
void main ()
{
A a = Factory.getA(); //External class create the instance
MyA mya = (MyA)a; //runtime Error!! I want to convert A to myA
}
Hi,
I want to extends an instance which I get from external Jar and overwrite a single method getId(). I don't control the creation of the instance so the only solution I got was to pass it to my constructor and init all members manually, example here:
class MyA extends A{
private int myId;
public MyA(A a, int myId)
{
this.myId = myId;
//init all other methods from a.? to this.?
this.setXXX(a.getXXX());
this.setYYY(a.getYYY());
....many methods...
}
public getId() {return myId};
}
Is there a better way?
MyA mya = (MyA)a; //runtime Error!! I want to convert A to myA
Is a an instance of MyA?? You can not convert if it is not an instance of MyA. you get java.lang.ClassCastException.
Rather than getting all data from A in the constructor of MyA (and thus reimplementing it completely), create an Adapter, change the methods you need and in the rest just pass the calls to the original instance of A:
class MyA extends A{
private A adaptee;
private int myId;
public MyA(A adaptee, int myId)
{
this.adaptee = adaptee;
this.myId = myId;
}
// Override the method you need to
#Override
public getId() {return myId};
...
// Override the rest of the methods so they call the adaptee.
#Override
public X getXXX() {
return a.getXXX();
}
#Override
public void setXXX(X x) {
a.setXXX(x);
}
...
}
Then, of course, use it as:
A a = new MyA(Factory.getA(), myId);
... a.getId();
I have three classes.
Class A extends jFrame (Which is the main user interface)
Class B extends jPanel (This one is called to appear inside of the main jFrame)
and Class C to do some file handling and processing.
What I am trying to do is have an object of Class C instantiated in Class A and calling it in Class B.
Here's some sample code:
Public Class A extends javax.swing.JFrame {
Public A(){
C ObjectOfC = new C();
B panelWithButtons = new B();
}
}
public Class B extends javax.swing.JPanel{
String s = ObjectOfC.getName();
}
public Class C{
String name;
public String getName(){
return this.name;
}
}
Is there anyway to get this done? or is it a lost cause?
There are a number of ways to do this, depending on what you are trying to accomplish. You probably want to build either a constructor or a method for B that takes object C as an argument.
Example:
Public Class A extends javax.swing.JFrame {
Public A(){
C objectOfC = new C();
B panelWithButtons = new B(objectOfC);
}
}
public Class B extends javax.swing.JPanel{
String s;
public B (C objectOfC) {
this.s = objectOfC.getName();
}
}
public Class C{
String name;
public String getName(){
return this.name;
}
}
A singleton example as per your comment:
Public Class A extends javax.swing.JFrame {
Public A(){
B panelWithButtons = new B();
}
}
public Class B extends javax.swing.JPanel{
String s;
objectOfC C = C.getInstance();
this.s = objectOfC.getName();
}
public class C {
private static String name;
private static final C INSTANCE = new C();
private C() {}
public static C getInstance() {
return INSTANCE;
}
public static String getName() {
return this.name;
}
}
A singleton example with changing variables (and errors removed from the original code.):
public class A extends javax.swing.JFrame {
public A() {
C objectOfC = C.getInstance();
objectOfC.setName("Bob");
B panelWithButtons = new B(objectOfC);
System.out.println("objectOfC_A:" + objectOfC.getName()); //return "George"
}
}
public class B extends javax.swing.JPanel {
public B (C objectOfC) {
C c2 = C.getInstance();
objectOfC.setName("Fred");
c2.setName("George");
System.out.println("objectOfC_B:" + objectOfC.getName()); //returns "George"
System.out.println("c2: " + c2.getName()); //returns "George"
}
}
public class C {
private static String name;
private static final C INSTANCE = new C();
private C() {}
public static C getInstance() {
return INSTANCE;
}
public String getName() {
return C.name;
}
public void setName (String name) {
C.name = name;
}
}
With this example you can call C.getInstance from any class and they will all be sharing the same instance. However, you must be careful with how you are going to access the object; there are plenty of tutorials out there about multithreading singletons which you will need to do if you plan on modifying data in the C instance from multiple objects at the same time.
Probably a very basic java question.
I have an abstract class, simplifying it:
public abstract class A{
private String value = "A" ; // I want it undeclared, but set it for testing purpouse
public String getValue(){
return value ;
}
}
Then I have a class extending it:
public abstract class B{
private String value = "B" ;
}
So the problem I have is, when creating an instance of B through class A, and calling getValue(), it always return "A":
A b = new B();
b.getValue(); // returns "A"
How can I get B calling super method using his own properties without having to duplicate code? A it is currently too long, and it is extended to many different class that only differs by it properties values and all of them use the same methods that the super class has.
Thanks!
Edit:
Sorry, I wasn't so specific. I have a lot of properties, and some methods to deal with those properties. Extended class change those properties, but I want to use the super methods with the extended class instanced object without having to declare them twice. I'm working with servlets context atributtes if that helps.
Config.java
public abstract class Config {
private String someValue1 ;
...
private String someValuen ;
public void export(ServletContext cxt){
cxt.setAttribute("someValue1", someValue1);
...
cxt.setAttribute("someValuen", someValuen);
}
}
SomeConfig.java
public class SomeConfig {
private String someValue1 = "something" ;
...
private String someValuen = "something else" ;
}
SomeServlet.java
ServletContext cxt = getServletContext() ;
Config config = new SomeConfig();
config.export(cxt);
To make it clear, properties all have different names. I use them from jsp as: ${someValuen}
The reason why it doesn't work is that only methods can be overriden - variable members are hidden instead (if you print value from your B class, it will be "B").
For that specific example I would use a dedicated constructor (which I have made protected to prevent client classes from accessing it):
public abstract class A {
private final String value;
public A() { //for internal / testing use only
value = "A";
}
protected A(String value) {
this.value = value;
}
public String getValue(){
return value ;
}
}
Then B can simply call the relevant constructor:
public class B extends A {
public B() {
super("B");
}
}
EDIT
Example with a ConfigHolder:
public class ConfigHolder {
String value1;
String value2;
String value3;
public ConfigHolder value1(String value1) {
this.value1 = value1;
return this;
}
//same for other variables
}
Then in class A:
public abstract class A {
private final ConfigHolder config;
public A() {
this.config = new ConfigHolder()
.value1("value1")
.value2("value2");
}
protected A(ConfigHolder config) {
this.config = config;
}
public void export(ServletContext cxt){
cxt.setAttribute("someValue1", builder.value1);
...
cxt.setAttribute("someValuen", builder.valuen);
}
}
And in B:
public class B extends A {
public B() {
super(new ConfigBuilder()
.value1("value1InB")
.value2("value2InB"));
}
}
To do this: A b = new B(); B must be a subclass of A
Besides, an abstract class can not be instantiated, ie can not create abstract class objects. The compiler will produce an error if you try to.
public abstract class A{
private String value = "A" ;
public String getValue(){
return value ;
}
}
public class B extends A{
private String value ;
public B(){
value = "B";
}
}
Now you can do B notAbstractClass = new B();
And when doing notAbstractClass.getValue(); it must return "B"
I just figured out a simple way to do it with a constructor and changing the super class properties to protected (thanks to #assylias answer):
Config.java
public abstract class Config {
protected String someValue1 ;
...
protected String someValuen ;
public void export(ServletContext cxt){
cxt.setAttribute("someValue1", someValue1);
...
cxt.setAttribute("someValuen", someValuen);
}
}
SomeConfig.java
public class SomeConfig {
public SomeConfig(){
someValue1 = "something";
...
someValuen = "something else";
}
}