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:

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

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);

      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


      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.

Recommended Answers

All 41 Replies

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 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).

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?

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.

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();

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.

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.

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.

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;
}

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?

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.

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
[B] Artist performer;[/B]
 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?

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.

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".

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
[B] Artist performer;[/B]
 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).

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.

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.

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 = [B]new[/B] 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.

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 = [B]new[/B] CdwArtist(input.nextLine());

OK, that makes sence, because I set this one up differently than the others, so the set is included. Part of that easier quicker way I was referrring to in an earlier post.
That is the line that is going to pull that parameter in form the new class. It all starts to become clearer now.
That will not put it into my artist name into the array.
I want to use some derivitive of
cds.setArtist();
but do not know off the top of my head what to use. Seems like artist, or CdwArtist would go in the parenthsis, but I know that is not right. I am still a little shakey on the whole array process having just started this last week.
I am headed home now, I will get it.
By the way, I am reading Java, How to Program 6th Edition. (Deitel)
So far I am through chapter 10, and the most learning I have done is out here at the hands of you guys.
I wish I had know this site was here at the beginning, I would have a much better foundation than I do now.

That will not put it into my artist name into the array.
I want to use some derivitive of
cds.setArtist();

If you have changed the definition of the array to CdwArtist cds[], the array now holds the new object type, which does not need the setArtist() call.

I am at home, and my code is at work, but I have not touched the definition yet.
How can that simple name change, keep all the current Compactdisk parameters, and add the new cdwartist one?
Simple because cdwartist is a sub of the compactdisk class?

Because that is what inheritance (subclassing) is meant for. The subclass extends the capability of the base class by adding extra functionality or giving specific functionality (overriding) behavior that is meant to be generic at the base class level.

Cool. Cannot wait to see that work. I will give it a shot tomorrow and let you know how it goes. If I can get it to work I am going to try something else that will help reinforce some of this. Repetition is one of my keys to picking stuff up.
I appreciate your help.

I love that link, thanks so much! I am going to read it again as soon as I am done here.
I am a little disappointed, I thought for sure I could get this Array moved over to the extended class, it sounded so simple last night. I have gone over and over my changed code, and for the last several adjustments I am getting the same error, cannot find symbol, and it is pointing to "new" in the bolded line below. I know the problem is not the word new, what does this error indicate?
I know there is a problem with the erray, but this error does not seem to point me in any direction.

import java.util.*;

public class Inventory 
{// begin class Inventory

 public static int maxlength = 0;
  public static CdwArtist[] sort(CdwArtist[] cds)
   { 
	Arrays.sort(cds, 0, maxlength); 
	return cds;
	}
	
 public static String toString(CdwArtist[] 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 
	CdwArtist[] cds = new CdwArtist[100];
	
 
	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
	  [B]cds[i] = new CdwArtist();[/B]
	  cds[i].setName(nameInput);
	  
	  System.out.print("Enter CD Artist Name: "); // prompt for artist name
	  CdwArtist artist = new CdwArtist(input.nextLine()); 
	  	  	  
	  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

Do you have any parameters in the CDArtist classes contructor?

E.g.

public CDArtist(String artistname)

Easy fix. Replace your CdwArtist with:

import java.util.*;

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

You didn't have a default constructor, which is what you were trying to call when you made your CdwArtist object. The one in there sets the string to nothing so you can set it later if you want. If you don't want one, you can just add the input.nextLine() statement as a parameter when creating.

commented: hehe We're typing about the same thing at the same time. He is trying to learn at least! +2
Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.