i have an activity say A that is extended by many other activities , i have a variable in activity A which is used by all other sub activities(classes) extending it. I want to know if i can set a value for that variable from a sub-activity such that the change will reflect in all the other subclasses extending Activity A.
i know its a basic question ,i am new to this any help is appreciated.
eg:
Activity A has
public String global = "ABC"
Activity B extent A
display(global); ---> ABC
Activity C extent A
display(global); ---> ABC
Activity D extent A
display(global); ---> ABC
now how can i change global in Activity D such that Activity B and C should also be affected.
Seems like you want a variable whos value persists and remains same throughout.
But since you only want to your inherited classes to be able to update or read the variable, you can do something like this:
class A
{
private static int your_var = 0;
public int get()
{
return your_var;
}
public void set(int a)
{
your_var = a;
}
}
class B extends A
{
}
class C extends A
{
}
In your static void main:
new B().set(101);
new C().get() // this will return value 101.
Note: Here only one copy of variable your_var is created. And since it is private, only the non static getter setter methods will be able to read or modify it. Thus making it accessible only by either the containing class itself or the child class objects.
You need to create a static variable in Activity A.
A static variable is a variable of the class and not of the objects.
You can have a singleton class which can hold global data and when need you can fetch the data from the single commonly shared instance of the singleton class. But there is another better way.
You need a class which sits on top of your activities. In any app we usually do have one such class (may be some Initilizer or main or manager class ) which wires the entities and initiates our application.
In android we have Application class which can hold global data. For reference see Android global variable
try the following:
in class A
public static String global = "ABC";
in class B
public class B extends A {
public static void main(String[] args) {
B b = new B();
A a = new A();
System.out.println(b.global);
System.out.println(a.global);
System.out.println(global);
}
}
alternatively you could try to work with encapsulation: mark the string as private and make the "global" string available through getters and setters. This is often a more flexible solution then working with static variables
http://www.tutorialspoint.com/java/java_encapsulation.htm
Related
So, I have a program where many objects of several different classes need to read some (many) variables from an object of 'class X', to give it a name. A quick and simple way of doing this would be to make a singleton, which wouldn't be X itself but a class it access to. I've done this, and later on it started feeling dirty, and many seem to agree, so I'd like to change my design for this. I haven't found any ideas to replace this pattern, though, just "don't do it" and "pass the data around." I'd like my data to be read-only, though. I haven't found mention of any other patterns.
The best I've got to share these read-only variables, which seems perfectly fine to me, is to have a class SharedVars for the data to share, but in the form of an inner class. It's inside Data, which is an outer class that is able to modify SharedVars, encapsulating what's meant to be read-only for the other classes. Basically, any class that wants to read these variables needs a Data.SharedVars object:
public class Data {
public static class SharedVars {
private int encapsulatedData;
public int getData() {
return encapsulatedData;
}
}
// no one should touch this but Data:
static private SharedVars sharedData;
Data() {
sharedData = new SharedVars();
}
public SharedVars getDataRef() {
return sharedData;
}
// here's where this class (and only this class, whenever it's told)
// modifies the encapsulated data:
void manipulateData() {
sharedData.encapsulatedData = 5;
}
}
One of the classes that depends on this would take this form:
public class Client {
// This class can't access the data directly
// so it'll use Data's getter:
Data.SharedVars vars;
public Client(Data.SharedVars vars) {
this.vars = vars;
// vars.encapsulatedData = 5; // is not allowed, since the field is private (which is what I want)
}
public void go() {
// the proper way to get its hand on the data:
int data = vars.getData();
System.out.println("The data is " + data);
}
}
Main is not needed in this example, but I'll leave it here anyway:
public class Main {
static Data dataControl;
static Client client;
public static void main(String[] args) {
dataControl = new Data();
client = new Client(dataControl.getDataRef());
dataControl.manipulateData();
client.go();
}
}
Is this proper? Or, what are the risks here? Notice I don't want the objects to copy them for themselves, since they'll be changing all the time, and I don't entirely like the idea of having a reference to the 'class X' I've mentioned before.
is it posible to read the "worldInfo" from another class ?
the following is part of the class that holds it:
public abstract class World implements IBlockAccess{
protected WorldInfo worldInfo;
//=====Stuff=====
public World(ISaveHandler par1ISaveHandler, String par2Str, WorldSettings par3WorldSettings, WorldProvider par4WorldProvider, Profiler par5Profiler, ILogAgent par6ILogAgent)
{
this.worldInfo.setWorldName(par2Str);
}
}
i want to use it in my class to get the name. "worldInfo.getWorldName"
EDIT 1:
Ok i created a class in the same package with the World.. "World_Spy.class"
public class World_Spy extends World{
public World_Spy(ISaveHandler par1iSaveHandler, String par2Str,
WorldProvider par3WorldProvider, WorldSettings par4WorldSettings,
Profiler par5Profiler, ILogAgent par6iLogAgent) {
super(par1iSaveHandler, par2Str, par3WorldProvider, par4WorldSettings,
par5Profiler, par6iLogAgent);
}
#Override
protected IChunkProvider createChunkProvider() {
return null;
}
#Override
public Entity getEntityByID(int i) {
return null;
}
String TheName = "";
public void gotIt(){
TheName = this.worldInfo.getWorldName();
System.out.println(TheName);
}
}
But when i call it from the main class it crashes the game..
World_Spy WName = new World_Spy(null, null, null, null, null, null);
Is it about the parameters?
In order to access worldInfo you'll have to extend World but as worldName is set to the second parameter of World constructor, it means you have to know it in your child class, so ..
For the functionality you want, either change the keyword protected to public, or create a public function in the class. It would look something like this:
public String getWorldName(){
this.worldInfo.getWorldName();
}
Actually, protected means it can be used by childclasses but also by any other class in the same package. So yes, you can use it by all classes in the same package even if they're not subclassing the abstract class
The class is abstract, so it cannot be initiated. You can read static variables from this class, but you cannot create object of this class. You can make this variabale as static and then you read it or inherit this class and make object of it or make it non-abstract and make object of it.
This variable holds constant? Make it static.
The field can be accessed directly if one of the following is true:
That another class extends World (inherited protected fields are
visible in derived classes, also World is not final and has non private constructor)
That another class belongs to the same package (protected fields are
visible in classes from the same package, same as package private).
The field can also be accessed through reflection from any other class after setting accessible property to true on that field (as long as security manager permits).
I'm working in a application which has many activities and most of the activities share more than one objects, So I created MyApplication class by extending android Application class to store selected objects to share. But I feel quit uncomfortable while accessing those objects inside provider/helper classes b'coz context is needed in providers to get instance of Application.
So I planned to create static class called SelectionProvider inside MyApplication class to store selected objects, then I can access those in static way without create instance to MyApplication.
MyApplication class with static inner class as follows
class MyApplication extends Application {
public static final String TAG = "MyApplication";
public static class SelectionProvider {
private static UserObj userObj;
private static TownObj townObj;
private static StoreObj storeObj;
public static UserObj getUserObj() {
return userObj;
}
public static setUserObj(UserObj userObj) {
this.userObj = userObj;
}
public static TownObj getTownObj() {
return townObj;
}
public static setTownObj(TownObj townObj) {
this.townObj = townObj;
}
public static StoreObj getStoreObj() {
return storeObj;
}
public static setStoreObj() {
this.storeObj = storeObj;
}
}
}
Is it right approach? if not why?
Will reside the selected objects (which are stored in inner class) in entire application life or will it destroyed anywhere?
This method or a static value elsewhere should work fine and last for the lifetime of the application as long as you don't have multiple processes running that need access to this object. If that's the case, you should use a Service to handle transactions.
I would not design it as an inner class. I would create SelectionProvider (and any other classes you need) as its own separate class, and instantiate it in your MyApplication class' onCreate method.
You should not instantiate the application object as it can be accessed at any time by calling getApplication() and casting it to your application class (e.g. (MyApplication)getApplication(); Then you can access any objects created by the class.
If data persistence is an issue with these classes, consider storing their values in SQLLite or as a Shared Preference, as Android may terminate your application at any time when it is in the background if it needs the resources.
I would create a singleton class of my own:
public class Data {
/* Start of singleton block */
private static Data data = new Data();
private Data(){
}
public static Data getInstance(){
}
/* End of singleton block */
private SelectionProvider selectionProvider;
public SelectionProvider getSelectionProvider(){
return selectionProvider;
}
/* other necessary methods (get, set) and classes below */
}
This way you can access your objects with Data.getInstance().getSelectionProvider().
This will be available during an active application, though you might want to build in some persistant storing of your data for when the user leaves the app for some time to come back later:
public SelectionProvider getSelectionProvider(){
if(selectionProvider == null)
selectionProvider = readSelectionProviderFromPersistantStorage();
return selectionProvider;
}
So I'm trying to cut back on some of the code that's been written. I created a separate class to try this. I have that class working correctly, however the old one uses variables that are now in the separate class. How do I access these variables? Unfortunately I can't share all the code for this, but I can give out small pieces that I think are necessary. Thanks for the help
This is from the old class that I am now trying to bring the variable to: I'm trying to bring "loader" over
// XComponentLoader loader = null;
fixture.execute(new OpenOfficeOpener());
component = loader.loadComponentFromURL("file:///"+System.getenv("BONDER_ROOT") + "/ControlledFiles/CommonFiles/"+spreadsheet, "_blank", 0, loadProps);
You can write getters for the members that you need to be visible outside. Example:
public class MyClass {
private int member1;
private String member2;
public int getMember1() {
return member1;
}
public String getMember2() {
return member2;
}
}
Now both member1 and member2 can be accessed from the outside.
There are a couple of solutions to your problem. What I would suggest is to add a method in your class to return the value to the new program, or pass it as a parameter.
An example of this on a higher level might look like this:
x = newClass.getValX()
It sounds like you're looking for a static field, though if is the case you almost certainly reconsider your current design.
public class YourClass {
private static XComponentLoader loader;
public YourClass() {
YourClass.loader = new XComponentLoader();
}
}
And to access it from another class:
public YourOtherClass {
public void yourMethod() {
YourClass.loader ...
}
}
If loader is static, than do something like:
component = TheOtherClass.loader.loadComponentFromURL( ...
Otherwise, your new class needs a reference to an instance of the other class. You could pass it with the constructor:
public class NewClass {
private OldClass oldClass = null;
public NewClass(OldClass oldClass) {
this.oldClass = oldClass;
}
// ...
fixture.execute(new OpenOfficeOpener());
// assuming, loader is a public field on OldClass.
// a getter (getLoader()) is preferred
component = oldClass.loader.loadComponentFromURL("file:///"+System.getenv("BONDER_ROOT") + "/ControlledFiles/CommonFiles/"+spreadsheet, "_blank", 0, loadProps);
// ...
}
I've you've split functionality into two classes, then you may want to have one class instantiate another.
If you've put your new code in Class B then it might look like this.
public class A {
// Class B instance
B b = new B();
public void doSomething() {
b.loadComponentFromURL("someurl");
}
}
Or if the loader is an instance itself, you could call it like this.
b.getLoader().loadComponentFromURL("someurl");
I am working on a series of classes that all inherit from a single, base, abstract class.
In order to keep track of all of these child classes, I'd like to implement something like a GUID -- for my purposes, it doesn't have to be an actual GUID, just an int that is unique to each instance of a child class. An incremented int is what I'd been hoping to use.
What I'd have liked to do, is implement the following in my abstract class:
abstract class ParentObject{
static int GUID = 0;
//other stuff
}
whereafter each child class, in its constructor, would have myGUID = GUID++;
However, whenever I try this, I get the following error from the Processing IDE:
The field GUID cannot be declared static; static fields can only be
declared in static or top-level types.
Because of how Processing handles class files (everything is an inner class), I can't have static class members. What are my options to duplicate this functionality in other ways?
Edit: This is being done in Processing and the Processing IDE. The ParentObject class is in its own processing file.
Edite2: I have learned that the reason Processing is different from Java is that all Processing classes are Inner Classes. Because of this, I have re-added the Java tag and reformulated the question.
Well, then face it. You can't do it. If you REALLY need it, declare an outer class for handling this piece of code, and call it in the top-level class's constructor.
If you MUST use this hierarchy of innerclass, then you can't do it. Java won't accept it in the way you wan't. You could declare your abstract class as static.
static abstract class ParentObject {
private static int GUID = 0;
}
But I'm almost sure this won't work for you either. So, I suggest to create a new outer class somewhere else to handle it.
public class GUID {
private static int GUID = 0;
public synchronized static void increment() {
GUID++;
}
}
abstract class ParentObject {
ParentObject() {
GUID.increment();
// constructor's stuff
}
}
This may speed down your app (depending on how often you instantiate a class), but not in a significant way.
a static protected method getNextGUID() would work
public abstract class ParentObject{
private static int GUID = 0;
protected static int getNextGUID(){
return GUID++;
}
//other stuff
}
don't forget to synchronize it/use AtomicInteger when you have multiple threads