Accessing a parents methods and variables correctly? - java

So this may be a very simple question that I'm overthinking but if I do something like the following:
class A{
public String test_string = "before (default)";
public A(){
B b = new B(this);
}
public void testA(){
this.test_string = "after (new)";
}
}
where B is:
class B{
private A parent;
public B(A mParent){
parent = mParent;
}
private void testB(){
System.out.println(parent.test_string);
}
}
Would that allow me to still access the same instance of A (all of its public fields and methods)? If I called A.testA() from another class somewhere else on that specific instance of A, would the B that was constructed in that A's constructor's testB function return the "after (new)" string? Or would that be a copy of A because doesn't java assign by value, not reference? Is there a better way of doing this? Am I just over complicating the issue?
I wasn't sure what to search for so I couldn't find other questions that answered my question.
Thanks in advance!

It is breaking encapsulation to have public fields in a class and access them. Please wrap them in accessors if you must have them.
Besides, if you stick by the "tell don't ask" rule, then actually your code would be:
private void testB(){
parent.printTestString();
}
and in A you'd have
public void printTestString(){
System.out.println(test_string);
}
In answer to your question
"Would that allow me to still access the same instance of A (all of its public fields and methods)? If I called A.testA() from another class somewhere else on that specific instance of A"
Yes it would if it was the same instance.
"would the B that was constructed in that A's constructor's testB function return the "after (new)" string?"
Yes it would, the member field would be pointed to a new string reference so any usage of that instance of A would get the same value (threadsafety notwithstanding)

Yes, it is the same instance. It works like shown in this image:
So, calling a method over b.parent.foo, it is called over the same instance passed in the constructor.

Related

what is the best way to get other class of object reference??

Sorry, i can't give better title.I have two class A and B.A class is singleton class.it always gives same object to whoever want it.Here B class always want that A object refenence. check follow code
class B
{
private A a;
B(){
this.a=A.getAObject();
}
public void process(String[] args)
{
a.sendData();//line 1
(or)
A.getAObject().sendData();//line 2
}
}
which is best way as mentioned above line 1 or line 2 as performance wise like that??
You can reference of one class to another class by making reference of the other class
In your code you do something like this :
class B {
private A a;
B(A a){
this.a=a; //refernce of a
}
public void display(){
a.getA(); //display method of a
}
}
class A{
public void getA(){
....
}
}
In many cases the differences will be insignificant.
But there would be scenarios like where you have to create a lot of instances of B. So in those scenarios there would be a performance impact since introducing a filed to that class means taking more memory when creating a instance.
If it is not a scenario like that, I think its better to assign it to a variable, since it will improve the readability of the code if you use that instance often in the class.

How can i access one class variable into other

There are to separate classes class One and class Two. Both of classes are in same package. I want to access one class data into other class how can i access variable data. My program is very lengthy ,I just want the logic of this.Thanking you in advance.
Class A.java
public class A
{
public static void main(String ar[])
{
int a=100;
}
}
Class B.java
public class B extends A
{
public static void main(String m[])
{
A obj=new A();
System.out.println("Variable of class A is :"+ obj.a);
}
}
I have done this thing to get access like i declared variable a as Static so that i can directly get access but it's not working. and when i am compiling B.java It giving me error
cannot find symbol at := System.out.println("Variable of class A is :"+ obj.a);
And
Illegal start of expression (when i am delaring variable a as public)
:-(error)public int a=100; [in class A].
Why are you using the static main method? Besides that the field a is local and not accessible outside the scope. Use this instead.
public class A
{
public int a;
public A()
{
a=100;
}
}
You don't have two true object-oriented classes above, but rather little more than two receptacles for static main methods. To combine code from two classes well, you will want to scrap that code and make OOP-compliant classes, complete with instance fields and methods. For more on this, check out the OOP section of the Java tutorials: link to OOP tutorial.
First, get rid of main() in A. You only want one main() in your application, and it's in B (since the one in A doesn't actually do anything):
public class A {
}
Now, you want A to have a class-level int value:
public class A {
private int a;
}
And you want it to have a default value of 100, yes? A constructor is a good place to do that:
public class A {
private int a;
public A() {
this.a = 100;
}
}
Now any time you do this:
A obj = new A();
you will have an object with a value. In order to access that value from outside that object, you need a "getter":
public class A {
private int a;
public A() {
this.a = 100;
}
public int get_a() {
return this.a;
}
}
Now in B (or anywhere, really), you can create an instance of A and access that value by using the "getter":
A obj=new A();
System.out.println("Variable of class A is :"+ obj.get_a());
Semantically, don't think of it as "accessing a variable from another class". Instead, think of what your objects are and what they represent. If it were a physical, real-world object which internally contained some kind of value.
When you create an instance of that object, the instance would internally have that value somewhere. From the outside of that object, it doesn't really matter how that value is internally maintained. There just needs to be some kind of interface to see the value. Which is what the "getter" method does.
One-liner answer: To access a variable outside a class, make it class-level. You have written a method-level variable that's accessible only inside that scope (method).
To elaborate:
There are to separate classes class One and class Two. Both of classes are in same package. I want to access one class data into other class how can i access variable data.
So basically you know that to by extending, you should be able to access parent class data into your subclass. For that, simply make the data in your parent class as class level.
class A {
int var = 10; //class level, but non-static, so to access you need A object
void method() {
int var = 20; //this is method local and can not be accessed outside
}
}
public class B extends A {
public static void main(String[] args) {
A aObj = new A();
System.out.println(aObj.var);
}
}
Illegal start of expression (when i am delaring variable a as public)
Its illegal. Because access modifiers like public, private etc. are applicable to class-level stuff like the first var or the main method in class B you see.
Said that:
You need to immediately go here: https://docs.oracle.com/javase/tutorial/
rather than just trying to run some classes when you lack language basics.

Having unknown error with Getters and Setters

I have some code that is utilising a variable from one class to another, I am using getters and setters and I checked that when i setClassName() before changing class that it works but i can't acces it properly from the other class, it return's null.
http://pastebin.com/6AP4c6ii -- CLASS A
http://pastebin.com/QCnWDnYs -- CLASS B
There is more code but it's relatively messy and long, im a noob to this and am working on ways to improve my coding and this is just a little project.
Any help appreciated.
It returns null because you actually never set the variable.
CLASSA Ccs = new CLASSA(gsm);
#Override
public void init() {
getFirstCompanion();
getVariables();
}
private void getVariables() {
classChoice = Ccs.getClassChoice();
System.out.println("Init, class is " + classChoice); //here, this returns as nothing, not null, nothing
}
You see, you are creating a totally new object when declaring new CLASSA(gsm), any changes you made to a previous object is not reflected, because this a fresh new object, therefore its chosenClass attribute, is initialized to null. Since you are getting the value without previously setting it, you are getting a null value
I hope I made myself clear enough, and I hope I helped you!
Edit
If you want to share the same variable across multiple instances, you can make them static:
private static String chosenClass = "";
public static void setChosenClass(String chosenClass)
{
this.chosenClass= chosenClass;
}
public static String getChosenClass()
{
return chosenClass;
}
Does "my code to go to the next class" mean you instantiate class B? Because then Class B might have another instance of A then the one you set the class choice on.

Accessing instance variables from another class from a static method

I have the following code:
public static boolean isRelated(Animal first, Animal second){
boolean result=false;
if(first(parentA).equals(second(parentA)))
result=true;
return result;
}
basically, I need to be able to access the parent A instance variable that is in the Animal class from this static method.
I understand that, to access instance variables in a static method, you need to create an object but I already have 2 brought in.(Parent A and Parent B)
Could you guys tell me what the problem here is?
In order to access instance variable, you need to use an instance. You don't have to create it each time you need it, as long as you have one.
And for your code:
if(first.getParentA().equals(second.getParentA()))
In this case you need to make sure than first.getParentA() isn't null before comparing (or else you'll get NPE)
if(first(parentA).equals(second(parentA)))
basically, I need to be able to access the parent A instance variable that is in the Animal class from this static method.
That is not the correct syntax to access instance members
should be
if(first.parentA.equals(second.parentA))
More over use setters and getters to access the data such that
public class Animal {
private String parentA;
// code
public String getParentA() {
return parentA;
}
public void setParentA(String parentA) {
this.parentA = parentA;
}
}
}
Then use the line if(first.getParentA().equals(second.getParentA()))
Static methods are created in method area, and is the first to be created. Instance variables are created in heap after static methods are created. Hence, accessing instance variables directly is not possible. Always make use of an object to access such variables.

Difficulty in extending the third party class

I have the following classes
class A{
private String name;
private int value;
public A(String n, int v){
name = n;
value = v;
}
public void print(){
System.out.println(name + " " + value);
}
}
class B extends A{
public B(String n, int v){
super(n,v);
}
}
When i say B b = new B("new object", 1);
it created an object of type B with name = new object and value = 1. and printed the same on calling print() method. But though it has those values in it, i cant access them through B's methods. Is it the limitation of encapsulation or inheritance.
Because the same situation is there in front of me where i need to extend a third party class and the properties in this class which are private but are needed in the extending class, and there are no setters and getters for the private members.
So what do i have to do?
If the variables are private, they are meant to be so - the designer of the class has decided they are not needed.
However, the designer of that class may have been wrong. That's not a good thing to assume in the first place, but if you really need them, you can call:
Field field = getClass().getSuperclass().getDeclaredField("privateFieldName");
field.setAccessible(true);
Object value = field.get(this);
If the variables are private, then you can't access them outside of the class where they are defined.
You could shadow those fields in A by assigning them to fields in class B's constructor. However, if the values are changed in A you will not know about those changes in class B and vice versa.
I assume you need to extend A because there are other things that expect an A and you want to be able to substitute a subtype?
I also assume you have the source code of A, as you're showing it above?
A solution (not a great solution, because you'll run into issues in dealing with upgrades to the third party class, but possibly workable one) is:
Copy the entire source of A to a new file B.
Change the class definition and constructor to:
public class B extends A {
private String name;
private int value;
public B(String n, int v){
name = n;
value = v;
}
Now you have a subclass that overrides every method of the parent class (with exactly the same code).
Modify B as required.
Or, better yet, make the instance variables in B protected, and then create a third subclass C extending B, and put your changes in that:
public class B extends A {
protected String name;
protected int value;
public B(String n, int v){
name = n;
value = v;
}
...
}
public class C extends B {
public C ( String n, int v) {
super(n, v);
}
Now your subclass can access the parent's instance variables directly, while the grandparent's (A) are completely hidden and irrelevant. You've also kept your code separate from the third party code, meaning you'll have an easier time handling updates and upgrades from the third party.
If the private members are truly needed in the subclass, then your problem indicates poor design of the superclass. Classes that are inheritable (as "A" is because it has no "final" qualifier) must be carefully designed to avoid problems such as the one you've encountered. The best solution would be to rework class A to better support inheritance.
Failing that, the other answers are appropriate.
May be the third party class didn't provide any getters/setters by design. Reexamine your need for extending the class. Instead of extending the class can you achieve what you want by using composition instead of inheritance ?
Is there a interface which the third party class implements, check if your requirements can be achieved by using the Decorator pattern.

Categories