Using objects through methods

Edit again: I seem to have figured it out now. All I have to do is use the current colon of the class I want to get? Person: Student or Person: Teacher Is that correct?

I am currently trying to learn all aspects of Object Oriented Programming. I currently have a new object that looks something like this:

class student
{
    int grade; //0 - 100 as opposed to the characters A, B, C, etc.
    string teacher; //For the teacher of the class the student is in.

}

class teacher
{ 
    int courseAverage;
    string name; 
    //teacher.name would correspond to the teacher in the student class.
}

class Program
{
    student Jim;
    Jim = new student();
    teacher John;
    John = new teacher();
}

static void grades()
{
    Jim.grade = 100;
}

static void teacher()
{
    Jim.teacher = "John Smith";
}

static void average()
{
    int average; //For the sake of simplicity I'll leave the average at an int.
    average = (Jim.grade + Sue.grade + Sally.grade + Robert.grade) / 4;
    /*A loop would be set before the average variable to 
    ensure that only students of John would be counted in this.*/

}

static void teacheraverage()
{
    John.courseAverage = average;//from the average method.
}

      

EDIT:

What I would like to do is change information from another class. However, I would like to change the information from student Jim using the method from the class of the program. A method for calculating average scores for students who have a given teacher.

Also, the only reason I use static in them is because they are the only way to access variables in different methods. I have tried using static methods to use methods in classes with no success. Is there any other way to do this?

I would like to use apprentice Jim in several ways. One to install Jim's class and another to install a teacher. In this case, I would like to use different methods so that I can learn how it is done.

Ok, it looks like my understanding was wrong. I'm going to try the methods within a class approach.

+1


source to share


7 replies


You are still missing the main point: the class binds data using its methods. So the method that Jim's teacher sets is part of the Student class, as well as the method that sets Jim's class.

Think about it in natural language. "Jim is a student, students have names, ID numbers and grades. Classes have teachers and classrooms. Students receive grades for each class at the end of the term."

So, we have a Student class. A student, when you create an object from it, needs a student name and student ID, so the "constructor" must be something with a name string and student ID - also call it a string - to initialize it. I don't know C #, so I'll do pseudocode with curly braces ...

class Student {
    String name;
    String studentID;
    Course crsList = List<Course>; // "list of courses."
    Student(String name, String studentID ){
        // Make a new student, the "constructor"
        this.name = name;
        this.studentID = studentID;
    }
    addCourse(Course c){
        // Add a course to the student list
        this.crsList.append(c); // Adds c to end of crsList
    }
}

      

This says, "The student has a name and ID, and we can add classes to their class collection."

class Teacher {
    String name;
    Course crsList = List<Course>;
    Teacher(String name){
        this.name = name;
    }
    // ... more methods here.
}

      



But we observe that teachers and students are both kinds of people, so we "reorganize" this to bring the common part together.

class Person {
    String name;
    Person(String name){
        this.name = name;
    }
    // ... more methods
}

      

Now we are changing Teacher and Student, so we say

class Student : Person {
    String studentID;
    Student(String name, String studentID){
        // Now we need to initialize the Person part
        super(name);
        // and the special Student part
        this.studentID = studentID;
    }
}

      

which now says: "A student is a kind of Human who has an additional student ID and with whom we can add classes."

You would specify "addClass" for Teach, but as part of the "Teacher" class. What for? Because adding a class for a teacher means something different than adding one for a student. You would add a method to the Student that takes a course and a class, finds a course, and assigns it to a class in some way. (Popular survey: is it part of the class of the course or is it part of the student?)

+1


source


Since you are using C # and assume that you are using .NET 3.5, your class will probably look something like this:

public class Student
{
    public int Grade { get; set; }
    public string Teacher { get; set; }
}

      

Class and Teacher are automatic properties that are roughly equivalent to Java getters and setters that would be methods. Properties in C # are essentially shortcuts for getting and setting local members of a class.



Your use of the above class looks something like this:

public class Program
{
    // creates a new Student object with the properties Grade and Teacher set.
    Student s = new Student() { Grade = 100, Teacher = "John Smith" }

    Console.Write(s.Grade); // outputs 100
    Console.Write(s.Teacher); // outputs John Smith
}

      

Is this what you are looking for?

+5


source


Well, at least three ways.

  • Make classes and teacher methods of class Student:

public class Student
{
    int grade; //0 - 100 as opposed to the characters A, B, C, etc.
    string teacher; //For the teacher of the class the student is in.

    public void SetGrades()
    {
        grade = 100;
    }

    public void SetTeacher()
    {
        teacher = "John Smith";
    }
}

class Program
{
    public static void Main()
    {
        Student Jim;
        Jim = new Student();
        Jim.SetTeacher();
        Jim.SetGrades();
    }
}

      

or 2. Pass the methods on to the student:


class Program
{
    public static void Main()
    {
        Student Jim;
        Jim = new Student();
        grades(Jim);
        teacher(Jim);
    }

    static void grades(Student student)
    {
        student.grade = 100;
    }

    static void teacher(Student student)
    {
        student.teacher = "John Smith";
    }
}

      

or 3. Use Jim as a variable in the Program class so you don't actually need to pass it on to anything


class Program
{
    static Student Jim;

    public static void Main()
    {
        Jim = new Student();
        grades();
        teacher();
    }

    static void grades()
    {
        Jim.grade = 100;
    }

    static void teacher()
    {
        Jim.teacher = "John Smith";
    }
}

      


Note that in all of the examples I've made the Student class uppercase S to distinguish it from the parameter and any local variables you may have.

It's important to know the differences.

In the first solution, you assign the class assignment and teacher to the object itself. If these are operations that you do a lot, they probably belong to the class itself and not to operations outside.

In the second solution, you bypass the student. This allows you to easily work with multiple learners as the code is not designed to work with a single object.

In the third solution, you don't need to skip anything, but your code is now locked to only work with one student at a time in the Jim field.

Personally, I would develop a variant of the first solution, just a little more flexible in terms of which class it will install and which teacher. Probably using properties (which you should also look into.)

+3


source


lassevk does a great job of answering your question - basically how you access a Student instance named Jim through multiple methods.

I would like to point out, however, that you are doing procedural code here. It's not that there is nothing wrong with that - it's just that you don't actually "get" OO here.

A quick, 2 minute OO-ish example:

class Student {
   public string Name { get; private set; }

   public Student(string name) {
      if (string.IsNullOrEmpty(name)) throw new ArgumentException();
      this.Name = name;
   }
}

class Teacher {
   public string Name { get; private set; }

   public List<Course> Courses { get; private set; }

   public Grade GetAverageCourseGrade() {
       int totalCourseGrade;
       foreach (Course course in this.Courses) {
          totalCourseGrade += course.GetAverageGrade().Value;
       }
       return new Grade(totalCourseGrade / this.Courses.Count);
   }

   public Teacher(string name) {
       if (string.IsNullOrEmpty(name)) throw new ArgumentException();
       this.Name = name;
       this.Courses = new List<Course>();
   }
}

class Course {
   public string Name { get; private set; }

   public IEnumerable<Student, Grade> StudentGrades { get; private set; }

   public Grade GetAverageGrade() {
      int totalGrade;
      // could use LINQ, but I'll make it slightly more explicit
      foreach (KeyValuePair<Student, Grade> studentGrade in this.StudentGrades) {
         Grade grade = kvp.Value;
         totalGrade += grade.Value;
      }
      return new Grade(totalGrade / this.StudentGrades.Count());
   }

   public Course(string name) {
       if (string.IsNullOrEmpty(name)) throw new ArgumentException();
       this.Name = name;
       this.StudentGrades = new Dictionary<Student, Grade>();
   }
}

class Grade {
   public int Value { get; private set; }

   public char Letter { 
       get {
          switch (this.Value / 10) {
             case 10: case 9:
               return 'A';
             case 8:
               return 'B';
             case 7:
               return 'C';
             case 6:
               return 'D';
             default:
               return 'F';
          }
       }
   }

   public Grade(int value) {
      if (value < 0 || value > 100) throw new ArgumentOutOfRangeException();
      this.Value = value;
   }
}

class Program {
   static int Main(string[] args) {
      Teacher john = new Teacher("John Smith");

      Course cs101 = new Course("Computer Science 101");
      john.Courses.Add(cs101);

      Student mark = new Student("Mark Brackett");
      Student xesaniel = new Student("Xesaniel");

      cs101.Students.Add(mark, new Grade(90));
      cs101.Students.Add(xesaniel, new Grade(95));

      Console.WriteLine(john.GetAverageCourseGrade());
   }
}

      

There are many ceremonies and noises, but the important point is that the Teacher and the course know how to calculate their own average grades and validate / enforce their own inner state. The main method is really only responsible for coordinating the setup and any interactions between the classes.

Technically, many relationships here are bi-directional - for example, a teacher has many courses, but a course has one teacher. But bi-directional relationships can be a PITA for governance - and there's no compelling reason for it here.

+1


source


Okay, there is a major misunderstanding here. Your methods are associated with a class. You have basically structures with some functions that use them; not wrong, but not OO at all.

What you really want is something like this (in the hopes that this is a good pseudo-burn to describe):

class Person
  name : String
  Person(namearg: String) -- your constructor
    name = namearg;
  end
end

class Student :: Person -- read :: as "is a kind of"
  Student(namearg : String)
    super(namearg) -- calls the Person ctor
  end
  -- more stuff will go in here
end
-- Teacher looks much the same

class Course
  courseName : String
  teacher : Teacher
  students : list of Student
  Course(namearg : string)
    courseName = namearg 
  end
  addStudent(s : student)
    students.append(s) -- add student to the end of the list
  end
  -- and so on.
end

      

The point is that the class knows everything there is to know about what it describes: both the data it uses and the operations that can be performed.

0


source


Your model is oversimplified and undefined. But let's ignore that for the moment; -)

in the examples below I also ignore property details and halt constructors so as not to confuse the main modeling problem

Student and Teacher are people (as noted by Charlie Martin and others)

//people have names
public class Person
{
    public Person(string _name)
    {
        Name = _name;
    }
    public string Name;
}

      

A student is a Human and has a class and a teacher.

//students are people with a grade and a teacher
public class Student : Person
{
    public Student(string _name, int _grade, 
        Teacher _teacher) : base(_name)
    {
        Grade = _grade;
        Teacher = _teacher;
        Teacher.Students.Add(this);  //add to the teacher collection
    }
    public int Grade;
    public Teacher Teacher;
}

      

Teachers are people with an average course and enrollment.

public class Teacher : Person
{
    public Teacher(string _name) : base(_name)
    {
    }
    public int CourseAverage;
    public IList<Student> Students = new List<Student>();
    public void ComputeAverageGrade()
    {
        int sum = 0;
        foreach(Student s in Students)
        {
            sum += s.Grade;
        }
        CourseAverage = sum / Students.Count;
    }
}

      

In your example, you have multiple students and calculate the average grade

public class Program
{
    public static void Main(string [] args)
    {
        Teacher JohnSmith = new Teacher("John Smith");

        Student Jim = new Student("Jim",100,JohnSmith);
        Student Sue = new Student("Sue",90,JohnSmith);
        Student Sally = new Student("Sally",70,JohnSmith);
        Student Robert = new Student("Robert",100,JohnSmith);

        //add our resident overachiever
        Student JonSkeet = new Student("Jon Skeet",150,JohnSmith);

        JohnSmith.ComputeAverageGrade();

        Console.WriteLine("Course Average for " + JohnSmith.Name + " is " +
            JohnSmith.CourseAverage.ToString());
    }
}

      

In a more realistic model, each student will likely be taking more than one course, and each teacher will likely teach more than one course, so you will need to model the courses. Courses only exist for a semester or a quarter, etc.

0


source


Try to think of the classroom as a blue printer for building a car. The object is a machine. When you use it, you don't care how it works internally. You just use various levers and switches on the outside to control it, and LEDs that tell you the answers, and so on. This is a black box for you.

Levers and switches are methods and properties. They expose a "user interface" for interacting with an object.

The code inside the methods is internal. How it works is a secret. This makes the object easier to use (if well designed). The fields that ultimately hold information are also secrets. They are not directly accessed by code outside of the class methods.

public class Student
{
    // Notice how these details are private
    private List<Subjects> _subjects = new List<Subjects>();
    private DateTime _started;

    // A property that only has a 'getter' because the value shouldn't be modified
    public DateTime Started
    {
        get { return _started; }
    }

    // Methods carry out actions. This one calls on to a method in another object.
    public void Enroll(Subject s)
    {
        if (_subjects.Contains(s))
            throw new Exception("Already studying that course");

        s.RegisterStudent(this);
        _subjects.Add(s); 
    }

    public void Flunk(Subject s)
    {
        if (!_subjects.Contains(s))
            throw new Exception("Can't flunk that subject, not studying it");

        s.RemoveStudent(this);
        _subjects.Remove(s);
    }
}

      

If you follow this approach, you are well on your way to object orientation. You still have a lot of interesting things to learn about - exception safety, inheritance abuse, loose coupling ...

0


source







All Articles