Inheritance

S

SpeedRunner

Guest
Having trouble with the subclass in this program...

Code:
/**
   This simply provides a driver to exercise the exciting
   Student class.

   @see Student
 */
public class StuList2
{
   /**
      Should not instantiate!
    */
   private StuList2(){};

   public static void main(String[] args)
   {
      Student[] stus = new Student[8];
      stus[0] = new Student(123,"Fred",3.4);
      stus[1] = new Student(234,"Suzy");
      stus[2] = new Student(345,4.0);
      stus[3] = new Student(456);
      stus[4] = new GradStudent(567,"Tom",3.6,"Computers");
      stus[5] = new GradStudent(678);
      stus[6] = new GradStudent(789,"Ned",3.3);
      stus[7] = new GradStudent(891,"Betty");

      stus[4].setGPA(3.9);
      stus[4].setName("Thomas");

      for(int i=0; i<stus.length; i++)
      {
         System.out.println(stus[i]);
         System.out.println(stus[i].getName() + " has number " + stus[i].getNumber() + "\n");
      }
   }
}
// Student class encapsulates a student's name, number, and gpa.
class Student
{
	// creates variables for student class
	private int number;
	private String name;
	private double GPA;

	// constructs a new student, given a name, number and gpa.
	public Student(int n, String m, double g)
	{
		number = n;
		name = m;
		GPA = g;
	}

	public Student(int number, double GPA)
	{
		this(number, "Student " + number, GPA);
	}

	public Student(int number)
	{
		this(number, "Betty", 0.0);
	}

	public Student(int number, String name)
	{
		this(number, name, 0.0);
	}

	public String getName()
	{
		return name;
	}

	public int getNumber()
	{
		return number;
	}

	public double setGPA(double g)
	{
		GPA = g;
		return GPA;
	}

	public String setName(String m)
	{
		name = m;
		return name;
	}

	public String toString()
	{
		return (name + ", " + number + ", " + GPA);
	}
}

class GradStudent extends Student
{
	// creates thesis variable
	private String thesis;
	private int number;
	private String name;
	private double GPA;

	public GradStudent(int n, String m, double g, String t)
	{
		super(n, m, g);
		thesis = t;
		GPA = g;
		name = m;
		number = n;
	}

	public GradStudent()
	{
		this(number, name, GPA, thesis);
	}

	public GradStudent(int number)
	{
		this(number, "GradStudent " + name, 0.0, "Undecided");
	}

	public GradStudent(int number, String name, double g)
	{
		this(number, name, GPA, "Undecided");
	}

	public GradStudent(int number, String name)
	{
		this(number, name, "0.0", "Undecided");
	}

}

It's giving me these errors:
Code:
C:\Documents and Settings\Marshall\My Documents\JAVA\StuList2.java:114: cannot reference number before supertype constructor has been called
		this(number, name, GPA, thesis);
                     ^
C:\Documents and Settings\Marshall\My Documents\JAVA\StuList2.java:114: cannot reference name before supertype constructor has been called
		this(number, name, GPA, thesis);
                             ^
C:\Documents and Settings\Marshall\My Documents\JAVA\StuList2.java:114: cannot reference GPA before supertype constructor has been called
		this(number, name, GPA, thesis);
                                   ^
C:\Documents and Settings\Marshall\My Documents\JAVA\StuList2.java:114: cannot reference thesis before supertype constructor has been called
		this(number, name, GPA, thesis);
                                        ^
C:\Documents and Settings\Marshall\My Documents\JAVA\StuList2.java:119: cannot reference name before supertype constructor has been called
		this(number, "GradStudent " + name, 0.0, "Undecided");
                                              ^
C:\Documents and Settings\Marshall\My Documents\JAVA\StuList2.java:124: cannot reference GPA before supertype constructor has been called
		this(number, name, GPA, "Undecided");
                                   ^
C:\Documents and Settings\Marshall\My Documents\JAVA\StuList2.java:129: cannot find symbol
symbol  : constructor GradStudent(int,java.lang.String,java.lang.String,java.lang.String)
location: class GradStudent
		this(number, name, "0.0", "Undecided");
                ^
7 errors

Tool completed with exit code 1

Clearly I am making a mistake, as I'm having the same error 6 different times. What does that error mean?
 
The superclass should be working fine, the constructors in the subclass are not.

what I've tried:

Code:
	public GradStudent()
	{
		this(super.number, super.name, super.GPA, thesis);
	}

Tried putting "super." in there. Didn't help at all, only added more errors.

also tried

Code:
	public GradStudent()
	{
		super(number, name, GPA, thesis);
	}

Thought that might get me closer to fixing it, it did not. My book doesnt seem to give me a clear idea how to make constructors in a subclass, so I'm kinda playing a game of trail-and-error.
 
You can't reference instance variables in the super call like that. So this is all you need for you GradStudent constructor that takes no parameters unless you want other default follows other than null and 0.

Code:
public GradStudent() {}

Plus GradStudent doesn't need the following because they already exist in the super class.

Code:
	private int number;
	private String name;
	private double GPA;

Also, the names of your constructor parameters sucks.

Code:
public GradStudent(int n, String m, double g, String t)
{
	super(n, m, g);
	thesis = t;
}

It is common to use a naming convention for instance variables. Prefixing your instance variables with my or a _ is common. I prefer _.

Code:
public GradStudent(int number, String name, double gpa, String thesis)
{
	super(number, name, gpa);
	_thesis = thesis;
}

And now you don't have shitty parameters names which should be punishable by death.
 
SpeedRunner said:
The superclass should be working fine, the constructors in the subclass are not.

Correct, I understand that.
SpeedRunner said:
what I've tried:

Code:
	public GradStudent()
	{
		this(super.number, super.name, super.GPA, thesis);
	}

Tried putting "super." in there. Didn't help at all, only added more errors.

This is bad form. Since you are in a subclass you don't need to AND SHOULDN'T be even trying to access members like this. You are subclassing for a reason, so that you don't have to re-do all that code. When you subclass you only need to include the information that is relevant and makes that case special, i.e. a grad student is a student with the addition that he also has a thesis. Does that make sense?
SpeedRunner said:
also tried

Code:
	public GradStudent()
	{
		super(number, name, GPA, thesis);
	}

Thought that might get me closer to fixing it, it did not. My book doesnt seem to give me a clear idea how to make constructors in a subclass, so I'm kinda playing a game of trail-and-error.

You're getting closer but you need to read more about calling super methods. Calling super() in the form you specified is going to look for a constructor method in the SUPER class with the parameters int, String, double, String. Does one exist? Why does the super class need to know about the thesis? (hint: it doesn't and shouldn't). So why are you trying to pass it to the super class?

Hopefully I gave you a few things to think about. If you need any more help or if you need conceptual help, perhaps another example you could cook up to talk more about the "super" keyword, I would be more than happy to help you out.
 
Are you suggesting that I should build the gradstudent constructors in the superclass? (Would that even work? :confused: )
 
SpeedRunner said:
Are you suggesting that I should build the gradstudent constructors in the superclass? (Would that even work? :confused: )

No, and you're right to think that's a bad thing to do. Since a grad student is still a student with more information (a thesis) then only the grad student class should know about that.

Using the super keyword will call the method with that signature in the super class. If you want to call a constructor, use super(param1, param2, ... paramN), passing in the relevant information. Remember you are using inheritance so that you don't have to store redundant information in each of your subclasses, hence only your subclasses should know about the information that is unique to them (the thesis in the case of the grad student).

You were on the right track with:
Code:
public GradStudent()
{
	super(number, name, GPA, thesis);
}

but why are you trying to tell the student's constructor about the thesis? How would you set the thesis in the grad student object normally if it weren't inheriting? Also, where are those variables (number, name, GPA, thesis) coming from? If they weren't passed into the function then the compiler is going to think you're using the ones defined in the class, which haven't been initialized yet, since you're in the constructor.
 
I think I almost got it. I have a few compiler errors though

Code:
class GradStudent extends Student
{
	// creates thesis variable
	private String aThesis;

	public GradStudent(int number, String name, double GPA, String thesis)
	{
		super(number, name, GPA);
		aThesis = thesis;
	}
	public GradStudent(int number)
	{
		super(number);
		this(number, "GradStudent " + number, 0.0, "Undecided");
	}
	public GradStudent(int number, String name, double GPA)
	{
		super(number, name, GPA);
		this(number, name, GPA, "Undecided");
	}
	public GradStudent(int number, String name)
	{
		super(number, name, GPA);
		this(number, name, 0.0, "Undecided");
	}
}

Code:
C:\Documents and Settings\Marshall\My Documents\JAVA\StuList2.java:108: call to this must be first statement in constructor
		this(number, "GradStudent " + number, 0.0, "Undecided");
                    ^
C:\Documents and Settings\Marshall\My Documents\JAVA\StuList2.java:113: call to this must be first statement in constructor
		this(number, name, GPA, "Undecided");
                    ^
C:\Documents and Settings\Marshall\My Documents\JAVA\StuList2.java:117: GPA has private access in Student
		super(number, name, GPA);
                                    ^
C:\Documents and Settings\Marshall\My Documents\JAVA\StuList2.java:118: call to this must be first statement in constructor
		this(number, name, 0.0, "Undecided");
                    ^
4 errors

Tool completed with exit code 1

Am I getting closer?
 
SpeedRunner said:
I think I almost got it. I have a few compiler errors though

Code:
...

Am I getting closer?

Yes that is much better. However you must now realize that you can only call one of either super() or this() in the constructor since they both must be the first line of code in the constructor. I recommend not calling another constructor using this() and just setting the properties manually as is usually done in constructors. I'm not sure what most people's opinions on this are but I consider bad style to call another constructor from a constructor.
 
generelz said:
I recommend not calling another constructor using this() and just setting the properties manually as is usually done in constructors. I'm not sure what most people's opinions on this are but I consider bad style to call another constructor from a constructor.

Uh, constructor chaining (that's the term for it) isn't bad. It is good because it removes code duplication - even if it is as trivial as instance variable initialization.
 
Ok, I've got it to compile. Here's what I did:

Code:
class GradStudent extends Student
{
	// creates thesis variable
	private String aThesis;

	public GradStudent(int number, String name, double GPA, String thesis)
	{
		super(number, name, GPA);
		aThesis = thesis;
	}

	public GradStudent(int number)
	{
		super(number, "GradStudent " + number, 0.0);
		aThesis = "Undecided";
	}

	public GradStudent(int number, String name, double GPA)
	{
		super(number, name, GPA);
		aThesis = "Undecided";
	}

	public GradStudent(int number, String name)
	{
		super(number, name, 0.0);
		aThesis = "Undecided";
	}
}

However, when the program runs its still missing something.

It SHOULD look like this:
Code:
Fred, 123, 3.4
Fred has number 123

Suzy, 234, 0.0
Suzy has number 234

Student 345, 345, 4.0
Student 345 has number 345

Student 456, 456, 0.0
Student 456 has number 456

Thomas, 567, 3.9, Computers
Graduate Thomas has number 567

GradStudent 678, 678, 0.0, Undecided
Graduate GradStudent 678 has number 678

Ned, 789, 3.3, Undecided
Graduate Ned has number 789

Betty, 891, 0.0, Undecided
Graduate Betty has number 891

But it looks like this:
Code:
Fred, 123, 3.4
Fred has number 123

Suzy, 234, 0.0
Suzy has number 234

Student 345, 345, 4.0
Student 345 has number 345

Student 456, 456, 0.0
Student 456 has number 456

Thomas, 567, 3.9
Thomas has number 567

GradStudent 678, 678, 0.0
GradStudent 678 has number 678

Ned, 789, 3.3
Ned has number 789

Betty, 891, 0.0
Betty has number 891

What's missing is the thesis and the word "Graduate " before the "Name has number xxx"

So, here's an idea I came up with.

At the end of the GradStudent class, I put in a toString method.

Code:
	public String toString()
	{
		return(("Graduate " + name) + ", " + number + ", " + GPA + aThesis);
	}

I hope that's what I'm supposed to do. But when this compiled, it gave me these errors:

Code:
C:\Documents and Settings\Marshall\My Documents\JAVA\StuList2.java:125: name has private access in Student
		return(("Graduate " + name) + ", " + number + ", " + GPA + aThesis);
                                      ^
C:\Documents and Settings\Marshall\My Documents\JAVA\StuList2.java:125: number has private access in Student
		return(("Graduate " + name) + ", " + number + ", " + GPA + aThesis);
                                                     ^
C:\Documents and Settings\Marshall\My Documents\JAVA\StuList2.java:125: GPA has private access in Student
		return(("Graduate " + name) + ", " + number + ", " + GPA + aThesis);
                                                                     ^
3 errors

Tool completed with exit code 1

So I thought, hey, maybe a super would solve this problem.
Code:
	public String toString()
	{
		super(number, name, GPA);
		return(("Graduate " + name) + ", " + number + ", " + GPA + aThesis);
	}

Code:
C:\Documents and Settings\Marshall\My Documents\JAVA\StuList2.java:125: call to super must be first statement in constructor
		super(number, name, GPA);

So all that does is add an extra error. I'm stuck again. :(
 
haha... I get it. I have to call the original toString method.

Code:
	public String toString()
	{
		return "Graduate " + super.toString() + ", " + aThesis;
	}

Now the program works properly.

^_^

Thanks guys.
 
Back
Top