Let's say that I have property/field of a class Character that's called position which is basically two coordinates:
public class Character {
int[][] position;
public Character(int[][] position) {
this.position = position;
}
}
Let's say that I want characters to be able to interact if and only if their position is exactly the same, something like this:
public void interact() {
for character in all_characters {
if (this.position = character.position) {
// Do something
}
}
}
How would I get an array of all instantiated objects from that class, i.e. all_characters above.
Regarding getting properties.
It should be available if it's not private.
In java there is a practice to make properties private and implement public getter method for them.
Let me show you an example.
And regarding comparison.
I would suggest try to use deepEquals static method of Arrays class.
http://docs.oracle.com/javase/7/docs/api/java/util/Arrays.html#deepEquals(java.lang.Object[],%20java.lang.Object[])
file Character.java
public class Character {
private int[][] position;
public Character(int[][] position) {
this.position = position;
}
public int[][] getPosition() {
return position;
}
}
file Worker.java
public class Worker {
List<Character> all_characters = new ArrayList<Character>();
// all_characters.add(ch1);
// all_characters.add(ch2);
// all_characters.add(chN);
public void interact() {
for (chLeft in all_characters) {
for (chRight in all_characters) {
if(java.util.Arrays.deepEquals(chLeft.getPosition(), chRight.getPosition())) {
// Let's interact :)
}
}
}
}
This is not automagically done. You must keep track of entities, possibly decorating them with interfaces to be able to track such things, for example:
class Position
{
private int[][] data;
public boolean equals(Position other) { .. }
}
interface Positionable
{
public Position getPosition();
}
class Character implements Positionable
{
private Position position;
#Override public Position getPosition() { return position; }
}
class EntityGroup
{
List<Positionable> entities;
public Optional<Positionable> findEntityInSamePosition(Positionable p) {
return entities.stream().filter(p2 -> !p.equals(p2) && p.getPosition().equals(p2.getPosition())).findfirst();
}
}
Related
I have an array list of Enemies and each enemy kind extends enemy. Now I don't wan't every same enemy kind to share all their stats, but I base my enemy selection of another array list. So I think the way to go would be to get the object of the array list containing all the options and then changing them to new Instances of the same class. My question is, how would I do that? Or do you guys have a better approach?
For easy of understanding here's what I mean abstracted
class shop{
ArrayList<Enemy> allEnemies;
}
class generator{
ArrayList<Enemies> selectedToGenerate = based on some of allEnemies
for(Enemy x : selectedToGenerate){ // i know this wouldn't work
x = newInstanceOf(x.getNonenemyThereforeChildclassClass());
}
}
hope this explains what I mean. Appreciate your time!
You can add a Builder to your Enemy.
abstract class Enemy {
private int strength;
public Builder<Enemy> getBuilder();
public static class Builder<T extends Enemy> {
int str;
public Builder<T> copyValues(T enemy) {
str = enemey.strength;
return this;
}
public Builder<T> strength(int s) {
str = s;
return this;
}
protected void fillValues(T toFill) {
toFill.strength = str;
}
protected abstract T createInstance();
public T build() {
T result = createInstance();
fillValues(result);
return result;
}
}
}
This Builder can create instances of your Enemy and fill it with values. For subclasses, you can extend the Builder by allowing it to fill more values.
class EnemyA extends EnemyA {
private int speed;
public Builder<EnemyA> getBuilder() {
return new Builder();
}
class EnemyABuilder extends Builder<EnemyA> {
int speed;
public EnemyABuilder copyValues(EnemyA enemy) {
super.copyValues(enemy);
speed = enemy.speed;
}
public EnemyABuilder speed(int s) {
speed = s;
return this;
}
protected void fillValues(EnemyA toFill) {
super.fillValues(toFill);
toFill.speed = speed;
}
protected EnemyA createInstance() {
return new EnemyA();
}
}
}
Now, you can create copies of the enemies by using their builders:
for(Enemy x : selectedToGenerate){ // i know this wouldn't work
Builder<? extends Enemy> builder = x.getBuilder();
builer.copyValues(x);
Enemy copy = builder.build();
}
As an additional bonus, you can use the builder to quickly create different versions of the same enemy.
EnemyA.Builder base = new Builder().strength(10);
EnemyA withSpeed1 = base.speed(1).build();
EnemyA withSpeed2 = base.speed(2).build();
EnemyA withSpeed3 = base.speed(3).build();
I have two classes: Fish and Plant. They do not inherit from any classes.
But both of them have one method called isAlive() which have the same implementation details. Now I have a list of fish and another list of dog and I need to remove dead fish and dead dog. I want my method to have same name but it is not possible without adding additional field to method signature. Is it possible I do not need to write additional chunk of code which does the same as the last chunk of code?
Below is the code. For class Model, Fish and Plant are two data members and they are ArrayList of Fish and Plant objects.
Is there any way I can write only one method called count and I do not need to add additional field to my method signature or modify my return type?
public class Fish{
public boolean isAlive(){
if(this.size > 0){
return true;
}
return false;
}
}
public class Plant{
public boolean isAlive(){
if(this.size > 0){
return true;
}
return false;
}
}
public class Model{
private int countDeadFish() {
int totalCount = 0;
for(Fish aFish : this.fish) {
if(aFish.isAlive() == false) {
totalCount += 1;
}
}
return totalCount;
}
private int countDeadPlants() {
int totalCount = 0;
for(Plant plant : this.plants) {
if(plant.isAlive() == false) {
totalCount += 1;
}
}
return totalCount;
}
}
If you do not want to use inheritance, then you can use a common method:
public class AliveChecker {
public static boolean isAlive(int size) {
return size > 0;
}
}
public class Plant{
public boolean isAlive(){
return AliveChecker.isAlive(this.size);
}
}
public class Fish{
public boolean isAlive(){
return AliveChecker.isAlive(this.size);
}
}
Since Fishand Plant do not inherit from anything yet you can consider creating a superclass and extend from it:
public class LivingThing {
protected int size = 1;
public boolean isAlive() {
return size > 0;
}
}
public class Plant extends LivingThing {
}
public class Fish extends LivingThing {
}
This example uses inheritance to classify Plantand Fish into the superclass LivingThing. You can set the size for example in the constructor of the Plant or an instance method:
public class Plant extends LivingThing {
public Plant(int size){
this.size = size;
}
}
Your Model could then be:
public class Model{
private int countDeadFish() {
return countDead(this.fish);
}
private int countDeadPlants() {
return countDead(this.plants);
}
private int countDead(ArrayList<LivingThing> things) {
int totalCount = 0;
for(LivingThing thing: things) {
if(!thing.isAlive()) {
totalCount++;
}
}
return totalCount;
}
}
Use interface
public interface LiveObject {
boolean isAlive();
}
public class Fish implements LiveObject {
public boolean isAlive(){
if(this.size > 0){
return true;
}
return false;
}
}
public class Plant implements LiveObject {
public boolean isAlive(){
if(this.size > 0){
return true;
}
return false;
}
}
public class Model{
private int countDead(Collection<LiveObject> objects) {
int totalCount = 0;
for(LiveObject obj : objects) {
if(obj.isAlive() == false) {
totalCount += 1;
}
}
return totalCount;
}
private int countDeadFish() {
return countDead(this.fish);
}
}
Based on the comments it seems you can't modify Fish or Plant. Here's an approach to reduce duplication in countDead<Something> methods which does not require this.
Basically you want to count items in an array which satisfy certain criteria. With Java 8 you can capture this criteria in a predicate using lambdas or method references. You do not need inheritance or implementation of a certain interface for this.
private long countDeadFish() {
return countDeadItems(this.fish, Fish::isAlive);
}
private long countDeadPlants() {
return countDeadItems(this.plants, Plant::isAlive);
}
private <T> long countDeadItems(Collection<T> items, Predicate<? super T> isAlive) {
return items.stream().filter(isAlive.negate()).count();
}
You could create a utility method (in a utility class somewhere):
public final class Liveliness {
private Liveliness() {
}
public static boolean isAlive(final IntSupplier sizer) {
return sizer.getAsInt() > 0;
}
}
Your method then becomes:
public boolean isAlive(){
return Liveliness.isAlive(this::getSize);
}
Alternatively, use an interface Life:
public interface Life {
int getSize();
default boolean isAlive(){
return getSize() > 0;
}
}
This way, adding a getSize method and inheriting from Life will add the method.
Note, avoid the following antipattern:
if(test) {
return true;
} else {
return false;
}
Use return test.
I have a class called a Plane.
class Plane {
private int _planeId;
public int getModel() { }
public int getNumberOfPassengers() {}
}
And I another class called PlaneService which depends on plane and adds some logic to it,
class PlaneService {
private Plane _plane;
public PlaneService(Plane _plane) {
this._plane = _plane;
}
public void validdatePlane(int planeId) {
fetch plane from planeId from db.
if ( plane.getNumberOfPassengers() is in range of {100 to 300} )
plane is valid.
}
}
But now a new requirement comes in: plane must be extended to support fighter jets. So new design looks like this:
class Plane {
private int _planeId;
public int getModel() { }
}
class PassengerPlane extends Plane {
public int getNumberOfPassengers() {}
}
class FigherJet extends Plane {
public boolean isCommissioned() {}
}
My question is how can I best design 'PlaneSvc'in OOP way ? Is there a good design pattern ?
Currently, my code looks like this:
class PlaneService {
private Plane _plane;
public PlaneService(Plane _plane) {
this._plane = _plane;
}
public void validdatePlane(int planeId) {
fetch CommercialPlane from planeId from db.
if (commericialPlaneObject != null) {
if ( plane.getNumberOfPassengers() is in range of {100 to 300} )
plane is valid.
}
fetch FighterPlaneObject from planeId from db.
if (FighterPlaneObject != null) {
if (fighterplane.isCommissioned()) {
return validPlane;
}
}
}
}
I am sure there is some design pattern to deal with such a case. I need to understand a cleaner approach to if-else here.
What you have here is the strategy pattern and you can find it here.
I dont thing you should pass planeId to the method because you have attached an plane to the PlaneService in the constructor which means that no service without a plane, i also assume that plane has the planeId in it.
If you want the implementation not to be bound at compile time you should use bridge pattern. More or less is the same but you use it for structural purpuses and you pass the delegator not in the constructor but with a setter method.
You could define a validate method in the plane class, for example:
class Plane {
private int _planeId;
public boolean validate(){
return false;
}
public int getModel() { }
}
and then in the child classes, you could override the behavior of the validate method:
class FigherJet extends Plane {
public boolean isCommissioned() {}
#Override
public boolean validate() {
return isComissioned();
}
}
class PassengerPlane extends Plane {
public int getNumberOfPassengers() {}
#Override
public boolean validate(){
//if plane.getNumberOfPassengers() is 100 to 300, return true, else return false
}
}
And then your plane service can call the validate() method on any of the child objects:
public boolean validatePlane(int planeId) {
//fetch passenger plane from planeId from db.
if (passengerPlane != null) {
return passengerPlane.validate();
}
}
You can use Visitor patter for this case as well.
class Plane {
private int _planeId;
public int getModel() { }
abstract boolean validateWith(PlaneValidator validator);
}
class PassengerPlane extends Plane {
public int getNumberOfPassengers() {}
boolean validateWith(PlaneValidator validator) {
return validator.validate(this);
}
}
class FigherJet extends Plane {
public boolean isCommissioned() {}
boolean validateWith(PlaneValidator validator) {
return validator.validate(this);
}
}
class PlaneService implements PlaneValidator {
...
boolean validatePlane(int planeId) {
//fetch Plane object from db
return plane.validateWith(this);
}
//Methods implemented from PlaneValidator
#Override
boolean validate(FighterJet plane) {
return plane.isCommissioned();
}
#Override
boolean validate(PassengerPlane plane) {
return plane.getNumberOfPassengers() in range(100, 300);
}
}
In this way, you can easily extend your system with new types, all thing you need to do is override validateWith(PlaneValidator) method in derived type and add appropriate method to PlaneValidator and describe its behavior in implemented method. I don't know is it pattern applicable to your system, but for me looks it could be.
I have a public integer variable (MainReg) in my Counter Class. I want to get value of this variable and set it in my JComponent class. Here is piece of my JComponent class:
public class Komponent2 extends JComponent implements ActionListener
{
Counter counter3;
.
.
.
int a = counter3.valueOf(MainReg);
But it doesn't work. I tried also:
int a = valueOf(counter3.MainReg);
int a = counter3.valueOf(counter3.MainReg);
int a = counter3.MainReg;
But it still doesn't work. How can I get this variable? Thanks for helping me.
EDIT
Here is my Counter class:
import java.util.Observable ;
public class Counter extends Observable
{
public int MainReg;
public int CompareReg;
public Mode countMode;
public boolean OVF;
private int a=0;
public Counter()
{
OVF=false;
}
public void setCompareReg(int dana)
{
CompareReg=dana;
}
public void setMainReg(int dana2)
{
MainReg=dana2;
}
public void setMode(Mode countMode)
{
this.countMode=countMode;
}
public void Count()
{
if (countMode==Mode.UP)
{
MainReg++;
OVF=false;
if (CompareReg < MainReg)
{
OVF=true;
MainReg=0;
setChanged();
notifyObservers();
}
}
else if (countMode==Mode.UPDOWN)
{
if(MainReg >= CompareReg)
{
a=MainReg;
MainReg--;
OVF=true;
}
else
{
if(MainReg >= a)
{
MainReg++;
OVF=false;
}
else
{
MainReg--;
if(MainReg==0)
{
a=0;
}
OVF=false;
}
}
}
else if (countMode==Mode.CONTINOUS)
{
MainReg++;
OVF=false;
if (65536 < MainReg)
{
MainReg=0;
OVF=true;
}
}
}
}
Well I see two ways you can do this.
Your MainReg integer is public, you could simply use int i = counter3.MainReg;
Or you could create a getMainReg() method in your Counter class. Then call it from whatever class.
EX:
public int getMainReg() {
return this.MainReg;
}
Give your Counter class getter methods, and then call them when you need to access their values. i.e.,
public int getMainReg() {
return mainReg;
}
public int getCompareReg(){
return compareReg;
}
public Mode getCountMode() {
return countMode;
}
And make your fields all private. Also your code should obey Java naming rules: variable names should begin with lower-case letters.
Also be sure that you've initialized your counter variable in the class that uses it, either by creating a new instance, or if appropriate, passing in a valid instance in a constructor or method parameter.
I'm working on program/game where I have static utility class with params.
class ParamsGeneral {
public static final int H_FACTOR = 100;
public static int MAX_SCORE = 1000;
...
}
then I need to override this values in some specific cases, for example playing on map with limited score. So I did following:
class ParamsLimited extends ParamsGeneral {
public static int MAX_SCORE = 500;
// other params stay same
}
And the intended usage is following:
class Player {
ParamsGeneral par;
public Player() {
if(onLimitedMap()){
par = new ParamLimited();
}
}
public boolean isWinner() {
if(this.score == par.MAX_SCORE) {
return true;
}
return false;
}
}
I haven't actually tested this code, because IDE is complaining about calling static field through instance and also about field hiding. I clearly see that this code is stinks, so is there a way to achieve this or do I have to write each param class separately?
PS: I know I shoud make the default class abstract and use getters, I'm just curious if there is a way to make the values accesible statically.
You cannot override static members - in Java, neither methods nor fields could be overriden. However, in this case it does not look like you need to do any of that: since you have an instance of ParamsGeneral in the par variable, a non-static method would do what you need with the regular override.
class ParamsGeneral {
public int getMaxScore() {
return 1000;
}
}
class ParamsLimited extends ParamsGeneral {
#Override public int getMaxScore() {
return 500;
}
}
...
public boolean isWinner() {
// You do not need an "if" statement, because
// the == operator already gives you a boolean:
return this.score == par.getMaxScore();
}
I wouldn't use subclassing for a general game vs a limited game. I would use an enumeration, like:
public enum Scores {
GENERAL (1000),
LIMITED (500),
UNLIMITED (Integer.MAX_INT);
private int score;
private Scores(int score) { this.score = score; }
public int getScore() { return score; }
}
Then, when constructing a game, you can do:
Params generalParams = new Params(Scores.GENERAL);
Params limitedParams = new Params(Scores.LIMITED);
And so forth.
Doing it this way allows you to change the nature of your game while keeping your values centralized. Imagine if for every type of parameter you think of you have to create a new class. It could get very complicated, you could have hundreds of classes!
Simplest solution is to do this:
class ParamsGeneral {
public static final int H_FACTOR = 100;
public static final int MAX_SCORE = 1000;
public static final int MAX_SCORE_LIMITED = 500;
...
}
class Player {
int maxScore;
public Player() {
if(onLimitedMap()){
maxScore = ParamsGeneral.MAX_SCORE_LIMITED;
}
else {
maxScore = ParamsGeneral.MAX_SCORE;
}
}
public boolean isWinner() {
if(this.score == this.maxScore) {
return true;
}
return false;
}
}
No need to have an instance of ParamsGeneral, it is just a collection of static definitions for your game.
Have MAX_SCORE be private static with public static getters; then you can call ParamsGeneral.getMaxScore and ParamsLimited.getMaxScore and you'll get 1000 and 500 respectively