I have a Car class :
public class Car {
public String name = null; // Name of the Car Model
public String color = null; // Color of the car
Car(){
/** DO WHATEVER***/
}
}
Then in the main() class I do this :
LinkedList<Car> myCars = new LinkedList<Car>();
myCars.add(new Car());
myCars.add(new Car());
myCars.add(new Car());
myCars.get(0).name = "Geep";
myCars.get(0).color = "Black";
myCars.get(1).name = "Camry";
myCars.get(1).color = "Red";
myCars.get(2).name = "Honda";
myCars.get(2).color = "Green";
My question :
Lets assume that at the time of Car object creations, we do not have values of these instance variables and we get them at a later stage, so that constructor initialization is not feasible.
Then is this the correct way above ? I mean how instance variables of each objects would be assigned values, in Java collection.I mean, using the get() method ? I understand, if we have lots of car
objects then we will use a for loop.
Please explain.
Thank you.
It would make more sense to change the constructor from: /** DO WHATEVER***/
to something like:
Car(String name, String color){
this.name = name;
this.color = color;
}
and later on to the insertion into the list:
myCars.add(new Car("Geep", "Black"));
myCars.add(new Car("Camry", "red"));
...
In case you don't have "the details" of the cars, and you simply need to instantiate a list with 50 cars and later on "add the details" - another question raises: where do the details come from ? if you don't know it in advance it has to come from an eternal source (user-input, file, etc) and then it would make sense to run in a loop over the list and add the details:
for (Car car : myCars) {
String name = ... // get the details of the car from an external source
String type = ... // get the details of the car from an external source
car.setName(name); // of course you'll have to implement setName() and setType()
car.setType(type); // which is a better practice than exposing the class members via public access
}
Regarding whether this is the correct way: I prefer overriding the constructor so that my initialization and setter code is at the same place.
Essentially, I would provide the constructor for Car as:
public class Car {
public String name = null; // Name of the Car Model
public String color = null; // Color of the car
public Car(String name, String color){
super();
this.name = name;
this.color = color;
}
}
I would then put it in my collection as:
LinkedList<Car> myCars = new LinkedList<Car>();
myCars.add(new Car("Jeep", "Black"));
myCars.add(new Car("Ferrari", "Red"));
First, it it not recommended to expose instance variables (public). Change public to private and create the getters. Also, you could create a constructor that takes a name and color in parameters:
public class Car {
private String name = null;
private String color = null;
public Car(String name, String color) {
this.name = name;
this.color = color;
}
public String getName() {
return name;
}
public String getColor() {
return color;
}
}
Then you can do :
LinkedList<Car> myCars = new LinkedList<Car>();
myCars.add(new Car("Jeep", "Black"));
myCars.add(new Car("Camry", "Red"));
myCars.add(new Car("Honda", "Green"));
There are many ways to do it but I would definitely set the car information before adding it to the list.
Related
I am trying to reach my parent class Car() variables and methods, from my ArrayList in main() of Objects Automobile(), Bus() which all inherit Car(). It gives me the opportunity to get the .Class and I know I can then compare if the class is Automobile or Bus and then do some operations, but I am actually trying to sort allInOne() ArrayList by getModel() Strings.
public class Car {
private String brand;
private String model;
public String getBrand(){
return brand;
}
public String getModel(){
return model;
}
}
public class Automobile extends Car {
int x;
Automobile(String brand, String model, int x){
super(brand, model);
this.x = x;
}
}
public class Bus extends Car {
int x;
Bus(String brand, String model, int x){
super(brand, model);
this.x = x;
}
main(){
Car first = new Automobile("brand1", "model1", 2);
Car second = new Bus("brand2", "model2", 3);
ArrayList<Object> allInOne = new ArrayList<Object>();
allInOne.add(first);
allInOne.add(second);
//here is the question part
allInOne.get(0).getBrand;
}
Instead of having Object List use ArrayList<Car>
ArrayList<Car> allInOne = new ArrayList<>();
then you can access all these methods:
allInOne.get(0).getBrand();
OR
If you want to stick to List of Object for some reason, then you can do this:
((Car) allInOne.get(0)).getBrand();
When instantiating the List, change Car as reference type instead of Object so that you might use the methods/attributes inherited from Parent Class.
ArrayList<Car> allInOne = new ArrayList<Car>(); // Java 7
ArrayList<Car> allInOne = new ArrayList<>(); // Java 8 it is not longer necessary to put reference type when instance an object.
I have 4 classes ( I will shorten them for convenience).
public class PoliceStation{
public String name;
ArrayList<Owner> owners = new ArrayList<>();
public boolean addOwner(Owner owner) {
if(findOwnerID(owner)) {
this.owners.add(owner);
System.out.println("Owner "+owner.getName()+" added.");
return true;
}
System.out.println("Owner "+owner.getName()+" with "+owner.getOwnerIDNumber()+" not added.");
return false;
}
and a few more classes for finding owner objects.
And Owner class:
import java.util.ArrayList;
public class Owner {
String name;
String dateOfBirth;
long ownerIDNumber;
String address;
ArrayList<Vehicle> vehicles=new ArrayList<Vehicle>();
ArrayList<Fine> penalties = new ArrayList<Fine>();
public Vehicle findVehicleObject(String plateNum) {
for(int i=0;i<vehicles.size();i++) {
System.out.println(i);
if(vehicles.get(i).getPlateNumber().equalsIgnoreCase(plateNum)) {
System.out.println("Vehicle with that plate number "+plateNum+" exists.");
return vehicles.get(i);
}
}
System.out.println("Vehicle doesnt exist with "+plateNum);
return null;
}
Which consists of addVehicle methods, findVehicle etc.
Vehicle class:
public class Vehicle extends Owner{
PoliceStation ps = new PoliceStation("center");
String plateNumber;
String name;
String type;
//String serialNum;
public Vehicle(String driverName, String dateOfBirth,long ownerID, String address,String plateNumber, String name, String type) {
super(driverName,dateOfBirth,ownerID,address);
this.plateNumber = plateNumber;
this.name = name;
this.type = type;
}
With findVehicle method that should return the vehicle object with the vehicle's plate number:
public Vehicle findVehicle1(String plateNum) {
if(this.plateNumber==plateNum) {
System.out.println("Lookin "+plateNum);
return super.findVehicleObject(plateNum);
}else return null;
}
And after that I have a fourth class called RadioCam that reads a plateNumber from a car: (note: the following code is badly written because I've been trying to get this to work without success)
class RadioCam{
public void detection(double speed) {
System.out.println("Vehicle detected.");
//speed would be a variable that the radioCam would return using radiowaves and doppler effect
if(speed>50) {
String plateNumber = takePicture();
Vehicle veh = new Vehicle(plateNumber);
veh = veh.findVehicle1(plateNumber);//<-- null
System.out.println("-------------------"+veh.getName());//<- null here as well
Owner ownerFine = ps.getOwner(veh);
ownerFine= ps.getOwner(veh);
System.out.println("sssssss"+ownerFine.getName());
//ownerFine = PoliceStation.getOwner(veh);
ps.addFine(ownerFine, "speed violation", veh);//<- so this method doesnt work in the end becuse ownerFine and veh are null
Which returns null to veh = veh.findVehicle1(plateNumber);. And going back to Owner class at public Vehicle findVehicleObject(String plateNum) {
for(int i=0;i<vehicles.size();i++) { <-- vehicle.size() is 0 so it doesn't go through the vehicles at all.
I get it that I need an owner object from the arraylist to get to the vehicle object from the arraylist, but in this case I need a vehicle object from plateNumber (which is a part of the Vehicle class) and from the vehicle object to get the owner object that owns the vehicle object.
I hope I explained my problems good enough.
Try equals method to compare values, this.plateNumber==plateNum may be false even they have same value.
public Vehicle findVehicle1(String plateNum) {
if(this.plateNumber.equals(plateNum)) {
System.out.println("Lookin "+plateNum);
return super.findVehicleObject(plateNum);
}else return null;
}
In your findVehicle1(String plateNum) method you are comparing two strings with the == operator, while you should be using string.equals(Object other)
Try changing
if(this.plateNumber==plateNum) {
to
if(this.plateNumber.equals(plateNum)) {
Also when constructing your vehicle object, you're ommiting a lot of the needed parameters
public Vehicle(String driverName, String dateOfBirth,long ownerID, String address,String plateNumber, String name, String type) {
^ the constructor asks for 7 parameters, while you only give
new Vehicle(plateNumber);
one parameter. Therefore of course your veh.getName() method will return null, because it's an attribute that you did not maintain when you created your vehicle object.
After fixing those issues, you can think about your general code structure, like where to implement loops and such.
I don't know whether or not you use an IDE, but if you do please familiarize yourself with the the debugging functionality to follow the code execution step-by-step in called methods. You could have easily pinpointed the lines of code that act in ways they shouldn't act (after all you already found the lines where null is the result of your method calls).
I am rather new to Java, rather only a week's worth of learning so I am still very inexperienced. I have spent a few days on polymorphism and know that I can extend a parent class to a child class, but I would like to know how to have a grandparent class have all the attributes of the parent classes. I have done a bit of research but haven't found what I was looking for. What I am working on is creating objects of clothing. I have one grandparent which is 'Clothing' three parents 'Upper_wear', 'Lower_wear', and 'Shoes' with many children such as 't-shirts', 'shorts' and 'sandals'. Currently what I have in the parents code is:
public class Upper_wear
{
private String fabric;
private int numb_zippers;
private String draw_string;
private int numb_pockets;
private int size;
private String color;
private double length_sleeves;
private int length_shirt;
private String collar;
private String hood;
private int code;
private double price;
private String name;
Upper_wear(String fabric,int numb_zippers,String draw_string,int numb_pockets,int size,String color, double length_sleeves, int length_shirt, String collar, String hood, int code, double price, String name){
this.fabric = fabric;
this.numb_zippers = numb_zippers;
this.draw_string = draw_string;
this.numb_pockets = numb_pockets;
this.size = size;
this.color = color;
this.length_sleeves = length_sleeves;
this.length_shirt = length_shirt;
this.collar = collar;
this.hood = hood;
this.code = code;
this.price = price;
this.name = name;
}
public String get_fabric(){
return fabric;
}
public int get_numb_zippers(){
return numb_zippers;
}
public String get_draw_string(){
return draw_string;
}
public int get_numb_pockets(){
return numb_pockets;
}
public int get_size(){
return size;
}
public String get_color(){
return color;
}
public double get_length_sleeves(){
return length_sleeves;
}
public int get_length_shirt(){
return length_shirt;
}
public String get_collar(){
return collar;
}
public String get_hood(){
return hood;
}
public int get_code(){
return code;
}
public double get_price(){
return price;
}
public String get_name(){
return name;
}
}
And for the children's code I have:
public class Jacket extends Upper_wear
{
Jacket(String fabric,int numb_zippers,String draw_string,int numb_pockets,int size,String color, double length_sleeves, int length_shirt, String collar, String hood, int code, double price, String name){
super(fabric, numb_zippers, draw_string, numb_pockets, size, color, length_sleeves, length_shirt, collar, hood, code, price, name);
}
}
The reason why I don't just extend clothing with all the variables is because I don't want to state if or not 'Upper_wear' has 'Shoe_laces' which is a variable in 'Shoes'. Yet, I want to gather all parent classes into one because when I go to the run class. In the for loop, I want to list out the prices of every item of Clothing and not just of a parent class. I feel that I am limited to only iterating through one parent class at a time such as what I currently have:
public class Run
{
public static void main (String[]args){
Shoes Tennis_shoes_01 = new Shoes("Canvas", 0, "yes", 10, "red and white", 0,0.5,2.5, 00001, 750.99,"Tenny shoey");
Upper_wear T_shirt_01 = new Upper_wear("Cotton", 0, "no", 0, 14, "yellow", 14.5, 15, "v-neck", "no", 00002, 990.50, "Yel-ow");)
Shoes[]In_Stock = {Tennis_shoes_01};
Upper_wear[]In_Stock_upper = {};
Lower_wear[]In_Stock_lower = {};
System.out.println("Price");
System.out.println("-------");
for(Shoes x : In_Stock){
System.out.println(x.get_name() + ": " +x.get_price());
}
for(Upper_wear x : In_Stock_upper){
System.out.println(x.get_name() + ": " + x.get_price());
}
}
What I am wanting is something more like this:
public class Want_run
{
public static void main(String[]args){
Clothing Tennis_shoes_01 = new Shoes("Canvas", 0, "yes", 10, "red and white", 0,0.5,2.5, 00001, 750.99,"Tenny shoey");
//Not sure if this is possible to have a class that's different than the constructor but I am looking for it to come from clothing class with properties of Shoes.
Clothing T_shirt_01 = new Upper_wear("Cotton", 0, "no", 0, 14, "yellow", 14.5, 15, "v-neck", "no", 00002, 990.50, "Yel-ow");
//So I want all properties to be in clothing but the ones that the childeren don't have I want to be just blank.ex. Upper_wear is blank on the shoe_laces.
Clothing[]In_Stock = {Tennis_shoes_01, T_shirt_01};
//I really want everything to be just in one list to iterate through but I can't currently do that with multiple parents of my knowledge.
for(Clothing x : In_Stock){
System.out.println(x.get_name() + ": " + x.get_price());
}
//this way I have only one for loop for every item,and for parents that don't have 'price' I am hoping would just not print.
}
}
So I want clothing to have every attribute of 'Upper_wear', 'Lower_wear', and 'Shoes', but not the parents to have every attribute of Clothing. Such that the attributes that are specific to Shoes, I wish to be blank for the other two parents when it iterates through methods specific to Shoes. I'm not sure if what I am looking for is even possible to do. If you cannot understand what I am looking for, I am sorry for being confusing. Thank you for taking your time to read this and helping me.
What you are trying to do is a classic application of polymorphism. You just need to clarify a few concepts.
Your grand parent will contain all the attributes that are common to all children, such as item ID, name, colour(s), price, etc. It should also contain common functions, such as a print() function which is what you require in your main.
All children (including parents) will introduce their specific attributes in their classes, such as hood/collar for uppers, and inner lining for jacket. They will also override (provide their own implementation of) functions they need to customize according to their needs. So, in your case, while the Clothing will have a print() function, each sub class will have its own implementation of it, in which it will print all its own properties such as number of zippers, shoelaces.
Finally, in your main, you will have a list of type Clothing, which will contain references to objects of all types you want. A parent can point to an object of a child type. For example,
Clothing c = new Jacket(...);
c.print(); // This will call the print() of class Jacket, not Clothing
I suggest reading up on dynamic polymorphism. This link contains a quick introduction and a nifty example.
I am currently studying Java and have been asked to write a program that deals with
actors and films as classes.
The actor class has the following attributes:
Name, Address, age, myFilm (an array or arraylist to hold all the films a particular actor
has starred in.
The film class has these attributes:
Name, Code (String, String)
I have implemented these classes with getter and setter methods to handle the data:
My actor class so far:
public class actor {
private String name;
private String address;
private int age;
int[] myFilms = new int[3];
public actor (String name, String address, int age) {
}
public void setName (String name) {
this.name = name;
}
public void setAddress (String address) {
this.address = address;
}
public void setAge (int age) {
this.age = age;
}
public void setFilm () {
}
public String getName () {
return name;
}
public String getAddress () {
return address;
}
}
My film class:
public class film {
private String name;
private String code;
//Constructor
public film () {
}
public void setName (String name) {
this.name = name;
}
public String getName (){
return name;
}
public String getCode (String name) {
//Get code:
//Split Function
String[] words = name.split("\\s+");
String code = "";
for (int i=0; i < words.length; i++) {
code = code + words[i].charAt(0);
code = code.toUpperCase();
}
return code;
}
}
I'm hitting a brick wall with how to approach making the program dynamic to display each actors total films. This is for a college assingnment and I am also required to do a deep copy of the array at some point. I am almost completely new to OO so this is proving a tricky task for me.
Any words of advice or a point in the right direction would be hugely appreciated.
Two comments about your classes...
Why not declare the films of an actor like this:
private List<Film> myFilms = new ArrayList<Film>();
This way, you will be able to add and remove film object references dinamically from your actor objects. You can implement getter and setter for the list and manipulate it from outside, for example. Lists (or Collections in general) are much easier to manipulate than primitive arrays.
Consider declaring classes with first capital letter, it's a convention. For example: Actor, Film.
Consider extracting a "actor that play in film" to another class, to decouple film out of actor (actor can also do theathre spectacles, vioce dubbig etc, not specialy movies.)
class ActorRole {
private Actor actor;
private Movie movie;
private int dollarsSallary;
private int scenesPlayed;
// etc.
}
If you don't want to, I'm almost sure that better create dependency from Movie to Actor than from Actor to Movie, because Movies almost surely have actos:
class Movie {
private List<Actor> actors = new ArrayList<Actor>();
}
This makes harder to count actor statistics (you have to iterate over all Movies) but I think this is a better design.
To count single actor shows:
for ( Movie movie : listOfAllMovies ) {
if ( movie.getActors().contains( myActor ) ) { // read about equals() in Java !
timesPlayed++;
}
}
If you want to make a ranking for more actors, you can use Map<Actor,Integer> to map actors to they times played counters.
This can be a lengthy operation, so you can think about cashing the results (like in above map) - the solution can be map, ActorStatistics class, simple timesPlayed field in actor etc. etc.
Don't be afraid to objects
Don't do a hard workaround to mape films to id (like your id, which is propably connected to your film code String, wich add another type-incompatibility issue.
Try to use more object references instead of workarounds, and List instead of array.
Generally, read about Collections in Java, like ArrayList and HashMap and also overriding equals() and hashCode(), and in general OOP Single responsibility principle and Class cohesion
You can compose a auto-increment container inside class actor, like vector ArrayList and so on. Or you could implement a dynamic array by yourself.
If u have a database which has a table with username and film(ID) & etc, u can create a class as follow,
Class Film{
private String actorName;
private String filmCode;
private String filmName;
....getter & setter methods
...
}
then u can create a method to get data list of Film class.
Eg:
List<Film> filmList = new ArrayList<Film>();
String actorName = "Arnold";
filmList = dbCon.getFilmListByActor(actorName);
your getFilmListByActor method should be like this,
public List<Film> getFilmListByActor(String actorName){
List<Film> filmList = new ArrayList<Film>();
//Query for get film list by actor
//assigne filmList to result set
enter code here
return filmList;
}
I have an object made in my main Recipe recipeOne = new Recipe("Pepperoni Pizza");
This object is an instance of this Object Array defined and constructed here!
public class Recipe implements Cloneable{
String Name;
final int INGREDIENT_ARRAY_MAX = 10;
Ingredient Recipe[] = new Ingredient[INGREDIENT_ARRAY_MAX];
public Recipe(String name){
Name = name;
}
So I am looking to make a deep copy of this object with the line Recipe ressippi = (Recipe) recipe.clone(); and it sends me here!
public Object clone(){
Recipe cloneRec = new Recipe(Name);
return cloneRec;
}
I know this is currently a shallow copy because the method only passes references, so if I was to attempt a name change on my new Object that was a clone of recipeOne...it would change both of their names. Obviously I do not want that, I'm fairly lost on this, can anyone help?
EDIT:#Rohit Jain
Both my Recipe class as well as my Ingredient class (the objects the recipe array holds) have toString methods and recipes calls on ingredients in order to print it all out in a nice little format. When I call it on my "recipeOne" object (the one called pepperoni pizza) i get "Pepperoni Pizza: 1.0 Pounds of Dough, 8.0 Ounces of Sauce, 10.0 Ounces of Cheese"
Then I proceed to make the object ressippi and set that to the clone of recipeOne, so all good from here...then I change ressippi's name to "Pineapple Pizza" and that prints out fine but it doesnt print the 3 ingredient objects that recipeOne stored, which it is suppose to do!
Add a copy constructor to the recipe class, which creates a new instance of recipe and copies all of the fields from an original recipe.
Recipe.java
public class Recipe implements Cloneable {
String name;
final int INGREDIENT_ARRAY_MAX = 10;
Ingredient[] ingredients = new Ingredient[INGREDIENT_ARRAY_MAX];
public Recipe(String name) {
this.name = name;
}
//Copy Constructor
private Recipe(Recipe recipe){
this.name = recipe.name;
for(int x = 0; x < recipe.ingredients.length; x++){
this.ingredients[x] = recipe.ingredients[x];
}
}
public static Recipe newInstance(Recipe recipe){
return new Recipe(recipe);
}
//Debug Method
public static void printRecipe(Recipe recipe){
System.out.println("Recipe: " + recipe.name);
for(Ingredient i:recipe.ingredients){
if(i != null && i.getName() != null){
System.out.println("Ingredient: " + i.getName());
}
}
}
//Test Method
public static void main(String[] args) {
Recipe recipe = new Recipe("Chicken Soup");
recipe.ingredients[0] = new Ingredient("Chicken");
recipe.ingredients[1] = new Ingredient("Broth");
Recipe copy = new Recipe(recipe);
copy.ingredients[2] = new Ingredient("Rice");
copy.name = "Chicken Rice Soup";
printRecipe(recipe);
printRecipe(copy);
System.out.println(recipe == copy);
System.out.println(recipe.ingredients == copy.ingredients);
}
}
Ingredient.java
public class Ingredient {
private String name;
public Ingredient(String name){
this.name = name;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
As you have found out, implementing the Cloneable doesn't actually clone the object. You'll have to implement the clone() method sensibly, and if you want a deep copy, that's what you should implement.
Now, creating a new Recipe object with the same Name attribute is quite OK. And changing the name for the new object afterwards is also quite okay, it won't change the name of the first object as java String's are immutable.
You may want to have a look at the commons-beanutils package, which provides handy code for cloning objects.
Finally, as for "...only passes references..." you should read eg. this and this thread.
Cheers,
Serialize it! Take a look at the deepClone function as exampled here: http://www.avajava.com/tutorials/lessons/how-do-i-perform-a-deep-clone-using-serializable.html
The other replies on Strings being immutable are true of course, but the problem you tried to describe with the String example was just a bad example; complexer objects like the Ingredients array still is copied-by-reference.
Also: change the name of your array so that it doesn't match the class name (=confusing):
Ingredient Recipe[] = new Ingredient[INGREDIENT_ARRAY_MAX];