954,541 Members — Technology Publication meets Social Media
Username:
Password:
Lost login information?
Have something to say? Contribute New Article Reply to this Article

Class and Sub Class

I thought I understood how this worked, but maybe I do not.
I intentionally left a field out of my compactdisk class (artist) so that I could create a sub class later, impliment it, and see how that whole thing worked.
Sounded simple, I still think it is, I just think I am doing something wrong.
Here is my original class:
[CODE][import java.lang.Comparable;

public class Compactdisk implements Comparable
{// begin class

//InventoryCD class has 5 fields
private String name; // Name of cd
private float price; // price of cd
private int itemno; // item number of cd
private int nstock; // how many units in stock
private int i; // cd counter for array
private float value; // value for single cd inventory


//Compact disk class constructor
public Compactdisk()

// 4 fields need to be set up
{
name = "";
price = 0;
itemno = 0;
nstock = 0;
i = 0;
value = 0;
}

// set values
public void setName(String diskName)
{
name = diskName;
}
public void setPrice(float cdPrice)
{
price = cdPrice;
}
public void setItemno(int cdItemno)
{
itemno = cdItemno;
}
public void setNstock(int cdStock)
{
nstock = cdStock;
}
public void setValue(float cdValue)
{
value = cdValue;
}
public void seti(int Count)
{
i = Count;
}


// return values
public String getName()
{
return (name);
}
public float getPrice()
{
return (price);
}
public int getItemno()
{
return (itemno);
}
public int getNstock()
{
return (nstock);
}
public int compareTo(Object in)
{
return ((Comparable)name.toLowerCase()).compareTo((Comparable)((Compactdisk)in).getName().toLowerCase());
}

// returns indivudual inventory value for a disk
public float getValue()
{
return(price * nstock);
}





}// end class
/CODE]
It works ok, does what I want it to do.
I then created this sub class just for cd artist that I thought would just add to it.

import java.util.*;

public class Cdartist extends Compactdisk
{
 private String artist; // artist performing on cd
 
 // Artist constructor
 public Cdartist()
 {
 artist = "";
 }
 
 // set value
 public void setCdArtist(String cdArtist)
 	{ 
 	artist = cdArtist;
	}
		
	// return value
	public String getCdArtist()
	{
	return (artist);
	}
	
	
} //End Class


My understanding was that this new sub class is just an extention of the original and could be used with little or no extra effort. So I changed my Inventory application to include this object accordingly.

import java.util.*;

public class Inventory 
{// begin class Inventory

 public static int maxlength = 0;
  public static Compactdisk[] sort(Compactdisk[] cds)
   { 
	Arrays.sort(cds, 0, maxlength); 
	return cds;
	}
	
 public static String toString(Compactdisk[] cds)
  { 
  	String toSend = "\n\n"; 
	
	for(int i = 0; i < maxlength; i ++)
	toSend = toSend + cds[i].getName() + "\n";
	return toSend;
  } 
  
  public static void main(String[] args)
  {//begin method main
  
   // create cd Array 
	Compactdisk[] cds = new Compactdisk[100];
	
	cds[0] = new Compactdisk(); 
	float totalValue = 0; 
	
	Scanner input = new Scanner(System.in); // create scanner 
	
	// begin display method 
	System.out.print("Enter up to 99 CD Names or STOP to Exit: "); 
	String nameInput = input.nextLine(); //read cd name 
	
	maxlength ++; 
	
	 for(int i = 1; i < cds.length && !nameInput.equalsIgnoreCase("STOP"); i++)
	 {// begin main While
	  cds[i] = new Compactdisk();
	  cds[i].setName(nameInput);
	  
<strong>	  System.out.print("Enter CD Artist Name: "); // prompt for artist name
	 // input=new Scanner(System.in); 
	  cds[i].setCdArtist(input.nextLine()); // artist name input from user
	  </strong>
	  
	  System.out.print("Enter Price of this CD: "); // prompt for price
	  cds[i].setPrice(input.nextFloat()); // price input from user. 
	  while (cds[i].getPrice()<= 0) 
	 	{// begin while 
	   	System.out.print("Price Must Be Greater Than Zero. Enter Price: ");
			cds[i].setPrice(input.nextFloat()); // cd price loop from user.
	  	} // End while 
	  
	  System.out.print("Enter CD Item Number: "); // prompt for cd item number
	  cds[i].setItemno(input.nextInt()); // cds item number input from user 
	  
	  System.out.print("Enter Number of these CDs in Stock: "); // prompt for cd stock 
	  cds[i].setNstock(input.nextInt()); // cds in stock input from user
	  
	  System.out.print("\n\nCD "+cds[i].getName()+", Item Number "+cds[i].getItemno()+","); // display name 
	  System.out.printf(" is worth %c%.2f.",'$', + cds[i].getPrice());//
	  System.out.print("\nWe have "+ cds[i].getNstock()+" copies in stock,");
	  System.out.printf(" making our inventory for this cd worth %c%.2f.\n", '$', + cds[i].getValue()); //inventory value 
	 
	  if(cds[i].getValue() != -1) totalValue = totalValue + cds[i].getValue();
	  System.out.printf("Combined Inventory for all CDs is Worth %c%.2f.\n\n\n", '$', + totalValue);
	  
	  System.out.print("Enter up to 99 CD Names or STOP to Exit: "); 
	  input=new Scanner(System.in); // internal loop prompt 
	  nameInput = input.nextLine(); //name input from user 
	  
	  maxlength ++; 
	  } // End main While
	  
	   //System.out.println(toString(cds));
		System.out.println(toString(sort(cds))); 
		System.out.print("Ending Program."); 

   }// end method main 
} // end class Payroll

I am getting a cannot find symbol error on the new code. This usually means there is a problem with that object, I am guessing Inventory cannot find it. Do I have it set up wrong, or is my logic screwy?
Thanks for any help.

no1zson
Posting Whiz in Training
226 posts since Jul 2007
Reputation Points: 59
Solved Threads: 1
 

cds is an array of CompactDisk, so it didn't have method like setCdArtist, (or getCdArtist)
you can first create a Cdartist, then assign it to a place in cds

tonakai
Junior Poster
121 posts since Feb 2005
Reputation Points: 25
Solved Threads: 11
 

tonakai is correct.

If you are confused about how subclasses act in Java, the vehicle example usually clarifies things:


A vehicle in this definition is something that moves or transports people. An automobile is a type of vehicle with wheels. A car is a type of automobile. A truck is also a type of automobile. A car is not a truck, and a truck is not a car. An automobile is not necessarily a car or truck (it could be a van). A boat is a type of vehicle but not a type of automobile, the reverse is true of automobile.

In terms of hierarchy of classes:
Vehicle is a superclass which only knows that it moves people. Automobile is a subclass of Vehicle and a superclass of car, truck, and van, and only knows that it has wheels (not what type it is). Car, truck, and van are the most specific types of automobiles and know the most about what they can do. Boats are also specific, knowing they cannot use wheels but instead use rudders.

In that way, you cannot assume vehicle can do anything that it's subtypes (automobile or boat) can do, but it's subtypes(automobile and boat) can do anything vehicle can do (as they are vehicles).

TheGathering
Junior Poster
102 posts since Jul 2007
Reputation Points: 22
Solved Threads: 10
 

I must be getting better at this, because I actually understood that. :o)

Two questions.
1. Concerning the setCdArtist method, is that not being created in the extended class? I thought the whole purpose of that class was to create that method for the set and get calls in Inventory.
2. I too thought I should assign it somewhere in cds. I thought my bolded code above would do that.

It is my understanding that I do not want to alter Compactdisk, or else it takes away from the purpose of extending a sub class. So if I do not add it in to the Inventory class as I thought I was doing, where would that insert happen?

no1zson
Posting Whiz in Training
226 posts since Jul 2007
Reputation Points: 59
Solved Threads: 1
 

TheGathering,
Thanks for that. I do think I have the concept of subclasses down, and to use your analogy, Compactdisk would be my vehicle, and Cdartist would be a car or truck.
When I run my application (Inventory) it pulls information from Compactdisk, and therefore Cdartist as an extented class, right? I should not have to alter Compactdisk to add objects in CdArtist, if I understand correctly.
So I am trying to figure out what I need to do in the Inventory class to get cds to recognize this new object.

no1zson
Posting Whiz in Training
226 posts since Jul 2007
Reputation Points: 59
Solved Threads: 1
 
TheGathering, Compactdisk would be my vehicle, and Cdartist would be a car or truck.

The Compactdisk class is really the specification for a car (or Cd no artist) and Cdartist a specification of a truck (cd with an artist).

The car or truck is the object that you instantiate e.g.

Compactdisk cd = new Compactdisk();
Cerberus
Junior Poster
162 posts since Sep 2006
Reputation Points: 27
Solved Threads: 14
 

So then what is my vehicle class?
If Compactdisk is car, and CdArtis is truck, then neither is really a subclass of the other? I was thinking that extending Compactdisk with CdArtist takes everthing as it is, and just adds one more detail.
Am I not doing what I think I am doing?
I want to make my CdArtist a sub class of Compactdisk, and just add that extra object into my array.

no1zson
Posting Whiz in Training
226 posts since Jul 2007
Reputation Points: 59
Solved Threads: 1
 
So then what is my vehicle class? If Compactdisk is car, and CdArtis is truck, then neither is really a subclass of the other? I was thinking that extending Compactdisk with CdArtist takes everthing as it is, and just adds one more detail. Am I not doing what I think I am doing? I want to make my CdArtist a sub class of Compactdisk, and just add that extra object into my array.


The way I'm understanding your hierarchy with the code I wrote is: Comparable is vehicle, Compactdisk is your automobile, and CdArtist is your car.

It seems like a better name would be CDwithArtist for that class.

TheGathering
Junior Poster
102 posts since Jul 2007
Reputation Points: 22
Solved Threads: 10
 

I see. So then I need to add everything that is in Compactdisk in to CdArtist along with my new Artist object, and then change my
Compactdisk cd = new Compactdisk(); to something like
CdArtist cd = new Compactdisk();
in my Inventory application and go from there.

I am not totally sure how to add all that into the new class, so I will get my face in a book here shortly. Thanks for the direction. Let me know if I am off base with this.
Thanks again.

no1zson
Posting Whiz in Training
226 posts since Jul 2007
Reputation Points: 59
Solved Threads: 1
 

I see. So then I need to add everything that is in Compactdisk in to CdArtist along with my new Artist object, and then change my Compactdisk cd = new Compactdisk(); to something like CdArtist cd = new Compactdisk(); in my Inventory application and go from there.

I am not totally sure how to add all that into the new class, so I will get my face in a book here shortly. Thanks for the direction. Let me know if I am off base with this. Thanks again.

public class CdArtist extends Compactdisk
{
Artist person;
public CdArtist(Artist in)
{
person=in;
}
//however you're adding artists

public Artist getArtist()
{return person;}
}


From there you can use:

CdArtist CDwArtists=new CdArtist();

and be able to call any of the methods in Compactdisk as well as .getArtist() from CDwArtists.

You can also use:

Compactdisk CDwArtists = new CdArtist();

If your Compactdisk class needs paramters, then in the constructor for CdArtist you can use something like:

public CdArtist(Artist in, String nameIn)
{
super.name=nameIn;
person=in;
}
TheGathering
Junior Poster
102 posts since Jul 2007
Reputation Points: 22
Solved Threads: 10
 

Wait, no, I take that back.
If Compactdisk is automobile, CDwithArtist is a car, then CDwithArtist "isa" automobile and should inherit everything therein if I just extend it. So I should NOT have to put everything in there manually ... right?
This logic leads me to believe then that I am somewhat close with my original cdartist code, but need to make a few changes in Inventory.
Am I talking in circles now?

no1zson
Posting Whiz in Training
226 posts since Jul 2007
Reputation Points: 59
Solved Threads: 1
 

Yes, what TheGathering said. Perhaps if you called your new class CdExtended it would make a little more sense to you. CdExtended has all of the info of Compactdisk plus artist info. To use that extra info, you need to use the CdExtended object in your code instead of the base level class of Compactdisk.

Ezzaral
Posting Genius
Moderator
15,986 posts since May 2007
Reputation Points: 3,250
Solved Threads: 847
 

Yeah. I posted that before I read his. I think I have a little better grasp on it now. At least enough to start coding some more and see what I can come up with.
I have been meaning to ask this question for awhile, and now is the perfect opportunity.
I see you guys set up your objects different than I do, it looks shorter and quicker, but when I try to emulate that into my own coding I get the same error every time. I just tried it with the stuff TheGather put down:

import java.util.*;

public class CdwArtist extends Compactdisk
{
 
 public String artist; // artist performing on cd
 
 // Artist constructor
<strong> Artist performer;</strong>
 public CdwArtist(Artist in)
 {
 performer=in;
 }
 
 // return value
 public Artist getArtist()
 {
 return performer;
 }
	
} //End Class

but I get "cannot find symbol" on Artist on the bolded line. Seems like it should work, I see it in all the books, why do I get this error?
And exactly what does that line do?

no1zson
Posting Whiz in Training
226 posts since Jul 2007
Reputation Points: 59
Solved Threads: 1
 

I think that the Actor class isn't available to the compiler.

The bolded line is defining that the class has an 'Artist' as a member. Just the same as you might have a class 'shape' that has an Integer variable 'sides' (int sides). The Artist is a user defined class.

Cerberus
Junior Poster
162 posts since Sep 2006
Reputation Points: 27
Solved Threads: 14
 

It just declares a variable of type (class) Artist. You get "Cannot find symbol" because you do not have a class Artist. Your constructor should be

public CdwArtist(String in) {
   artist=in;
 }


since you have declared a String property "artist".

Ezzaral
Posting Genius
Moderator
15,986 posts since May 2007
Reputation Points: 3,250
Solved Threads: 847
 

I see you guys set up your objects different than I do, it looks shorter and quicker, but when I try to emulate that into my own coding I get the same error every time. I just tried it with the stuff TheGather put down:

import java.util.*;

public class CdwArtist extends Compactdisk
{
 
 public String artist; // artist performing on cd
 
 // Artist constructor
<strong> Artist performer;</strong>
 public CdwArtist(Artist in)
 {
 performer=in;
 }
 
 // return value
 public Artist getArtist()
 {
 return performer;
 }
	
} //End Class

but I get "cannot find symbol" on Artist on the bolded line. Seems like it should work, I see it in all the books, why do I get this error? And exactly what does that line do?


Oops, I should have explained (I forget that you haven't written much Java). Artist is referencing an Artist class (which I was assuming you had made already).

This is a basic Artist class as I would think one would be made. Yours might need different requirements so you should edit the class to compensate.

public class Artist
{
public String name, date, producer; //keep adding as needed

public Artist(String n, String d, String p)
{
name=n;
date=d;
producer=p;

}

public String getName(){return name;}
public String getDate(){return date;}
public String getProducer(){return producer;}
/*etc... These are  Accessor methods used to get variables if they
are private or protected.*/
}

If all you need is it to hold a name, then replace Artist person with String artist and set the artist value in the constructor.


If you are referencing the

Artist person;


as being short, that is because nothing has been defined to it. It essentially carries a null value until I declare it's value in the constructor:

public CdwArtist(Artist in)
 {
 performer=in;
 }

here.

As the constructor is the first thing accessed, I can give values to the variables inside the constructor (safer practices in terms of abstract and ease of adding method calls inside the constructor).

TheGathering
Junior Poster
102 posts since Jul 2007
Reputation Points: 22
Solved Threads: 10
 

I see. So my sub class should look like this:

import java.util.*;

public class CdwArtist extends Compactdisk
{
 
 public String artist; // artist performing on cd
 
 // Artist constructor
  public CdwArtist(String in)
 {
 artist=in;
 }
 
 // return value
 public String getArtist()
 {
 return (artist);
 }
	
} //End Class


Which, minus the set method is pretty close to my original class. I was at least on the right track for a change! :o)

I have another meeting to go to now, I do not fully understand the use of (string in) and artist=in just yet, and I will still have to code my Inventory class, but a little reading this evening should set me up for that.
Thanks again guys, you always help get me back in the right direction.

no1zson
Posting Whiz in Training
226 posts since Jul 2007
Reputation Points: 59
Solved Threads: 1
 
I have another meeting to go to now, I do not fully understand the use of (string in) and artist=in just yet, and I will still have to code my Inventory class, but a little reading this evening should set me up for that. Thanks again guys, you always help get me back in the right direction.


The (String in) part is just the parameter declaration of the method signature. You are defining a String parameter named "in". You could call it whatever you like, it's just a variable for the parameter that you will use inside your method. Which leads to the "artist=in" part. You are setting "artist" equal to the parameter that was passed, "in". You could have called it "artistName" instead if you preferred. Then you would set "artist = artistName".

Make sense? It's merely a variable name for that parameter of type String.

Ezzaral
Posting Genius
Moderator
15,986 posts since May 2007
Reputation Points: 3,250
Solved Threads: 847
 

I understand, and for consistency purposes I did change that variable to the same convention I have in the compactdisk class. It helps me relate one to the other.
Why is there no setArtist command needed in this class?
I am coding in the Inventory now to pull that parameter over, I have inserted

System.out.print("Enter CD Artist Name: "); // prompt for artist name
	  CdwArtist artist = <strong>new</strong> CdwArtist(); 
	  cds[i].getArtist(input.nextLine()); // artist name input from user

Seems like I should have "setArtist" in there, not get Artist, but get is all I have defined in the CdwArtist class.
Just as a quick I tried to run it to see if I was lucky, but I get a cannot find symbol on the "new", and on the period before "get". Strange to me. Seems as if I missing a pointer somewhere that should tell Inventory where to look for this variable, but I am not sure what else I would add or where to put it at this point.

no1zson
Posting Whiz in Training
226 posts since Jul 2007
Reputation Points: 59
Solved Threads: 1
 

You are using the constructor in CdwArtist to set the artist when the object is created. Since you no longer have an empty constructor, CdwArtist(), you can't create one like that. You would need the following instead

CdwArtist artist = <strong>new</strong> CdwArtist(input.nextLine());
Ezzaral
Posting Genius
Moderator
15,986 posts since May 2007
Reputation Points: 3,250
Solved Threads: 847
 

This question has already been solved

Post: Markdown Syntax: Formatting Help
You