locked
instantiating an object in the main method using a constructor with parameters from another class RRS feed

  • Question

  • I am able to instantiate an object using a default constructor with no problems. I am able to instantiate an object if I use a constructor with parameters and manually input the parameter data into the constructor as shown in both of my text books.    However, what I cannot figure out, and what neither book discusses, is how to instantiate an object using a constructor that has parameters whose input comes from user inputted data which has been returned from a method. 

    Just to make things clear, this is a lab for a college class I am taking.  I am not asking for anyone to do my code for me.  I am trying to understand the concept here so that I can implement it on this homework and all future homework.  I have literally tried six different ways that I can think of doing it, none of which have worked.   

    Here is the code for my main class, to include the different ways I've tried to instantiate the constructor:

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    
    namespace Exercise6_3
    {
        class ProgramApplication
        {
            static void Main(string[] args)
            {
                
                
                
                /*CalculateScores averageGradeObject = new CalculateScores(
                  averageGradeObject.AskForTestScores(),
                  averageGradeObject.AddInputValues(userInput),
                  averageGradeObject.NumberOfTestScoresInput(userInput),
                  averageGradeObject.AveTestScores(addTestScores, testCount));            
                
                /*CalculateScores averageGradeObject = new CalculateScores(
                  averageGradeObject.AskForTestScores(), 
                  averageGradeObject.AddInputValues(userInput),
                  averageGradeObject.NumberOfTestScoresInput(InputValues), 
                  averageGradeObject.AveTestScores(Sum, NumOfTestScores));
                
                
                CalculateScores averageGradeObject = new CalculateScores(
                  CalculateScores.AskForTestScores(), 
                  CalculateScores.AddInputValues(inputValues),
                  CalculateScores.NumberOfTestScoresInput(InputValues), 
                  CalculateScores.AveTestScores(Sum, NumOfTestScores));
                
                /*CalculateScores averageGradeObject = new CalculateScores(
                  AskForTestScores(), AddInputValues(InputValues),
                  NumberOfTestScoresInput(InputValues), AveTestScores(Sum, NumOfTestScores));
    
                CalculateScores averageGradeObject = new CalculateScores(
                  averageGradeObject.userInput, averageGradeObject.addTestScores,
                  averageGradeObject.testCount, averageGradeObject.aveScore);
    
                CalculateScores averageGradeObject = new CalculateScores(
                    CalculateScores.userInput, CalculateScores.addTestScores,
                    CalculateScores.testCount, CalculateScores.aveScore);
                
                CalculateScores averageGradeObject = new CalculateScores(userInput,
                      addTestScores, testCount, aveScore);*/
    

    Here is my second class which contains my constructor

    namespace Exercise6_3
    {
        class CalculateScores
        {
            private String inValue = "",
                           averageGrade = "";
            private int inputValues = 0,
                        sum = 0,
                        numOfTestScores = 0, 
                        averageTestScores = 0; 
          
            //property of the intValue datafield
            public int InputValues
            {
                get
                {
                    return inputValues;
                }
                set
                {
                    inputValues = value;
                }
            }
    
            //property of the sum datafield
            public int Sum
            {
                get
                {
                    return sum;
                }
                set
                {
                    sum = value;                
                }
            }
    
            //property of the numOfTestScores datafield
            public int NumOfTestScores
            {
                get
                {
                    return numOfTestScores;
                }
                set
                {
                    numOfTestScores = value;               
                }
            }
    
            //property of averageTestScores datafield
            public int AverageTestScores 
            {
                get
                {
                    return averageTestScores;
                }
                set
                {
                    averageTestScores = value;
                }
            }        
    
            //create default Constructor
            public CalculateScores()
            {
            }
    
            //constructor w/ four arguments
            public CalculateScores(int userInput, int addTestScores, int testCount,
                int aveScore)
            {
                inputValues = userInput;
                sum = addTestScores;
                numOfTestScores = testCount;
                averageTestScores = aveScore;
            }
    
            //display purpose of program
            public void ProgramIntroduction()
            {
                Console.WriteLine("This program will allow the input of multiple\n" +
                    "test scores between 0 and 100 and will calculate, then\n" +
                    "display the average score and letter grade");
                Console.WriteLine();
                Console.WriteLine();
            }
    
            //Ask user to input test scores 
            public int AskForTestScores()
            {
                Console.WriteLine("Enter value between 0 and 100 (-99 to exit)");
                inValue = Console.ReadLine(); //prime the ReadLine so -99 is not
                                              //included in return
    
                while (inValue != "-99") //Continue input until user inputs -99
                {                
                    int intValues = Convert.ToInt32(inValue);
                    inputValues = intValues;
                    //sum += intValue;
                    Console.WriteLine("Enter value between 0 and 100 (-99 to exit)");
                    inValue = Console.ReadLine();
                }            
                return inputValues;            
            }
    
            //add all of the input scores
            public int AddInputValues(int InputValues)
            {
                sum += InputValues;
                return sum;
            }
    
            //count the number of test scores input
            public int NumberOfTestScoresInput(int InputValues)
            {
                for (InputValues = 0; InputValues != -99; InputValues++)
                {
                    numOfTestScores = InputValues;
                   
                }
                return numOfTestScores;
            }
    
            // Find the average of the test scores 
            public int AveTestScores(int Sum, int NumOfTestScores)
            {
                averageTestScores = Sum / NumOfTestScores;
                return averageTestScores;
            }
    
            //display average grade
            public void AverageGrade(int AverageTestScores)
            {
                if (AverageTestScores > 89)
                    averageGrade = "A";
                //Console.WriteLine("Average Grade: " + averageGrade); 
                else if (AverageTestScores > 79)
                    averageGrade = "B";
                // Console.WriteLine("Average Grade: " + averageGrade);
                else if (AverageTestScores > 69)
                    averageGrade = "C";
                // Console.WriteLine("Average Grade: " + averageGrade);
                else if (AverageTestScores > 59)
                    averageGrade = "D";
                // Console.WriteLine("Average Grade: " + averageGrade);
                else
                    averageGrade = "F";
                // Console.WriteLine("Average Grade: " + averageGrade);
                Console.WriteLine(averageGrade);
            }
    
            //edit ToString() method
            public override String ToString()
            {
                return "Average Grade: " + averageGrade;
            }
        }
     }
    
                
                
                
               
                
                
               
    Thank you in advance for any help you could provide.

    Thursday, February 16, 2012 6:51 PM

Answers

  • Generally methods that access instance fields of the class should be instance methods, methods that doen't access instance fields should be static. 

    • Marked as answer by PullingMyHair Friday, February 17, 2012 12:38 AM
    Thursday, February 16, 2012 7:48 PM
  • So, when creating a class, should all methods except for the constructors, accessors, and mutators be static methods?  Also, would it be correct to say that even though a constructor is an instance method, its parameters have to come from static methods?

    I guess I'm having a hard time understanding when something needs to be a class method and when it needs to be an instance method. 

    No - In fact, I would personally have two classes here.

    There are a couple of issues in your question:

    1) Static vs. Instance methods -  

    When deciding between instance and static methods, you have to think about what the method does...  Not all methods should be static, nor (necessarily) instance methods.  In general, most methods tend to not be static, actually.

    If you have a method that is related to the class itself, and requires data stored in that class, it should be an instance method.  As an example, if you use the classic OOP example of animals, a "Speak()" method would be an instance method, since it works on a specific animal (and might work differently depending on the type of animal being created).  

    However, utilities typically don't work on a specific object or use the object itself.  For example, the Math class in the framework has a Sin method for calculating the sine of an angle - this isn't working on a "math object", and everything it requires to compute the value is passed in as a parameter (the angle), so it makes sense to use a static method here.

    2) Constructor parameters -

    The constructor parameters don't necessarily "come from static methods" - they just have to be a value that already exists.  You're passing a value here - it could be a constant (42) or the result computed by some other method in a different object, or anything else.  It just has to "exist" when you pass it.

    3) Your overall design - 

    In your case, you really are making a class that does two things.  The Single Responsibility Principle says that each class really should have one function - a single "responsibility".  In this case, that would suggest that you should probably split your functionality into 2 separate classes.  One class could be used for prompting the user for input, and the second for computing your test scores.

    In this case, the "prompting class" probably would have a set of static methods (to prompt for a specific type of data), but your score computing class would probably be all instance methods - since it's values or functions related to the data contained within the class itself.

    Does that help?

     



    Reed Copsey, Jr. - http://reedcopsey.com
    If a post answers your question, please click "Mark As Answer" on that post and "Mark as Helpful".

    • Marked as answer by PullingMyHair Friday, February 17, 2012 12:38 AM
    Thursday, February 16, 2012 7:55 PM
  • So, when creating a class, should all methods except for the constructors, accessors, and mutators be static methods?  Also, would it be correct to say that even though a constructor is an instance method, its parameters have to come from static methods?

    I guess I'm having a hard time understanding when something needs to be a class method and when it needs to be an instance method. 

    No, that's not really the case.  Sherif just gave you the smallest change that you would need to make to get your program to compile and work, but not quite what would likely be the best design.  Generally you should use static methods rather rarely, and only after determining that it is not possible or practical to use instance methods, rather than the other way around.

    I would propose that the constructor have no parameters and that you allow someone to make an instance of the object without populating any of the information.  Then I would alter the methods that you are currently using in the constructor so that rather than returning a value they would modify the instance fields of the class itself.  This would mean that you would create the object and then call the four methods immediately afterwards to populate that class with its data.  If it is imperative that the class not be able to exist without the data all being populted then you should put those for method calls inside of the constructor (which still takes no parameters) since it appears that you are always calling them in the same manor.  

    The constructor for an object is called after the object has been constructed, so you can access all of the instance fields/methods within it.  When you write the code as you have here it need to evaluate each of the methods into their integers so that it can pass those integers into the constructor, which means calling methods of a class that doesn't exist yet.

    • Marked as answer by PullingMyHair Friday, February 17, 2012 12:38 AM
    Thursday, February 16, 2012 8:03 PM

All replies

  • The line below is incorrect because you are trying to call a method for an object that hasn't been initialized.

    CalculateScores averageGradeObject = new CalculateScores(
                  averageGradeObject.AskForTestScores(),
                  averageGradeObject.AddInputValues(userInput),
                  averageGradeObject.NumberOfTestScoresInput(userInput),
                  averageGradeObject.AveTestScores(addTestScores, testCount)); 

    To fix this you should make your methods static methods for example:

    AskForTestScores should be defined as public static int AskForTestScores(). But since it uses the inValue field you also have to make the inValue field a local variable inside the method instead of a field because static method can't just work with instance fields without an object instance to work with.

    Thursday, February 16, 2012 7:05 PM
  • So, when creating a class, should all methods except for the constructors, accessors, and mutators be static methods?  Also, would it be correct to say that even though a constructor is an instance method, its parameters have to come from static methods?

    I guess I'm having a hard time understanding when something needs to be a class method and when it needs to be an instance method. 

    Thursday, February 16, 2012 7:41 PM
  • Generally methods that access instance fields of the class should be instance methods, methods that doen't access instance fields should be static. 

    • Marked as answer by PullingMyHair Friday, February 17, 2012 12:38 AM
    Thursday, February 16, 2012 7:48 PM
  • So, when creating a class, should all methods except for the constructors, accessors, and mutators be static methods?  Also, would it be correct to say that even though a constructor is an instance method, its parameters have to come from static methods?

    I guess I'm having a hard time understanding when something needs to be a class method and when it needs to be an instance method. 

    No - In fact, I would personally have two classes here.

    There are a couple of issues in your question:

    1) Static vs. Instance methods -  

    When deciding between instance and static methods, you have to think about what the method does...  Not all methods should be static, nor (necessarily) instance methods.  In general, most methods tend to not be static, actually.

    If you have a method that is related to the class itself, and requires data stored in that class, it should be an instance method.  As an example, if you use the classic OOP example of animals, a "Speak()" method would be an instance method, since it works on a specific animal (and might work differently depending on the type of animal being created).  

    However, utilities typically don't work on a specific object or use the object itself.  For example, the Math class in the framework has a Sin method for calculating the sine of an angle - this isn't working on a "math object", and everything it requires to compute the value is passed in as a parameter (the angle), so it makes sense to use a static method here.

    2) Constructor parameters -

    The constructor parameters don't necessarily "come from static methods" - they just have to be a value that already exists.  You're passing a value here - it could be a constant (42) or the result computed by some other method in a different object, or anything else.  It just has to "exist" when you pass it.

    3) Your overall design - 

    In your case, you really are making a class that does two things.  The Single Responsibility Principle says that each class really should have one function - a single "responsibility".  In this case, that would suggest that you should probably split your functionality into 2 separate classes.  One class could be used for prompting the user for input, and the second for computing your test scores.

    In this case, the "prompting class" probably would have a set of static methods (to prompt for a specific type of data), but your score computing class would probably be all instance methods - since it's values or functions related to the data contained within the class itself.

    Does that help?

     



    Reed Copsey, Jr. - http://reedcopsey.com
    If a post answers your question, please click "Mark As Answer" on that post and "Mark as Helpful".

    • Marked as answer by PullingMyHair Friday, February 17, 2012 12:38 AM
    Thursday, February 16, 2012 7:55 PM
  • So, when creating a class, should all methods except for the constructors, accessors, and mutators be static methods?  Also, would it be correct to say that even though a constructor is an instance method, its parameters have to come from static methods?

    I guess I'm having a hard time understanding when something needs to be a class method and when it needs to be an instance method. 

    No, that's not really the case.  Sherif just gave you the smallest change that you would need to make to get your program to compile and work, but not quite what would likely be the best design.  Generally you should use static methods rather rarely, and only after determining that it is not possible or practical to use instance methods, rather than the other way around.

    I would propose that the constructor have no parameters and that you allow someone to make an instance of the object without populating any of the information.  Then I would alter the methods that you are currently using in the constructor so that rather than returning a value they would modify the instance fields of the class itself.  This would mean that you would create the object and then call the four methods immediately afterwards to populate that class with its data.  If it is imperative that the class not be able to exist without the data all being populted then you should put those for method calls inside of the constructor (which still takes no parameters) since it appears that you are always calling them in the same manor.  

    The constructor for an object is called after the object has been constructed, so you can access all of the instance fields/methods within it.  When you write the code as you have here it need to evaluate each of the methods into their integers so that it can pass those integers into the constructor, which means calling methods of a class that doesn't exist yet.

    • Marked as answer by PullingMyHair Friday, February 17, 2012 12:38 AM
    Thursday, February 16, 2012 8:03 PM