Java - defining unknown number of variables in an entity - java

I need an entity called DynamicEntity for example, in which I must define an UNKNOWN number of variables with theyr setters and getters. The variables must have a name I want to give them, so for this i got:
The main class:
public class Main {
public static void main(String[] args) {
DynamicEntity dynamic = new DynamicEntity();
dynamic.parseVariable("int");
}
}
And the DynamicEntity class:
public class DynamicEntity {
public void parseVariable(String text) {
String[] tokens = text.split("-");
String variableType = tokens[0];
String variableName = tokens[1];
if (variableType.equals("int")) {
int variableName = 0;
}
}
}
Definetly the variableName will not be accepted due to its defined already.
The thing is that i dont want the variable inside the IF to be called variableName, I want the variable to be called as the whats inside the tokens[1].
And of course creating setters and getters for every new variable added, which i have no clue what to do for this.

You can benefit from the Map structure. Where as the key you put the name of your member and as value the value for it.
A simple example of concept:
class Dynamic {
private final Map<String,Object> members = new HashMap<>();
public void setMember(String name, Object value) {
members.put(name,value);
}
public Object getMember(String name) {
return members.get(name);
}
}

Related

Java Inheritance: How to override instance variables/fields from parent class?

Update: I can change the variables from being private, static, or final.
I have a parent class and a child class. I want to re-use a method in the parent class. Normally, this is as easy as super.methodFromParentClass() and you're done. However, when I do this, the method I want to re-use is using instance variable data from the Parent class, which is wrong or rather, I do not want this behavior. I have DIFFERENT initialized data in the child class that needs to get passed into the method I want to reuse. If you look at the method I want to re-use (below is just an example to make it simple, but the idea is the same), I am creating multiple objects in there that use the instance variables of the class its called in. So you can see why when I call super.methodIWantToReuse it won't work, because it will take the Parent data and pass it into the objects, even though I really want it to pass the data I initialize in the child class. My real example is also creating way more objects and I have way more instance variables, so I really want to re-use this code (DRY principle) if at all possible.
How can I get around this? Would using getters i.e. getFirstName() and overriding them in the Child class, thus using Runtime Polymorphism when I call super.methodIWantToReuse(), would grab/use the Child class instance variable data be the only way???
public class ParentClass {
private static final String firstName = "Billy Ray";
private static final String lastName = "Cyrus";
private static final int age = 58;
private static final String city = "Hunstville";
public boolean methodIWantToReuse() {
Object1 obj1 = new Object(firstName, lastName);
Object2 obj2 = new Object(age,city);
Object3 obj3 = new Object(obj1, obj2);
Object4 obj4 = new Object(obj3);
// Passing in the objects created above as argument, which have the Parent instance variable data
return someRandomMethodHere(obj4);
}
public class ChildClass {
private static final String firstName = "Miley";
private static final String lastName = "Cyrus";
private static final int age = 27;
private static final String city = "Los Angeles";
public boolean methodIWantToReuse() {
// DOESN'T WORK CORRECTLY, because ends up using the instance variable data of PARENT class, but it
// needs to use CHILD class instance variable data
super.methodIWantToReuse();
}
Your parent class instance variables are Private to that, so you can't update them from Child class. So rather you use parameterize method or create Protected setter/getter for instance variables (or protected variable itself). In you your case the variables are final so you actually can't even update them. So technically that's not possible to use child class variables in parent class.
If you update your variable to protected and remove static/final modifiers (as you mentioned in comments that you can). Before calling method from parent class, update variable data before calling super method. You can do it as below:
Approach 1 : Updating data in parent class before calling parent class method.
Parent Class:
public class ParentClass {
protected String firstName = "Billy Ray";
protected String lastName = "Cyrus";
protected int age = 58;
protected String city = "Hunstville";
public boolean methodIWantToReuse() {
// Passing in the objects created above as argument, which have the Parent
// instance variable data
Object1 obj1 = new Object(firstName, lastName);
Object2 obj2 = new Object(age,city);
Object3 obj3 = new Object(obj1, obj2);
Object4 obj4 = new Object(obj3);
return someRandomMethodHere(obj4);;
}
}
Child Class:
public class ChildClass extends ParentClass {
protected String firstName = "Miley";
protected String lastName = "Cyrus";
protected int age = 27;
protected String city = "Los Angeles";
public boolean methodIWantToReuse() {
// Update data in Parent class first
super.firstName = firstName;
super.lastName = lastName;
super.age = age;
super.city = city;
return super.methodIWantToReuse();
}
}
Approach 2 : If you want to use parameterized method to make it stateless, you can do it as below:
Parent Class:
public class ParentClass {
protected String firstName = "Billy Ray";
protected String lastName = "Cyrus";
protected int age = 58;
protected String city = "Hunstville";
public boolean methodIWantToReuse() {
return methodIWantToReuse(this.firstName, this.lastName, this.age, this.city);
}
public boolean methodIWantToReuse(String firstName, String lastName, int age, String city) {
// Passing in the objects created above as argument, which have the Parent
// instance variable data
Object1 obj1 = new Object(firstName, lastName);
Object2 obj2 = new Object(age,city);
Object3 obj3 = new Object(obj1, obj2);
Object4 obj4 = new Object(obj3);
return someRandomMethodHere(obj4);;
}
}
Child Class:
public class ChildClass extends ParentClass {
protected String firstName = "Miley";
protected String lastName = "Cyrus";
protected int age = 27;
protected String city = "Los Angeles";
public boolean methodIWantToReuse() {
// Update data in Parent class first
return super.methodIWantToReuse(this.firstName, this.lastName, this.age, this.city);
}
}
NOTE: It's not good practice to keep local variables name same as the class level variables. But kept it here same for just understanding.
You can not override fields of a class. Only methods can be overridden. In your case you have to use getters and override them in sub class.
In case you really mean instance variables instead of your static variables (or class variables) as shown in your example, you could make them accessible for your subclass by changing the access modifier and removing the final keyword.
If, however, you actually mean static variables, you cannot reassign them in each subclass as they would all share the same static variables defined by the ParentClass, meaning the last loaded class would be the only result you get by calling your ParentClass#methodIWantToReuse.
Best would be to use OOP to your advantage by instantiating new individual objects with the required arguments, and using them.
By this I mean instead of doing this:
public class Example {
public static class ParentClass {
protected String name;
protected int age;
public ParentClass() {
name = "The parent";
age = 35;
}
public String methodIWantToReuse() {
return name + " is " + age + " years old.";
}
}
public static class AChildClass extends ParentClass {
public AChildClass() {
name = "Alice";
age = 13;
}
}
public static class AnotherChildClass extends ParentClass {
public AnotherChildClass() {
name = "Bob";
age = 21;
}
}
public static void main(String[] args) {
// Prints "The parent is 35 years old."
System.out.println(new ParentClass().methodIWantToReuse());
// Prints "Alice is 13 years old."
System.out.println(new AChildClass().methodIWantToReuse());
// Prints "Bob is 21 years old."
System.out.println(new AnotherChildClass().methodIWantToReuse());
}
}
Do this:
public class Example {
public static class ParentClass {
protected String name;
protected int age;
// Variables instantiated here to not cause confusion
public ParentClass() {
name = "The parent";
age = 35;
}
public String methodIWantToReuse() {
return name + " is " + age + " years old.";
}
}
public static class ChildClass extends ParentClass {
public ChildClass(String name, int age) {
this.name = name;
this.age = age;
}
}
public static void main(String[] args) {
// Prints "The parent is 35 years old."
System.out.println(new ParentClass().methodIWantToReuse());
// Prints "Alice is 13 years old."
System.out.println(new ChildClass("Alice", 13).methodIWantToReuse());
// Prints "Bob is 21 years old."
System.out.println(new ChildClass("Bob", 21).methodIWantToReuse());
}
}
This should also be along the lines of the DRY principle, as you want to reuse your code as efficient as possible instead of coding technically the same over and over again.
As you can see, there was no need for me to override ParentClass#methodIWantToReuse or call the ChildClass' super's implementation.

Duplicate variables (null copy) in loop?

I've never seen this before.. I have the following code, a simple nested loop assigning an object from one ArrayList to an object of another.
But, inside the inner loop, the object has some (not all) duplicate variables with null values?!? What am I doing wrong?!?
The first image shows the local variable "member", a reference to an object inside the ArrayList "members". This is the object with duplicate variables with null values.
The second image show the other object "offer", looking like one would expect.
Code below. Help?
public static void setMembersForOffers(ArrayList<WPMemberPost> members, ArrayList<WPOfferPost> offers)
{
int memberCount = members.size();
int offerCount = offers.size();
for (int i=0; i<offerCount; i++)
{
WPOfferPost offer = offers.get(i);
if (offer.memberIdentifier != null)
{
for (int j=0; j<memberCount; j++)
{
WPMemberPost member = members.get(j);
String id = member.identifier; // NULL?!? (Expected "436")
if (offer.memberIdentifier.equalsIgnoreCase(id))
{
offer.member = member;
break;
}
}
}
}
}
Of course two variables with the same name can exist in an inheritance hierarchy
Try this code and make a breakpoint in the main method at System.out.println(subclass);.
In the debugger you will see that the variable exists two times, because it is defined in Base and Subclass.
public class Main {
public static void main(String[] args) {
Subclass subclass = new Subclass();
subclass.someString = "test";
System.out.println(subclass);
}
private static class Base {
public String someString;
}
private static class Subclass extends Base {
public String someString;
}
}

Java Referencing Abstract Classes

I am trying to create a game in Java and within this game I am trying to implement a quest / mission system. I have come up with an idea to do this, but I am not sure how I would reference the quests or even if it would work at all. It works as such:
I have an abstract class which defines all of the variables and has a few simple methods. The file resembles this:
public abstract class Quest {
public String name = null;
public int id;
public abstract int getPrerequisite() {
return this.id-1;
}
}
I then have a few files that set values for these variables like the example below.
public class MyFirstQuest {
name = "A quest";
id = 0;
}
I'm not sure if it is possible but is there any way that I could reference the files like so:
Quest MFQ = new MyFirstQuest();
System.out.println(MFQ.name);
or
Quest[] quests = new Quest[10];
quest[0] = new MyFirstQuest();
just replace
public class MyFirstQuest {
name = "A quest";
id = 0;
}
by
public class MyFirstQuest extends Quest{
public MyFirstQuest(){
name = "A quest";
id = 0;
}
}
and there are some tips :
use private variables and use getters like this public String
getName(){return name;}
remove the abstract of the method getPrerequisite

How do I allow vars to be accessed by any class/method?

import javax.swing.*;
class Person {
public String name;
public static void main(String[] args) {
new Person().enter();
}
void enter(){
Person a = new Person();
String first = JOptionPane.showInputDialog(null,"Enter your first name");
a.name = first;
new la().a();
}
}
class la{
void a(){
Person a = new Person();
System.out.println(a.name);
}
}
As you can see what I'm trying to do here is to set global var 'name' from the JOption input and to then be able to access 'name' with the new inputted var, from other classes later on. Since the workings of the classes later on depend on that var 'name'. Now I know I can simply pass these on through constructors to the relevant classes and avert this problem, but I want to know if this way is possible at all ?
You're example won't achieve what you are trying to achieve.
You create a new instance Person in Main, assign it a new, then create a new instance of la, which creates it's own instance Person
There is no coalition between these various instances.
public static void main(String args[]) {
String first = JOptionPane.showInputDialog(null,"Enter your first name");
// You should be checking the return result, but any way...
Person person = new Person();
person.name = first;
La la = new La(person);
}
public class La {
public La(Person person) {
System.out.println(person.name);
}
}
Right now by not specifying that your class is Public you are setting it as Default. Default is package private so classes in other packages will not have access to this class's public vars.
Declare the class as Public and set any global vars to Public and they will be accessible.

Java cannot find symbol errors even though class and parameters has been defined?

I'm wondering what I'm doing wrong with this: Currently testing the StringDirective class, which is supposed to parse the input string for the name of the String variable to be created. I was thinking I've set the TPLString class up correctly but get a whole boatload of cannot find symbol errors on multiple lines-- are the parameters I passed in wrong? This code is supposed to parse a String, split it in two parts, parse it for a String variable name, and then assign it an empty string as a value for now, and then store the information about the variable's name and value in a HashMap.
public class StringStatement implements Directive
{ /** StringStatement implements the STRING keyword as defined in class TPLString.
* This keyword declares a String variable.
* A declared String is empty when first instantiated.
*/
public void execute(String[] parts)
{
//instantiate a TPLString
String temp=parts[1];
String[] placeholder = temp.split("[\\s+]");
String name=placeholder[0];
String value;
variables.addVariable(name, value);//add variable to variables hashmap
}
}
//variable classes
abstract class TPLVariable
{
String name;
TPLVariable(String s)
{
name = s;
}
}
class TPLInt extends TPLVariable
{
int intValue;
TPLInt(String s, int v)
{
super(s);
intValue=v;
}
}
class TPLString extends TPLVariable
{
String stringValue;
TPLString(String s, String str)
{
super(s);
stringValue=str;
}
}
//add to variables HashMap
class TPLVariables
{
private Map<String, TPLVariables> variables = new HashMap<String, TPLVariables>();
public void addVariable(String name, String value)
{
// Parses the declaration String, create a TPLVariable of the appropriate type
// and add it to the map using the variable name as the key
if(value.charAt(0)=='"')
{
TPLString stringDeclaration= new TPLString(name, value);
variables.put(name, TPLString(name, value));
System.out.println(name+ " hex0");//debug
System.out.println(value+ " hex1");//debug
}
else
{
TPLInt integerDeclaration= new TPLInt(name, value);
variables.put(name, TPLInt(name, value));
System.out.println(name+ " hex2");//debug
System.out.println(value+ " hex3");//debug
}
}
TPLString(name, value) is not a correct syntax.
If you want a new TPLVariable, you should add new keyword before it.
variables.put(name, new TPLString(name, value));
If you want to reference previous variable you declare, you should use it's name
TPLString stringDeclaration= new TPLString(name, value);
variables.put(name, stringDeclaration);
I suggest you can follow SSCCE principle to post question next time

Categories

Resources