9 Replies - 1251 Views - Last Post: 13 December 2012 - 02:00 AM Rate Topic: -----

#1 flyingkipperr  Icon User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 5
  • Joined: 12-December 12

Question about invoking toString() method in subclass

Posted 12 December 2012 - 10:25 PM

Hello. I am writing a program that takes in thirty grades for a class and outputs the mean, median, and mode of the entire class. I am confused about how to output the data using the toString method. Please help! Also if you find any other errors that aren't related to outputting the data then please tell me how to correct them. Thank you.
I'll post my parent class at top and subclass at the bottom.
This is my parent class:

import java.util.Scanner;
public class ClassGrades 
{
// instance variables
    static int [] gradeSet; 
    static int mean;
    //static int median;
    static int grades;
// override the toString method
        public String toString()
        {          
            return ("Mean:"+ClassGrades.getMean(gradeSet) +"\n"+"Median:"
                    +ClassGrades.getMedian(gradeSet) +"\n"+"Mode:"
                    +ClassGrades.getMode(gradeSet));
         }
// set the grade values 
        public static int [] setGrades()
        {        
                Scanner keyboard = new Scanner(System.in);
                int[] gradeSet = new int[3];
                int b = 0;
                System.out.print("Hello Teach! Please enter the grades of your thirty students below\n"
                + "Enter negative number to cancel.\n");
                for(int i = 0; i < gradeSet.length; ++i) {
                System.out.println("Please Enter Grade: \n");
                gradeSet[i] = keyboard.nextInt();
                if(gradeSet[i] < 0 && gradeSet.length > 2)
                    break;
                    ++b;
                }
                return (gradeSet);
        }
//calculate the mean      
        public static int getMean(int gradeSet [])
        {
                int sum = 0;
                int average=0;                
                for(int j = 0; j < gradeSet.length; j++)
                {
                    sum += gradeSet[j];
                        average = sum / gradeSet.length;
                }
                return average;
        }
//calculate median
        public static int getMedian(int gradeSet[])
        {       
                int median;
                if (grades % 2 != 0) 
                {
                    median = gradeSet[gradeSet.length / 2];
                }
                else 
                {
                    median = (gradeSet[(gradeSet.length / 2) - 1] + 
                    gradeSet[gradeSet.length / 2]) / (int)2;
                }
                return (median);
        }   
//calculate mode
        public static int getMode(int gradeSet[])
        {
                int max=0, maxCount=0;
                int length=gradeSet.length;
                for (int i = 0; i <length; ++i) 
                {
                    int count = 0;
                        for (int j = 0; j <length; ++j) 
                        {
                            if (gradeSet[j] == gradeSet[i]) ++count;
                        }
                            if (count > maxCount)
                            {
                                maxCount = count;
                                max = gradeSet[i];
                            }
                }
                return max;
        }
}




This is my subclass:
import classgrades.*;
import java.util.Scanner;

public class ClassGradesTest extends ClassGrades 
{

public static int getMean(){
   int m = ClassGrades.getMean(gradeSet);
    return (m);          
}
public static int getMedian(){
    int med = ClassGrades.getMedian(gradeSet);
    return (med);
}
public static int getMode(){
    int mod=ClassGrades.getMode(gradeSet);
    return (mod);
}
public static void main(String[] args)
{
ClassGrades.setGrades();

}
   }



  






Is This A Good Question/Topic? 0
  • +

Replies To: Question about invoking toString() method in subclass

#2 Sheph  Icon User is offline

  • D.I.C Lover
  • member icon

Reputation: 447
  • View blog
  • Posts: 1,032
  • Joined: 12-October 11

Re: Question about invoking toString() method in subclass

Posted 12 December 2012 - 10:47 PM

You are not even making use of polymorphism here. All of your methods and fields are static, so they are unable to be extended and overridden. Start by removing static from all of your stuff.

The toString() method is a perfect example of why you shouldn't use static. Because it is not static, you are allowed to override the method, so it returns an appropriate String. Then when you want to output that String you send your object to the println method which takes an Object parameter and calls toString().
MyObject obj = new MyObject();
System.out.println( obj ); // calls obj.toString() and prints it
System.out.println( obj.toString() ); // prints same thing

Was This Post Helpful? 0
  • +
  • -

#3 flyingkipperr  Icon User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 5
  • Joined: 12-December 12

Re: Question about invoking toString() method in subclass

Posted 12 December 2012 - 10:54 PM

View PostSheph, on 12 December 2012 - 10:47 PM, said:

You are not even making use of polymorphism here. All of your methods and fields are static, so they are unable to be extended and overridden. Start by removing static from all of your stuff.

Thank you.
So should nothing be static? Not even the public main? And should I make the variables private instead?
Was This Post Helpful? 0
  • +
  • -

#4 Martyr2  Icon User is offline

  • Programming Theoretician
  • member icon

Reputation: 5201
  • View blog
  • Posts: 13,944
  • Joined: 18-April 07

Re: Question about invoking toString() method in subclass

Posted 12 December 2012 - 10:55 PM

With the toString() function simply think of it as a function that asks "How do I print myself?" So when you put it in your subclass, it is "How do I print out a representation of ClassGradesTest?"

When I do something like...

ClassGradesTest test = new ClassGradesTest();

System.out.println(test.toString());



What am I really asking? I am asking the instance "test" to print out some kind of value that represents itself. It might be a string that reads "Mean: 4, Median: 5, Mode: 3". So before you tackle that function you should always ask yourself how is it going to represent and print out its data to other.

Then it is just a matter of coding it up as a function in a class...

@Override public String toString() {
    return "Mean: " + mean.toString() + ", Median: " + median.toString() + ", Mode: " + mode.toString();
}



Here the method is overriding the toString() provided by a parent class, or until it eventually reaches "Object" the base class of all objects. So when we create an instance of our class and call toString() it will check to see if you have overridden the function first and if not, it will go up the hierarchy until it finds one or hits the version provided by Object.

Hope that simplified things for you.

:)
Was This Post Helpful? 1
  • +
  • -

#5 Sheph  Icon User is offline

  • D.I.C Lover
  • member icon

Reputation: 447
  • View blog
  • Posts: 1,032
  • Joined: 12-October 11

Re: Question about invoking toString() method in subclass

Posted 12 December 2012 - 11:19 PM

View Postflyingkipperr, on 13 December 2012 - 12:54 AM, said:

View PostSheph, on 12 December 2012 - 10:47 PM, said:

You are not even making use of polymorphism here. All of your methods and fields are static, so they are unable to be extended and overridden. Start by removing static from all of your stuff.

Thank you.
So should nothing be static? Not even the public main? And should I make the variables private instead?

I'll try to explain it the best I can. The main method has to be static. The program has to start from a method which does not require an object to be made. There are also some reasons for making a method or field static (such as the Math class), but for the most part one should strive for non-static class members.

If you look at your code, all of your fields are static. This means when you extend your parent class, you are not bringing any of that data along to be part of the subclass. Secondly, you cannot override any of the static methods if you wanted to change the way calculating the mode works, for instance. When you remove the static modifier, each member becomes a part of the every object of that class.
public class ThreeNumbers {
    static int a, b, c;
}

In this situation, the class ThreeNumbers contains 3 numbers, and you could get/set them by referring to ThreeNumbers.a, ThreeNumbers.b, etc. But this class only ever has three numbers. If you wanted another set of three different numbers, you can't have them. Anything that extends ThreeNumbers can't change how the three numbers are used.
public class ThreeNumbers {
    private int a, b, c;

    public ThreeNumbers() {} // default all to 0

    public ThreeNumbers(int a, int b, int c) {
        this.a = a;
        this.b = b;
        this.c = c;
    }

    public void setA(int a) { this.a=a; };
    public int getA() { return a; }

    ...
}

In this example, every instance of a ThreeNumbers object contains 3 numbers, and you can have as many as you want. Furthermore, a subclass could override the method getC(), so that it returned getA() + getB() + c.

That part is where your question about making the variables private comes in. That is called encapsulation. A classes variables should be private and accessed/changed via methods. In this manner, subclasses can change how the user of your class sees or changes the data by overriding the proper methods (example: toString())
Was This Post Helpful? 1
  • +
  • -

#6 flyingkipperr  Icon User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 5
  • Joined: 12-December 12

Re: Question about invoking toString() method in subclass

Posted 12 December 2012 - 11:23 PM

thank you!
This is very helpful.
Was This Post Helpful? 0
  • +
  • -

#7 flyingkipperr  Icon User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 5
  • Joined: 12-December 12

Re: Question about invoking toString() method in subclass

Posted 13 December 2012 - 12:43 AM

ok so i edited my code and now i can't get the methods to perform what they are supposed to. Can you please tell me how to call them or what i'm doing wrong.
Parent Class:
package classgrades;
import java.util.Scanner;
public class ClassGrades 
{
// instance variables
    private int [] gradeSet; 
    private int mean;
    private int median;
    private int mode;
    private int grades;
    public  String m;
// override the toString method
    @Override
        public String toString() 
        {   
            m = "Mean: " + mean 
            + ", Median: " + median + 
              ", Mode: " + mode;
            return m;
        }
// set the grade values 
        public int [] setGrades()
        {        
                Scanner keyboard = new Scanner(System.in);
                gradeSet = new int[3];
                int b = 0;
                System.out.print("Hello Teach! Please "
                        + "enter the grades of your thirty students below\n"
                + "Enter negative number to cancel.\n");
                for(int i = 0; i < gradeSet.length; ++i) {
                System.out.println("Please Enter Grade: \n");
                gradeSet[i] = keyboard.nextInt();
                if(gradeSet[i] < 0 && gradeSet.length > 2)
                    break;
                    ++b;
                }
                return (gradeSet);
        }
//calculate the mean      
        public int getMean(int [] gradeSet)
        {
                int sum = 0;
                int average;                
                for(int j = 0; j < gradeSet.length; j++)
                {
                    sum += gradeSet[j];
                        average = sum / gradeSet.length;
                        
                }
                return mean;
        }
//calculate median
        public int getMedian(int [] gradeSet)
        {       
                int medianInt;
                if (grades % 2 != 0) 
                {
                    medianInt = gradeSet[gradeSet.length / 2];
                }
                else 
                {
                    medianInt = (gradeSet[(gradeSet.length / 2) - 1] + 
                    gradeSet[gradeSet.length / 2]) / (int)2;
                    median = medianInt;
                }               
                return (median);
        }   
//calculate mode
        public int getMode(int [] gradeSet)
        {
                int max=0, maxCount=0;
                int length=gradeSet.length;
                for (int i = 0; i <length; ++i) 
                {
                    int count = 0;
                        for (int j = 0; j <length; ++j) 
                        {
                            if (gradeSet[j] == gradeSet[i]) ++count;
                        }
                            if (count > maxCount)
                            {
                                maxCount = count;
                                max = gradeSet[i];
                                mode = max;
                            }
                }
                return mode;
        }
}

Subclass:

package classgrades;
import classgrades.*;
import java.util.Scanner;

public class ClassGradesTest extends ClassGrades 
{
//getters
       
  public int getMean()
         {
            this.getMean();
            return (this.getMean());
         }
        public int getMedian()
        {
            this.getMedian();
            return (this.getMedian());
        }
        public int getMode()
        {       
            this.getMode();
            return (this.getMode());
        }     

public static void main(String[] args)
{
ClassGrades obj = new ClassGrades();
System.out.println( obj.setGrades() );
System.out.println(obj);
}
   }





The output looks like this:
run:
Hello Teach! Please enter the grades of your thirty students below
Enter negative number to cancel.
Please Enter Grade: 

4
Please Enter Grade: 


4
Please Enter Grade: 

4
[[email protected]
Mean: 0, Median: 0, Mode: 0
BUILD SUCCESSFUL (total time: 2 seconds)



Was This Post Helpful? 0
  • +
  • -

#8 Sheph  Icon User is offline

  • D.I.C Lover
  • member icon

Reputation: 447
  • View blog
  • Posts: 1,032
  • Joined: 12-October 11

Re: Question about invoking toString() method in subclass

Posted 13 December 2012 - 01:05 AM

Your argument to your methods is named the same as your instance variable, gradeSet. You set the instance variable with values in your setGrades method, but in your other methods, you have an argument with the same name, so when you try to access it by the name, you will be accessing the argument. My suggestion is to remove the parameter from the methods and use the instance variable.

Also, your subclass doesn't actually do anything for you here. You don't call any of the methods from your subclass in your program. If you did, you'd be stuck in an infinite loop and eventually get a Stack Overflow Error. If you want to call the parent class' version of an overridden method, use the keyword super, like: super.getMode();

You should also try to use the accessor methods in your parent class instead of directly accessing the variables, to allow for polymorphic behavior. Imagine a toString() method in the parent class that looks like this:
@Override
public String toString() 
{   
    return "Mean: " + getMean()
        + ", Median: " + getMedian() + 
        ", Mode: " + getMode();
}

Now when you override getMedian() to always return 4, no matter what the case, the toString method doesn't need to be overridden to cope with that change.
Was This Post Helpful? 0
  • +
  • -

#9 flyingkipperr  Icon User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 5
  • Joined: 12-December 12

Re: Question about invoking toString() method in subclass

Posted 13 December 2012 - 01:31 AM

Thank you! It seems to be working now... but i was hoping you could help me make the code more dynamic (error checking, overloading methods, etc...) and make my subclass more useful.
Here is my updated code:

Parent Class:
package classgrades;

import java.util.Scanner;
public class ClassGrades 
{
// instance variables
    private int [] gradeSet; 
    private int mean;
    private int median;
    private int mode;
    private int grades;
    public  String m;
// override the toString method
    @Override
        public String toString() 
        {   
        return null;
        }
// set the grade values 
        public int [] setGrades()
        {        
                Scanner keyboard = new Scanner(System.in);
                gradeSet = new int[3];
                int b = 0;
                System.out.print("Hello Teach! Please "
                        + "enter the grades of your thirty students below\n"
                + "Enter negative number to cancel.\n");
                for(int i = 0; i < gradeSet.length; ++i) {
                System.out.println("Please Enter Grade: \n");
                gradeSet[i] = keyboard.nextInt();
                if(gradeSet[i] < 0 && gradeSet.length >= 30)
                    break;
                    ++b;
                }
                return (gradeSet);
        }
//calculate the mean      
        public int Mean()
        {
                int sum = 0;
                int average =0;                
                for(int j = 0; j < gradeSet.length; j++)
                {
                    sum += gradeSet[j];
                        average = sum / gradeSet.length;
                        mean = average;
                }
                return mean;
        }
//calculate median
        public int Median()
        {       
                int medianInt;
                if (grades % 2 != 0) 
                {
                    medianInt = gradeSet[gradeSet.length / 2];
                }
                else 
                {
                    medianInt = (gradeSet[(gradeSet.length / 2) - 1] + 
                    gradeSet[gradeSet.length / 2]) / (int)2;
                    median = medianInt;
                }               
                return (median);
        }   
//calculate mode
        public int Mode()
        {
                int max=0, maxCount=0;
                int length=gradeSet.length;
                for (int i = 0; i <length; ++i) 
                {
                    int count = 0;
                        for (int j = 0; j <length; ++j) 
                        {
                            if (gradeSet[j] == gradeSet[i]) ++count;
                        }
                            if (count > maxCount)
                            {
                                maxCount = count;
                                max = gradeSet[i];
                                mode = max;
                            }
                }
                return mode;
        }
}



Subclass:
package classgrades;
import classgrades.*;
import java.util.Scanner;

public class ClassGradesTest extends ClassGrades 
    {
    public String toString() 
        {   
                    return "Class Mean: " + super.Mean()
                    + "\nClass Median: " + super.Median() + 
                        "\nClass Mode: " + super.Mode();
        }
    public static void main(String[] args)
        {
        ClassGradesTest obj = new ClassGradesTest();
        System.out.println( obj.setGrades() );
        System.out.println(obj);
        }
    }


Was This Post Helpful? 0
  • +
  • -

#10 Sheph  Icon User is offline

  • D.I.C Lover
  • member icon

Reputation: 447
  • View blog
  • Posts: 1,032
  • Joined: 12-October 11

Re: Question about invoking toString() method in subclass

Posted 13 December 2012 - 02:00 AM

I liked your previous version (post #7) better than the newest one. If you just make a few simple changes that I mentioned:
import java.util.Scanner;

public class ClassGrades {

	// remove unneeded variables, use get methods instead
	private int[] gradeSet;

	@Override
	public String toString() {
		return "Mean: " + getMean() + ", Median: " + getMedian() + ", Mode: "
				+ getMode();
	}
	// change to void, add a getGrades method if you want the array
	public void setGrades() {
		Scanner keyboard = new Scanner(System.in);
		gradeSet = new int[3];
		int b = 0;
		System.out.print("Hello Teach! Please "
				+ "enter the grades of your thirty students below\n"
				+ "Enter negative number to cancel.\n");
		for (int i = 0; i < gradeSet.length; ++i) {
			System.out.println("Please Enter Grade: \n");
			gradeSet[i] = keyboard.nextInt();
			if (gradeSet[i] < 0 && gradeSet.length > 2)
				break;
			++b;
		}
	}

	public int getMean() {
		int sum = 0;
		int average = 0;
		for (int j = 0; j < gradeSet.length; j++) {
			sum += gradeSet[j];
			average = sum / gradeSet.length;

		}
		return average;
	}

	public int getMedian() {
		int medianInt;
		if (gradeSet.length % 2 != 0) {
			medianInt = gradeSet[gradeSet.length / 2];
		} else {
			medianInt = (gradeSet[(gradeSet.length / 2) - 1] + gradeSet[gradeSet.length / 2])
					/ (int) 2;
		}
		return medianInt;
	}

	public int getMode() {
		int max = 0, maxCount = 0, mode = 0;
		int length = gradeSet.length;
		for (int i = 0; i < length; ++i) {
			int count = 0;
			for (int j = 0; j < length; ++j) {
				if (gradeSet[j] == gradeSet[i])
					++count;
			}
			if (count > maxCount) {
				maxCount = count;
				max = gradeSet[i];
				mode = max;
			}
		}
		return mode;
	}

	public static void main(String[] args) {
		ClassGrades grades = new ClassGrades();
		grades.setGrades();
		System.out.println(grades);
	}
}

I don't really see a need for a subclass here...
Was This Post Helpful? 0
  • +
  • -

Page 1 of 1