How to add parent class attributes to sub class - java

I have a parent class named Set representing a set of a tennis matches.
public class Set {
private String set1;
private String set2;
private String set3;
//private Object[] match;
public Set() {
setSet1(set1);
setSet2(set2);
setSet3(set3);
}
public void setSet1(String set1) {
this.set1 = set1;
}
public String getSet1() {
return set1;
}
public void setSet2(String set2) {
this.set2 = set2;
}
public String getSet2() {
return set2;
}
public void setSet3(String set3) {
this.set3 = set3;
}
public String getSet3() {
return set3;
}
public String toString(){
return String.format("set1: %s, set2: %s, set3: %s", set1, set2, set3);
}
}
and a sub class of Set named SingleSet where I try to add the sets into an array named `game.
public class SingleSet extends Set{
private Object homePlayer;
private Object awayPlayer;
private String[] game;
public SingleSet(Object homePlayer, Object awayPlayer){
super();
game = new String[3];
game[0] = super.getSet1();
game[1] = super.getSet2();
game[2] = super.getSet3();
setHomePlayer(homePlayer);
setAwayPlayer(awayPlayer);
}
public void setHomePlayer(Object homePlayer) {
this.homePlayer = homePlayer;
}
public Object getHomePlayer() {
return homePlayer;
}
public void setAwayPlayer(Object awayPlayer) {
this.awayPlayer = awayPlayer;
}
public Object getAwayPlayer() {
return awayPlayer;
}
public void setGame(String[] game) {
this.game = game;
}
public String[] getGame() {
return game;
}
public String toString(){
return String.format("Player: %s Vs. Player: %s, Single set game: %s, %s, %s", homePlayer, awayPlayer, game[0], game[1], game[2]);
}
}
This is where I am trying to add the Sets from my parents class into my sub class (this is for FXML, so the code is in my controller):
public void submit() {
SingleSet game1 = new SingleSet(homePlayer1Dropdown.getValue(), awayPlayer1Dropdown.getValue());
game1.setSet1(set1Box1.getText());
game1.setSet2(set1Box2.getText());
game1.setSet3(set1Box3.getText());
System.out.println(game1);
}
When I print the result, my array values are null. I tried printing them individually and that worked fine, so I know the set1Box.getText() is working fine.

The reason you are seeing null values when you print is because they are actually null.
SingleSet game1 = new SingleSet(homePlayer1Dropdown.getValue(), awayPlayer1Dropdown.getValue()); is creating a new SingleSet, which extends Set.
SingleSet constructor makes a super() call to Set constructor.
When Set is created for the first time, all its values are null. Then constructor kicks in, but Set constructor actually does nothing, so Set's instance variables remain null.
Ten SingleSet carries on on building your object with parameter given, which do nothing for setting a value for set1, set2, set3.
game1.setSet1(set1Box1.getText());
game1.setSet2(set1Box2.getText());
game1.setSet3(set1Box3.getText());
They actually set a value to set1, set2, set3 (since you are saying that set1Box1.getText() and others are working). So why you are still seeing null when printing?
public String toString(){
return String.format("Player: %s Vs. Player: %s, Single set game: %s, %s, %s", homePlayer, awayPlayer, game[0], game[1], game[2]);
}
That's why: you are printing game[0], and so on, that are actually null because when you set your game array, those values where null!
public SingleSet(Object homePlayer, Object awayPlayer){
super(); //setting null values to set1, set2, set3
game = new String[3];
game[0] = super.getSet1(); //this returns null!
game[1] = super.getSet2(); //this returns null!
game[2] = super.getSet3(); //this returns null!
setHomePlayer(homePlayer);
setAwayPlayer(awayPlayer);
}
Print some values when you build your object and will see :)
To solve, one way is to use a parametrized constructor public Set(String set1, String set2, String set3), use a parametrized child constructor public SingleSet(String set1, String set2, String set3, Object homePlayer, Object awayPlayer) and a parametrized call to super, super(set1, set2, set3)
Then you should set values when creating game1
SingleSet game1 = new SingleSet(set1Box1.getText(), set1Box1.getText(), set1Box1.getText()homePlayer1Dropdown.getValue(), awayPlayer1Dropdown.getValue());

You are not setting anything in Set's default constructor
Should really find a better name for your class as "Set" is confusing with collections Set.
Make use of immutable for both of your classes to save yourself from trouble - remove all the setters and initialize in constructor.
I'm not that good at tennis scoring rules, but to my best knowledge a "set" has number of "games", and "match" consists from a number of sets. What is the logic for this relation "Set <- SingleSet"? What if you change your hierarchy in this way (in pseudo-code, will skip most method bodies for brevity):
class Player{
private String name;
public Player(String name);
}
class Match{
private Player homePlayer;
private Player awayPlayer;
private List<Set> sets;
public Match(Player homePlayer, Public awayPlayer);
public List<Set> getSets(){
if(sets == null){
sets = new ArrayList<>();
}
return sets;
}
}
class Set{
public Set(Game... games);
}
class Game{
// game score details
public Game(int scoreHomePlayer, int scoreAwayPlayer);
}
So that in your Controller, you could use it like this:
Match match = new Match(new Player("Williams"), new Player("Johnson"))
match.getSets().add(new Set(
new Game(6, 1),
new Game(4, 6),
new Game(7, 0)
// etc.
))
You could further refactor #4 hierarchy and spare all these "new ()" constructor calls using Builder Pattern, something along the line:
Match match = new MatchBuilder("Williams","Johnson").addSet()
.addGame(6,1).addGame(4,6).addGame(7,0)
.build()

you should override set method .Instead of in the set after the constructor is instantiated
public SingleSet(Object homePlayer, Object awayPlayer) {
super();
game = new String[3];
// game[0] = super.getSet1();
// game[1] = super.getSet2();
// game[2] = super.getSet3();
setHomePlayer(homePlayer);
setAwayPlayer(awayPlayer);
}
#Override
public void setSet1(String set1) {
this.game[0]=set1;
super.setSet1(set1);
}
#Override
public void setSet2(String set2) {
this.game[1]=set2;
super.setSet2(set2);
}
#Override
public void setSet3(String set3) {
this.game[2]=set3;
super.setSet3(set3);
}

Related

How to set & fetch fields of inner class in another class

package com.pr.trio;
import java.util.List;
public class lalala {
private List<SegmentationFieldValue> segmentationFieldValues;
public static class SegmentationFieldValue {
private Integer segmentationFieldId;
private Integer segmentationFieldGroupId;
private String value;
public Integer getSegmentationFieldId() {
return segmentationFieldId;
}
public void setSegmentationFieldId(Integer segmentationFieldId) {
this.segmentationFieldId = segmentationFieldId;
}
public Integer getSegmentationFieldGroupId() {
return segmentationFieldGroupId;
}
public void setSegmentationFieldGroupId(Integer segmentationFieldGroupId) {
this.segmentationFieldGroupId = segmentationFieldGroupId;
}
public String getValue() {
return value;
}
public void setValue(String value) {
this.value = value;
}
}
public List<SegmentationFieldValue> getSegmentationFieldValues() {
return segmentationFieldValues;
}
public void setSegmentationFieldValues(List<SegmentationFieldValue> segmentationFieldValues) {
this.segmentationFieldValues = segmentationFieldValues;
}
}
package com.pr.trio;
import java.util.Arrays;
public class kk {
public static void main(String[] args) {
lalala l1 = new lalala();
//currently passed as an empty array, want to set SegmentationFieldId & value here from inner class
l1.setSegmentationFieldValues(Arrays.asList());
//lalala.SegmentationFieldValue.this.setSegmentationFieldId(15);
System.out.println(l1.getSegmentationFieldValues());
}
}
So here, I'm not able to pass values for the segmentation field instead of the empty array, gives an error. So how can I set the values from the inner class fields & pass it to my list?
Seeing as your SegmentationFieldValue class is public, it's trivial to use it inside another class, there are basically two ways to go about this:
The first is to import the inner class:
import com.pr.trio.lalala.SegmentationFieldValue;
The second is to qualify the classname whenever you use it:
lalala.SegmentationFieldValue a = new lalala.SegmentationFieldValue();
You can then call the setters on this class, and use the objects in your call to setSegmentationFieldValues:
lalala.SegmentationFieldValue a = new lalala.SegmentationFieldValue();
a.setSegmentationFieldId(1);
a.setSegmentationFieldGroupId(1);
a.setValue("a");
lalala.SegmentationFieldValue b = new lalala.SegmentationFieldValue();
b.setSegmentationFieldId(2);
b.setSegmentationFieldGroupId(1);
b.setValue("b");
l1.setSegmentationFieldValues(Arrays.asList(a, b));
Judging from your comment code, you also seem to be looking for a shorthand way to add an element to your list. A simple implementation could look like this (in class lalala):
public void addSegmentationFieldValue(Integer id, Integer groupId, String value)
{
if (segmentationFieldValues == null)
{
segmentationFieldValues = new ArrayList<>();
}
SegmentationFieldValue result = new SegmentationFieldValue();
result.setSegmentationFieldId(id);
result.setSegmentationFieldGroupId(groupId);
result.setValue(value);
segmentationFieldValues.add(result);
}
After which you can do the following in the main method of k1:
l1.addSegmentationFieldValue(1, 1, "a");

How to set values for class array variable?

I am setting values to an API and I need to set values for class data type variable which is an array and I need to know how to set the value?
I have tried in java, and I keep on getting compile time error
Items equipmenxxts = new Items ();
equipmenxxts.setDKU(savedRequest.DKUType());
equipmenxxts.setQuantity(savedRequest.getQuantity());
item.setEquipments(equipmenxxts);
**//error setEquipments(Items[]) in ItemOrder cannot be applied to (Items)**
api class to set values
public class ItemOrder implements java.io.Serializable {
private java.lang.String company,
private Items[] equipments; // class given below
public ItemOrder() {
}
public ItemOrder(Items[] equipments) {
this.equipments = equipments;
}
public java.lang.String getCompany() {
return company;
}
public void setCompany(java.lang.String company) {
this.company = company;
}
public Items[] getEquipments() {
return equipments;
}
public void setEquipments(Items[] equipments) {
this.equipments = equipments;
}
}
data type of this class used above
public class Items implements java.io.Serializable {
private java.lang.String DKU;
private int quantity;
public Items() {
}
public Items(String DKU, int quantity) {
this.DKU = DKU;
this.quantity = quantity;
}
}
api class to set up value
#Service("clApiService")
public class NewApiImpl implements NewApiService {
#Override
public Request completeapiNewOrderRep(ServletWebRequest webRequest) {
try {
ItemOrder item = new ItemOrder();
item.setCompany(req.getCompany());
item.setEquipments(); //error setEquipments(Items[]) in ItemOrder cannot be applied to ()**
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
}
I expect just to set the values of (req.setDKU and Quantity) to item.setEquipments( );
.setEquipments(Items[]) demands an array of items, but you pass only a single item.
try creating an array containing your item first:
item.setEquipments(new Items[] {equipmenxxts});
Alternatively you can create equipmentxxts as an array:
final Items[] equipmenxxts = new Items[1];
equipmenxxts[0].setDKU(savedRequest.DKUType());
equipmenxxts[0].setQuantity(savedRequest.getQuantity());
item.setEquipments(equipmenxxts);
Also, when setting a number of items this way, make sure you do not expose your class' internal state, unless you really know what you are doing—and why! You may consider a variable number of arguments for your method:
public Items[] getEquipments() {
return Arrays.copyOf(equipments, equipments.length);
}
public void setEquipments(Items... equipments) {
this.equipments = Arrays.copyOf(equipments, equipments.length);
}
Now you can either call .setEquipments(...) with an array as parameter, or with a custom number of items:
item.setEquipments(e1, e2, e3);
You may reconsider the names of your variables. I do not understand, why an ItemOrder object is called "item" - and you set "Items" objects through .setEquipments(...)
For what I studied, making a set for an array is somewhat a design error. You can, however, make a void setItems(Items i), introducing on parameters a certain index of an ItemOrder or you can make a "superset", which is not a real set:
public void superSet(ItemOrder io){
this.equipments=io.setEquipments(Items[] i);
}

Java array list returning 0 value

I have created a class like this, which contains a bunch of arraylist as you can see. I've been setting the array with the methods add.. and then retrieving it with get.., when i tried to System.out.println numberofcitizen for example it is returning 0. Note that i have instantiated the class in another class to set the values.
public int numberOfCitizen;
private final ArrayList<Integer> citizenid = new ArrayList<>();
private final ArrayList<String> citizenName = new ArrayList<>();
private final ArrayList<Integer> citizenWaste = new ArrayList<>();
private final ArrayList<Float> longitude = new ArrayList<>();
private final ArrayList<Float> latitude = new ArrayList<>();
private final ArrayList<String> address = new ArrayList<>();
public void working() {
System.out.println("executing fine");
}
public void setnoOfcit(int number) {
this.numberOfCitizen = number;
}
public int getnumber() {
return this.numberOfCitizen;
}
public void addCitizenId(int citizen) {
citizenid.add(citizen);
}
public int getCitizenid(int i) {
int citId = citizenid.get(i);
return citId;
}
public void addCitizenName(String citizenname) {
citizenName.add(citizenname);
}
public String getCitizenName(int i) {
return citizenName.get(i);
}
public void addCitizenWaste(int waste) {
citizenWaste.add(waste);
}
public int getCitizenWaste(int i) {
return citizenWaste.get(i);
}
public void addLatitude(float lat) {
latitude.add(lat);
}
public float getLat(int i) {
return latitude.get(i);
}
public void addlng(float lng) {
longitude.add(lng);
}
public float getlng(int i) {
return longitude.get(i);
}
com.graphhopper.jsprit.core.problem.VehicleRoutingProblem.Builder vrpBuilder = com.graphhopper.jsprit.core.problem.VehicleRoutingProblem.Builder.newInstance();
public void runVPRSolver() {
System.out.println(numberOfCitizen);
System.out.println(getCitizenName(0));
//create a loop to fill parameters
Probable source of problem :
numberOfCitizen is a member attribute that you seem to never change. If you want it to represent the number of elements in your lists, either use citizenName.size() or increment the value of numberOfCitizen in one of the add methods.
Design flaw :
Your design takes for granted that your other class always use that one properly. Anytime you or someone uses that class, he must make sure that he add every single element manually. This adds code that could be grouped inside your class, which would be cleaner and easier to maintain.
So instead of several add method like this :
addCitizenid();
addCitizenName();
addCitizenWaste();
addLongitude();
addLatitude();
addAddress();
Design an other Citizen class which will contain those elements, and use a single list of instances of that class. That way you can use only one method :
private List<Citizen> citizenList = new ArrayList<>();
public void addCitizen(Citizen c) {
/*Add element in your list*/
citizenList.add(c);
}
This programming methodology is called "Encapsulation" which you can read about here
You need to increment numberOfCitizen in your add methods. For example:
public void addCitizenId(int citizen){
citizenid.add(citizen);
numberOfCitizen++;
}
I would also suggest encapsulating your variables into Objects, so create a citizen class:
public class Citizen {
private Integer id;
private Integer name;
private Integer waste;
}
And change your variable to an ArrayList of objects:
ArrayList<Citizen> citizens;

Intro to polymorphism 101 java

I'm making a small RPG. There is an Item class which is the parent of each item in the game. These items could be Potion (which is a class) or Bandage (which is a class).
The Item class looks like this:
public class Item
{
int qty;
String name;
Hero hero1;
public void passHero(Hero hero1)
{
this.hero1 = hero1;
}
public void use()
{
if(qty == 0)
{
System.out.println("You have no more of this item to use.");
}
else
{
qty--;
}
}
public void addInv(int value)
{
qty = qty + value;
}
}
A method for passing in the Hero class.
A method for using an item.
A method for adding to the inventory of the item.
This method activates these item classes:
public void initializeItemInventory()
{
items[0] = new Potion();
items[1] = new Bandage();
}
And this method would theoretically print all the items and their quantities:
public void useInventory()
{
for(int i = 0; i<items.length; i++)
{
System.out.println("Enter: " + i + " for " + items[i].name);
}
int response = input.nextInt();
items[response].use();
}
The Potion class, as an example, has an instance variable like:
String name = "Potion";
So my question. Why isn't the name variable from Potion being called correctly in the useInventory method. It returns null which tells me it's returning the parent class Item name, and not the name of the individual subclass variables.
public class Item
{
int qty;
String name;
...
The Item class already has name, and that's what you access from an Item-typed variable:
items[0].name
So if you have
public class Potion extends Item
{
String name = "Potion";
...
then the Potion class has two name fields:
Potion p = new Potion();
System.out.println(p.name);
System.out.println((Item) p).name);
As you say, you want polymorphism, but it only applies to methods. Therefore you need a getter:
public class Item
{
String name;
public String getName() { return name; }
...
In the Potion subclass you may have
public class Potion extends Item
{
public Potion() { this.name = "Potion"; }
...
and items[0].getName() will now work as expected.
Additional note
I'll add this to show a bit of the power of polymorphism.
If you happened to have the name property always the same for all the instances of the same class, you could easily refactor your getter-based solution by completely eliminating the need to store a name variable:
public class Item
{
public String getName() { return "Generic item"; }
...
public class Potion extends Item
{
#Override public String getName() { return "Potion"; }
...
Instead of declaring a new variable in your subclass like "String name = "Potion";"
Use your constructor to pass the value to your superclass, something like this:
// the Item supuerclass has one constructor
public Item(name) {
this.name = name;
}
// the Potion subclass has one constructor
public Potion() {
super("Potion");
}

Changing parent object to child object

I need a bit of help here. so i have this. I was basically wondering when you create an array of object of a parent class, then change that object to a child class, can I access the methods of that child class and if not why. thanks for any help.
public class Racer {
private String name;
private int position;
// Constructor
public Racer()
{}
public Racer(String name)
{
this.name = name;
position = 0;
}
public String getName()
{
return name;
}
public int getPosition()
{
return position;
}
public void setPosition(int n)
{
position = n;
}
public void setName(String n){
this.name=n;
}
}
the child class
public class Spartiates extends Racer{
private int energy;
public Spartiates(){
super();
}
public Spartiates(String name){
setName(name);
setPosition(20);
energy=100;
}
public void setEnergy(int energy){
this.energy=energy;
}
public int getEnergy(){
return energy;
}
}
main class
public class demo{
public static void main(String[] args){
Racer [] player = new player[3];
for(int i=0; i<player.length; i++){
player[i] = new Spartiates();
}
System.out.println(player[1].getEnergy());
}
so here the problem the getEnergy method doesn't work so I was wondering why. If anybody can help it would be very much appreciated. thanks
This is discussed here:
Is it possible to call subclasses' methods on a superclass object?
Along with all the reasons why doing something like this is probably never a good idea :).
You'll have to cast it to an instance of the subclass. If you plan on having a mixed array of object instances you'd need to first check the type:
System.out.println(((Racer)player[1]).getEnergy());
You need either define the function in the superclass or cast the object to the subclass.
If you intend the array to hold ONLY elements of the subclass Spartiates, then declare it as such.
Otherwise, if it needs to hold objects of both type, there only way to do this is to check with instanceof.
if (player[1] instanceof Spartiates)
System.out.println(((Spartiates)player[1]).getEnergy());
else
// handle other types
The reason energy is 0 is because you are calling your empty (no arg) constructor:
player[i] = new Spartiates();
which does not initialize the energy variable (so it will be 0 by default). You only set the variable to 100 in the constructor which takes in a String, namely here:
public Spartiates(String name){
setName(name);
setPosition(20);
energy=100;
}
So either call that constructor in the for loop with some string as an argument, or call your setEnergy() setter with some value after creating the object with the empty constructor.
Also, this is wrong:
Racer [] player = new player[3];
It should read:
Racer [] player = new Racer[3];
or:
Racer [] player = new Spartiates[3];

Categories

Resources