Java Multiple Objects return same info [duplicate] - java

This question already has answers here:
What does the 'static' keyword do in a class?
(22 answers)
Closed 3 years ago.
I'm trying to code a system to determine the type of a weapon and the damage of the weapon for a video game. I'm trying to instantiate two weapons with different stats, but when I use the method getType();, they return the same thing.
I tried using an ArrayList, but grabbing the type of the weapon from something such as (arraylist name here).get(0).getType(); and (arraylist name here).get(1).getType(); still return "AK-47".
ArrayList<Weapon> weapons = new ArrayList<Weapon>();
Weapon weapon = new Weapon("Desert Eagle", 5);
Weapon weapon2 = new Weapon("AK-47", 3);
weapons.add(weapon);
weapons.add(weapon2);
System.out.println(weapon.getType());
System.out.println(weapon2.getType());
Methods:
public class Weapon {
static String type;
static int damage;
public Weapon(String type, int damage) {
Weapon.type = type;
Weapon.damage = damage;
}
public static String getType() {
return type;
}
}
I want weapon.getType(); to return "Desert Eagle" and weapon2.getType(); to return "AK-47".
I know it should be a simple answer, but I'm probably just over-complicating this for myself haha. Any help is appreciated, thanks!

It is because your type is static
Change it to private String type;

Remove static keywoard as it makes fields shared across every instance of that class
static String type;
static int damage;

Remove static from type and damage in Weapon. static means one value for the class globally, not one value per class instance (which is what you want). Also, this.type = type; and this.damage = damage; in the constructor.
public class Weapon {
private String type;
private int damage;
public Weapon(String type, int damage) {
this.type = type;
this.damage = damage;
}
public String getType() {
return type;
}
}
Also, you aren't currently using any values from your List (you kept the references you created, and are calling through those references). And prefer programming to the List interface over the ArrayList type (and you could use the diamond operator <>). Like,
List<Weapon> weapons = new ArrayList<>();
weapons.add(new Weapon("Desert Eagle", 5));
weapons.add(new Weapon("AK-47", 3));
for (Weapon w : weapons) {
System.out.println(w.getType());
}
Outputs
Desert Eagle
AK-47

Related

Is it safe to assign default values to class members in Java?

Here's are two classes, Passenger and Car. Instead of initializing all private members of the Car class in all constructors, I thought of setting default values for them and overwriting specific members' values if provided by the instance creator.
import java.util.ArrayList;
class Passenger {
private String name;
Passenger(String name) {
this.name = name;
}
}
class Car {
private String color = "red";
private int numberOfWheels = 4;
private ArrayList<Passenger> passengers = new ArrayList<Passenger>();
Car() {}
Car(String color) {
this.color = color;
}
Car(int numberOfWheels) {
this.numberOfWheels = numberOfWheels;
}
public void addPassenger(Passenger p) {
this.passengers.add(p);
}
}
Is it safe to set default values to class members like this? Any pitfalls to avoid for any particular data types (even other than the ones I have used)?
Yes, it is safe.
Personally I prefer initialize where is declaration if is a common value for all constructors. If I have more constructor is not very pleasure to write that thing multiple times. And for me is more clear what value have.

Chaining multiple constructors

I understand that when chaining constructors this must be done on the first line of the main constructor, can someone explain how you would go about the below code.
I want to chain to all constructors so that they can all be private other than the main constructor.
public class Flight {
int passengers = 0;
int seats = 150;
double maxKgPerPassenger;
private Flight(int passengers) {
this.passengers = passengers;
}
private Flight(int seats) {
this.seats = seats;
}
private Flight(double maxKgPerPassenger) {
this.maxKgPerPassenger = maxKgPerPassenger;
}
public Flight(int passengers, int seats, double maxKgPerPassenger) {
this(passengers);
this(seats);
this(maxKgPerPassenger);
}
}
A constructor is up to set as many fields as possible or construct an instance completely.
You pick a constructor which has a greater number of arguments and use it within constructors with a smaller amount. For example,
public Flight(double maxKgPerPassenger) {
this(0, 0, maxKgPerPassenger); // default, default, maxKgPerPassenger
}
private Flight(int passengers, int seats, double maxKgPerPassenger) {
this.passengers = passengers;
this.seats = seats;
this.maxKgPerPassenger = maxKgPerPassenger;
}
I want to chain to all constructors so that they can all be private other than the main constructor.
I suggest the opposite way. Make all constructors you are going to use public, but an all-arguments constructor private if you won't be using that.
The approach you tried to adopt is similar to the builder pattern where each method sets a single field. You definitely need to have a look at it if a number of arguments are going to grow up.
Why do you want to chain constructors ?
As you chain constructors, you have to specify some default values from the constructor with less argument to the invoked constructor with more arguments.
You do the reverse here :
public Flight(int passengers, int seats, double maxKgPerPassenger){
this(passengers);
this(seats);
this(maxKgPerPassenger);
}
You indeed want to invoke from the constructor with the most argument all other constructors.
It makes no sense and it is not valid either as a constructor can invoke a single other constructor of the same class.
I want to chain to all constructors so that they can all be private
other than the main constructor.
Things work in the reverse order.
The actual code doesn't seem to need constructor chaining.
This one is enough :
public Flight(int passengers, int seats, double maxKgPerPassenger){
this.passengers = passengers;
this.seats = seats;
this.maxKgPerPassenger = maxKgPerPassenger;
}
Suppose that class clients could create Flight instances with two flavors :
by passing all parameters
by passing only the seats parameter (remains being valued with default values)
You could so write :
public Flight(int passengers, int seats, double maxKgPerPassenger){
this.passengers = passengers;
this.seats = seats;
this.maxKgPerPassenger = maxKgPerPassenger;
}
public Flight(int seats){
super(50, seats, 10); // you pass some default values for passengers and maxKgPerPassenger
}
make the default constructor private to prevent constructor instantiation and instantiate objects using a public static method. This way you can work around the constructor restriction. To add a little confusion I converted your constructors to normal methods using the class name by adding void return type. Also consider if want you really want isn't the Builder pattern.
public class Flight {
private int passengers = 0;
private int seats = 150;
private double maxKgPerPassenger;
private Flight() {}
private void Flight(int passengers)
{
this.passengers = passengers;
}
private void Flight(int seats)
{
this.seats = seats;
}
private void Flight(double maxKgPerPassenger)
{
this.maxKgPerPassenger = maxKgPerPassenger;
}
public static Flight create(int passengers, int seats, double maxKgPerPassenger)
{
Flight flight = new Flight();
flight.Flight(passengers);
flight.Flight(seats);
flight.Flight(maxKgPerPassenger);
return flight;
}
}

Java association problems

Finding Java an overly complicated language. I can't figure out this association thing if my life depended on it. I'm specifically stuck on the Cab object +pickup(rider:Passenger): String. I know it will return a String and here's the code I have so far.
UML Diagram
package cabsimulation;
public class Cab {
private double companyTotalFare;
private double rate;
private double taxiTotalFare;
private int tripCounter;
private int cabID;
public Cab(int cabID){}
public double dropOff(int minutes){
return minutes*rate;
}
public double endOfShift(){
double sumOfFares = taxiTotalFare + companyTotalFare;
return sumOfFares;
}
//public String report();
public double getRate(){
return rate;
}
public void setRate(double cabRate){
this.rate = cabRate;
}
}
and
public class Passenger {
private final double weight;
private final boolean inFrontSeat;
public Passenger (double weight, boolean front){
this.weight = weight;
this.inFrontSeat = front;
}
public double getWeight(){
return weight;
}
public boolean isInFrontSeat(){
return inFrontSeat;
}
}
How do I write (program) an association between these two objects?
As written in your instructions: define a typed attribute
private Passenger passenger;
or the like (I'm no Java guy).
When you want to have an association between two classes, you will normally use an instance variable. In this case, a Cab can contain a Passenger. So you want to have an instance variable in the Cab class which is able to hold a Passenger. This can be done like that:
public class Cab {
Passenger passenger;
//...
}
In the pickUp method shown in the UML, you want to fill this variable, e. g. like that (unfortunately, there is no specification what String the method should return):
public class Cab {
Passenger passenger;
//...
public String pickUp(Passenger rider) {
this.passenger = rider;
return "something";
}
}
After you called the method pickUp, you can access the passenger in the cab via its instance variable.
I hope I could help you!
usually, if you have an attribute, you have the getter/setter which are dedicated to set and to get the attribute.
If you have a method (other than a setter) with a parameter of the type of an attribute, it does not mean that the parameter will set the attribute.
So for me, it could be easier to remove the method pickup and to define a getter and setter on passenger.

Good way to organize group of constants in enum-like fashion

I'm trying to find a good way to orginize a group of constant values that are used simply for immutable data.
Here is what I'm currently attempting:
public class FishType {
//PredatorFishType extends FishType
public static final PredatorFishType SHARK = new PredatorFishType(5, 20, "Shark");
public static final FishType CAT_FISH = new FishType("Cat Fish");
private String name;
private FishType(String name) {
this.name = name;
}
public String getName() {
return name;
}
}
I use reflection to gather the final values into a collection aswell. I used to utilize enum but was forced to think of a new way to do this when different types of fish came into play such as the predator which contains other data such as food and so on. These constants are only used for data displaying purposes and have no reason to be mutated.
If there is some way to have multiple enum types within the same enum (If that makes any sense at all), that'd be great.
Thanks for reading.
You can either use constructor overloading or a combination of overloading and a wrapper class. If you know for certain that this data is immutable and will always be that way, I don't see anything wrong with sticking to enums for it. For the sake of putting it into one class, I've included the enums in the EnumTester class, but you may not want to do that.
Here's an example that prints "Cat Fish 5 20 Shark" and "Cow Fish" when run, using nothing but enums and a wrapper class. You could put accessors wherever you need them, depending on what you actually want to do with the information - I'm trying to demonstrate how to compose the two enums, not how to use them.
package enums;
public class EnumTester
{
public enum MainType {
CAT_FISH("Cat Fish"), DOG_FISH("Dog Fish"), COW_FISH("Cow Fish"); //everything has a name...
private String name;
private MainType(String name){
this.name = name;
}
public String getTypeDetails(){
return name;
}
}
public enum SubType {
PREDATOR(5, 20, "Shark"), PREY(), MANATEE(); //but not everything has any additional information
private boolean isFullSubType;
private int val1;
private int val2;
private String subName;
private SubType(int val1, int val2, String subName){
this.isFullSubType = true;
this.val1 = val1;
this.val2 = val2;
this.subName = subName;
}
private SubType(){
this.isFullSubType = false;
this.val1 = -1;
this.val2 = -1;
this.subName = "none";
}
public String getSubTypeDetails()
{
if( isFullSubType ) {
return val1 + " " + val2 + " " + subName;
}
else {
return "";
}
}
}
private MainType mainType;
private SubType subType;
public EnumTester(MainType mainType, SubType subType)
{
this.mainType = mainType;
this.subType = subType;
}
public static void main(String[] args)
{
EnumTester kittyShark = new EnumTester(MainType.CAT_FISH, SubType.PREDATOR);
System.out.println(kittyShark.printDetails());
EnumTester cowManatee = new EnumTester(MainType.COW_FISH, SubType.MANATEE);
System.out.println(cowManatee.printDetails());
}
public String printDetails(){
return mainType.getTypeDetails()+" "+subType.getSubTypeDetails();
}
}
I typically follow a similar pattern to what you've done above. I might make the class FishTypes to be the collector, just to keep the FishType interface a bit cleaner. You can also invent some syntactic sugar to help you collect registered FishTypes:
public static final Set<FishType> registeredFish = new HashSet<>();
public static final PredatorFishType SHARK = register(new PredatorFishType(5, 20, "Shark"));
public static final FishType CAT_FISH = register(new FishType("Cat Fish"));
public static <T extends FishType> T register(T fishType) {
registeredFish.add(fishType);
return fishType;
}

How to extend or implement classes? [closed]

Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
Questions asking for code must demonstrate a minimal understanding of the problem being solved. Include attempted solutions, why they didn't work, and the expected results. See also: Stack Overflow question checklist
Closed 9 years ago.
Improve this question
Picture to show task:
First I am sorry, for my bad to for expressing my mind.
I have such a task, I don't need that you do it for me.
Vehicle is parent class for Sedan (Cause Sedan class is String type).
How to extend or implement Vehicle class with universal class?
I forgot to ask my teacher, but maybe you will know, what means striped pointer to Owner class, and what is that: has a?
P.S. If you need code that I have written already, I will show you.
So this is my parent Vehicle class:
public class Vehicle {
private int vehicleNumber;
protected int fuelTankSize;
protected int maxSpeed;
protected Owner owner;
//1
public Vehicle(int vehicleNumber){
this.vehicleNumber = vehicleNumber;
}
//2
public Vehicle(int vehicleNumber, int fuelTankSize) {
this.vehicleNumber = vehicleNumber;
this.fuelTankSize = fuelTankSize;
}
//3
public Vehicle(int vehicleNumber, int fuelTankSize, int maxSpeed) {
this.vehicleNumber = vehicleNumber;
this.fuelTankSize = fuelTankSize;
this.maxSpeed = maxSpeed;
}
//4
public Vehicle(int vehicleNumber, int fuelTankSize, int maxSpeed, Owner owner) {
this.vehicleNumber = vehicleNumber;
this.fuelTankSize = fuelTankSize;
this.maxSpeed = maxSpeed;
this.owner = owner;
}
//1
public int getMaxSpeed() {
return maxSpeed;
}
public void setMaxSpeed (int maxSpeed){
this.maxSpeed = maxSpeed;
}
//2
protected int getFuelTankSize(){
return fuelTankSize;
}
protected void setFuelTankSize (int fuelTankSize){
this.fuelTankSize = fuelTankSize;
}
//3
public Owner getOwner(){
return owner;
}
public void setOwner (Owner owner){
this.owner = owner;
}
}
child Sedan with:
public class Sedan extends Vehicle {
private String registrationIndex;{
}
public Sedan (int vehicleNumber, int fuelTankSize, int maxSpeed, String registrationIndex, Owner owner) {
super(vehicleNumber, fuelTankSize, maxSpeed, owner);
this.setRegistrationIndex (registrationIndex);
}
public String getRegistrationIndex (){
return registrationIndex;
}
public void setRegistrationIndex (String registrationIndex) {
this.registrationIndex = registrationIndex;
}
}
second Universal child without an error:
public class Universal extends Vehicle {
private int trunkSize;
public Universal (int vehicleNumber, int fuelTankSize, int maxSpeed, int trunkSize, Owner owner) {
super(vehicleNumber, fuelTankSize, maxSpeed, owner);
this.setTrunkSize (trunkSize);
}
public int getTrunkSize() {
return trunkSize;
}
public void setTrunkSize(int trunkSize) {
this.trunkSize = trunkSize;
}
public void printDescription() {
super.printDescription();
System.out.println("Universalo bagažinės tūris: " + getTrunkSize() + "l.");
}
}
and some misterious (to me) Owner class:
public class Owner {
public String firstName;
public String lastName;
public Owner (String firstName){
this.firstName = firstName;
}
public Owner (String firstName, String lastName){
this.firstName = firstName;
this.lastName = lastName;
}
}
added VechileTest for testing:
public class VehicleTest {
public static void main(String[] args) {
Vehicle vehicleInf = new Vehicle (1, 45, 260);
Universal universalInf = new Universal(2, 50, 220, 70);
Sedan sedanInf = new Sedan (3, 40, 180, "AVA 123");
vehicleInf.printDescription();
universalInf.printDescription();
sedanInf.printDescription();
}
}
Well, 1st of all I recommend you read a good tutorial / explanation of UML class diagrams, like this here for example.
After you know the basics, it should be easy to translate that into Java code.
I'll give you the code for the Universal class and a start for your Vehicle. The rest you'll have to do on your own.
The class Universal:
public class Universal extends Vehicle {
private int trunkSize;
public int getTrunkSize() {
return this.trunkSize;
}
public void setTrunkSize(int trunkSize) {
this.trunkSize = trunkSize;
}
}
As you can see the first block inside a class box refers to the variables. The - and + indicates the visibility (private for -, public for +).
The next block is about the methods, specifying visibility, return type, method name and parameters (type and name).
The arrow between Universal and Vehicle indicates a inheritance relationship (see in code that Universal extends Vehicle).
So all in all the diagram is a construction plan for your classes; at least for the static part, meaning the relationships and state they can have.
The start of class Vehicle:
public class Vehicle {
private int vehicleNumber;
// the rest here ...
}
Edit:
Well, now that I see your code, you seem to have a few misconceptions:
The Sedan type is not from type String, it is from type Sedan (which extends Vehicle). Just the new member variable in the Sedan type is of type String, does not matter.
To your 1st question: The Vehicle class is the base (parent) class of Sedan. You do not to do anything with it, inheritance is expressed from the child towards the parent, not the other way around. Vehicle should usually be declared abstract (as you cannot create an instance of a generic Vehicle), but this is not in the diagram.
To your 2nd question: The has a relationship is just this. It expressed that one class has another class as it's member (which is redundantely expressed inside the class diagram already), so nothing to do for that.
Additionally your code has a few issues:
I do not see any constructors declared in Vehicle class, those 4 can go.
Your Sedan has a superflous pair of {} after declaration of your registrationIndex variable.
Since your Vehicle has no default constructor, you must call this constructor from your Sedan class (or remove the constructors from Vehicle.
Your Universal class calls the Vehicle constructor with the trunkSize while the Vehicle constructor expects the vehicleNumber there.
Your Vehicle class doesn't have a parameterless constructor, which means that Universal and Sedan must explicitly call one of them (super(...);). You're doing this in Universal (albeit incorrectly as you're passing the trunk size instead of the vehicle number expected by Vehicle's constructor) but not in Sedan.
As for the second question: The two major relations in OOP are is a and has a. The difference can be easily explained like this:
A Sedan is a vehicle
A vehicle has an owner
is a means it inherits some properties of something else, has a means that it has a reference to something else.

Categories