How to change values of variables using methods? - variables

I am having troubles incrementing the value of my instance variables. I tried making a method so that for every pet I buy, it will add that much to how many I already have. But when I print dogs variable, it says 0 even though I added 2. I'd appreciate any help. Thanks!
public class myStuff
static int dogs;
static int cats;
public static void main(String[] args) {
myStuff.buy(dogs, 2);
System.out.println(dogs);
}
public static void buy(int pet, int howMany) {
pet = pet + howMany;
}
}

you cant do that in java, since it is pass-by-value

In Java, method parameters are passed by value (which means the value of dogsin your case is passed in the first Place, but never touched). Objects however, are manipulated by reference. So, if you want to increase the number of pets, you could use a class Pet with a value count
public class Pet {
private int count;
public Pet(int count) {
this.count = count;
}
public int getCount() {
return count;
}
public void setCount(int count) {
this.count = count;
}
}
If you then pass an instance of Pet to your buy function and increase the count via setCount, the value will be saved.

Related

PrimaryKey 'id' not set by auto incrementer

I wrote a static class that auto-increments the id of a RealmObject by 1.
public class AutoIncrementKey {
public static int Next(Class<? extends RealmObject> c)
{
Realm realm = Realm.getDefaultInstance();
Number maxId = realm.where(c).max("id");
realm.close();
if(maxId == null)
{ // no object exists, so return 0
return 0;
}
return maxId.intValue() + 1;
}
}
However, when I set the default value of a RealmObject's ID like so:
#PrimaryKey private int id = AutoIncrementKey.Next(PresetSelect.class);
It never works! Specifically the first time it goes to create a new class via realm.createObject(IExtendRealmObject.class) the value is 0, but AutoIncrementKey.Next(...) returns the id as 1!
So id is never set to 1. It's always 0, and trying to create more objects causes it to throw an error "index already exists: 0"
What gives?
The AutoIncrementKey.Next() function IS being called. It IS finding the next key to be 1. The value returned simply isn't carried through though.
Edit:
So now that I've managed to create more than one object in my Realm, I'm finding that setting the id to a default value isn't the only issue.
Setting ANY member of a class extending RealmObject with a default value is IGNORED. Whats the deal with that?
That's because instead of
realm.createObject(IExtendRealmObject.class)
You're supposed to use
realm.createObject(IExtendRealmObject.class, primaryKeyValue)
But I think your method
public class AutoIncrementKey {
public static int Next(Class<? extends RealmObject> c)
{
Realm realm = Realm.getDefaultInstance();
Number maxId = realm.where(c).max("id");
realm.close();
if(maxId == null)
{ // no object exists, so return 0
return 0;
}
return maxId.intValue() + 1;
}
}
Would be more stable as
public class AutoIncrementKey {
public static int Next(Realm realm, Class<? extends RealmModel> c)
{
Number maxId = realm.where(c).max("id");
if(maxId == null)
{ // no object exists, so return 0
return 0;
}
return maxId.intValue() + 1; // why not long?
}
}
If you meet the condition that when you call AutoIncrementKey.Next(realm, Some.class), then a write transaction is in progress.
Hell, you might even add
public class AutoIncrementKey {
public static int Next(Realm realm, Class<? extends RealmModel> c)
{
if(!realm.isInTransaction()) {
throw new IllegalStateException("Realm is not in a transaction.");
}
// continue as mentioned
It should work well for your needs

Is there an OOP convention about private method signatures - directly using fields or getting arguments?

I'd like to know which of the following is a better OOP practice when having private methods. Should the fields be used directly, or given to the method like an argument?
class MyClass {
private int myNumber;
public MyClass(int number) {
this.setMyNumber(number);
}
public void setMyNumber(int number) {
this.myNumber = number;
}
public int getMyNumber() {
return this.myNumber;
}
public int getTransformedNumber() {
return transformNumberInSomeWay1();
// OR
return transformNumberInSomeWay2(this.getMyNumber());
}
private int transformNumberInSomeWay1() {
int number = this.getMyNumber();
<... transformation of the number ...>
return number;
}
private int transformNumberInSomeWay2(int number) {
<... transformation of the number ...>
return number;
}
}
If I'm using the transformation number method for other things than the field myNumber, the second way is better. What about the case when I'm not actually using it for anything else, yet I don't know how will the development of the class go? Should I always do it the second way or let the people who need it, change it later on?

Accesing arraylist property from another class using constructor

So i have a class that makes an array list for me and i need to access it in another class through a constructor but i don't know what to put into the constructor because all my methods in that class are just for manipulating that list. im either getting a null pointer exception or a out of bounds exception. ive tried just leaving the constructor empty but that dosent seem to help. thanks in advance. i would show you code but my professor is very strict on academic dishonesty so i cant sorry if that makes it hard.
You are confusing the main question, with a potential solution.
Main Question:
I have a class ArrayListOwnerClass with an enclosed arraylist property or field.
How should another class ArrayListFriendClass access that property.
Potential Solution:
Should I pass the arraylist from ArrayListOwnerClass to ArrayListFriendClass,
in the ArrayListFriendClass constructor ?
It depends on what the second class does with the arraylist.
Instead of passing the list thru the constructor, you may add functions to read or change, as public, the elements of the hidden internal arraylist.
Note: You did not specify a programming language. I'll use C#, altought Java, C++, or similar O.O.P. could be used, instead.
public class ArrayListOwnerClass
{
protected int F_Length;
protected ArrayList F_List;
public ArrayListOwnerClass(int ALength)
{
this.F_Length = ALength;
this.F_List = new ArrayList(ALength);
// ...
} // ArrayListOwnerClass(...)
public int Length()
{
return this.F_Length;
} // int Length(...)
public object getAt(int AIndex)
{
return this.F_List[AIndex];
} // object getAt(...)
public void setAt(int AIndex, object AValue)
{
this.F_List[AIndex] = AValue;
} // void setAt(...)
public void DoOtherStuff()
{
// ...
} // void DoOtherStuff(...)
// ...
} // class ArrayListOwnerClass
public class ArrayListFriendClass
{
public void UseArrayList(ArrayListOwnerClass AListOwner)
{
bool CanContinue =
(AListOwner != null) && (AListOwner.Length() > 0);
if (CanContinue)
{
int AItem = AListOwner.getAt(5);
DoSomethingWith(Item);
} // if (CanContinue)
} // void UseArrayList(...)
public void AlsoDoesOtherStuff()
{
// ...
} // void AlsoDoesOtherStuff(...)
// ...
} // class ArrayListFriendClass
Note, that I could use an indexed property.

Object creration in Tic tac toe

I am creating a two player game and I want to be able to restrict users from creating additional player objects.
public class Player {
Symbol symbol;
public Player() {
symbol = Symbol.X;
}
}
If I have a public constructor like this, users can keep creating objects and there will be no way to restrict this?
Edit:
Extracting players from an enum
public enum Symbol {
X, O;
}
I want to be able to get the symbol from here and assign it to player object when creating it.
You can use the factory pattern:
class Player {
private static int players = 0;
private Player(...) {
...
}
public static Player newPlayer(...) {
if (players < MAX_PLAYERS) {
players++;
return new Player(...);
}
throw new TooManyPlayersException(...);
}
}

Why protected and private attributes are accessible by same class rather than by the same object?

For example, we have the class Man
If Man.age is protected, then I don't see why chuckNorris (instance of class Man) can change the protected/private attribute age of the object jackBauer (another instance of class Man). He shouldn't be able to do that (IMO).
In my mind, the value of a protected/private attribute is supposed to belong only to the object itself, not the class...
I need some explanation I think, I'm confused.
Matthieu is right. cuckNorris can do jackBauer.age
But there is no problem on that. If you are referencing Man instance attributes inside Man, that means you are coding Man class, so you know what you are doing.
The problem would be if you pass me that Man class and I could access the Man attributes with out knowing how Man class is coded.
Setters and getters may be doing some business logic that I don't know and I don't need to know. But the one who coded Mam does know.
Consider this Java class:
public class Base {
private int a
protected int b;
public Base(int a,int b) {
this.a = a;
this.b = b;
}
public int getA() {
return a;
}
public int getB() {
return b;
}
}
...
Base foo = new Base(1,2);
Base bar = new Base(3,4);
There is no way(maybe except via dirty reflection) the foo instance can change the protected or private variable in bar
You might allow it to if you want,
public class Base {
private int a
protected int b;
public Base(int a,int b) {
this.a = a;
this.b = b;
}
public int getA() {
return a;
}
public int getB() {
return b;
}
public void changeB(int newB,Base other) {
other.b = newB;
}
}
...
Base foo = new Base(1,2);
Base bar = new Base(3,4);
foo.changeB(5,bar);
You can't protect the changeB method from altering stuff inside the other object [*], you just have to be careful about what your program does. With some languages you could have marked the other argument as unchangable , but not in Java - I don't find it a big deal.
[*} You could, by marking all the fields of Base as final, though then not even the instance itself could change the members after the object has been constructed.
A private attribute is accessible only by method in the class.
A protected attribute is accessibe in descendant class only. Therefore an object jackbauer can't modify anything private or protected in an object chuckNorris of class Man. Hope this would help