2008-12-22 2 views
1

Редактировать снова: Я думаю, что я понял. Все, что мне нужно сделать, это использовать текущий класс двоеточия класса, который я хочу получить? Лицо: Студент или лицо: преподаватель Верно ли это?Использование объектов через методы

В настоящее время я пытаюсь изучить все аспекты объектно-ориентированного программирования. В настоящее время у меня есть новый объект, который что-то вроде следующего:

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:

То, что я хотел бы сделать, это изменить информацию из другого класса. Тем не менее, я хотел бы изменить информацию от ученика Джима методом из класса программы. Метод вычисления средних баллов для студентов, которые имеют данного учителя.

Кроме того, единственная причина, по которой я использую static в них, заключается в том, что это единственный способ получить доступ к переменным через методы. Я попытался использовать статические методы для использования методов в классах без успеха. Есть ли другой способ сделать это?

Я хотел бы использовать ученика Джима несколькими способами. Один, который определит класс Джима, и другой, который установит учителя. В этом случае я хотел бы использовать разные методы, чтобы я мог узнать, как это делается.

Хорошо, похоже, что мое понимание было неправильным. Я собираюсь попробовать методы в рамках подхода класса.

+0

Синтаксис Студент: Лицо означает, что класс Student наследуется от класса Person. См. Http://www.csharp-station.com/Tutorials/Lesson08.aspx для получения дополнительной информации –

ответ

1

Вы все еще отсутствующий существенный момент: класс Ассоциирует данных с его методами. Итак, метод, который устанавливает учитель Джима, является частью класса Студента, как и метод, который устанавливает класс Джима.

Подумайте об этом на естественном языке. «Джим - студент, у студентов есть имена, идентификационные номера и классы. В классах есть учителя и классные комнаты. Студенты получают оценки для каждого класса в конце срока».

Итак, у нас есть класс Студент. Студент, когда вы создаете объект из него, нуждается в имени ученика и идентификатора студента, поэтому «конструктор» должен быть чем-то с строкой имени и идентификатором ученика - также называем его строкой - для его инициализации. Я не знаю, C#, так что я буду делать pseudocde с брекетами ...

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's list 
     this.crsList.append(c); // Adds c to end of crsList 
    } 
} 

Это говорит: «Студент имеет имя и ID, и мы можем добавить классы в свою коллекцию классов."

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

Но мы видим, что преподаватели и студенты оба типа людей, так что мы„рефакторинг“это поставить общий кусок вместе

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

Теперь мы изменим Учитель и ученик поэтому мы говорим

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

, который теперь говорит, «Студент является таким человеком, который имеет дополнительный идентификатор студента, и которые мы можем добавить классы.»

Вы бы определили «addClass» для Teach, , но как часть класса учителя. Зачем? Поскольку добавление класса для учителя означает нечто иное, чем добавление одного для ученика. Вы бы добавили метод к Студенту, который принимает курс и класс, находит курс и назначает его класс каким-то образом. (Популярная викторина: является частью класса курса или частью студента?)

+0

Это невероятно ясно, все еще немного грубо по краям для меня, но теперь я получаю предельно базовую концепцию. Что касается поп-викторины, я бы предположил, что это будет часть студента, поскольку студент получит оценки для курса. курсы имеют оценки учащегося, правильно? – Xesaniel

+0

Yup. Нам понадобятся больше случаев использования, чтобы точно знать, как (у нас есть требование, чтобы увидеть, например, какой средний класс будет в сеансе курса), но моя первая мысль заключается в том, что между учеником будет ассоциация и экземпляр курса; ... –

+0

... и у вас будет метод assignGrade, который устанавливает класс для ученика против курса. (Если у вас есть требование о табуляции против курсов, вы должны использовать эту ассоциацию, чтобы найти ее у Студента.) –

3

Ну, по крайней мере, три способа.

  1. Сделать классы и методы учителя класса 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(); 
    } 
} 

или 2. Пропустите студентов к методам:


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

или 3 Используйте Jim как переменную в классе Program, так что вы на самом деле не должен передать его к чему-либо


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

Обратите внимание, что во всех примерах, которые я сделал класс Student имеет прописную S в его названии, чтобы отличить его от параметра и любого местного переменные, которые у вас могут быть.

Важно знать различия.

В первом решении вы сами задаете объект, чтобы задать оценки и учитель. Если это операции, которые вы делаете много, они, вероятно, принадлежат к самому классу, а не к внешним операциям.

Во втором решении вы проходите мимо ученика. Это позволяет вам легко работать с несколькими учениками, поскольку код не предназначен для работы с одним объектом.

В третьем решении вам не нужно ничего пропускать, но ваш код теперь заблокирован только для работы с одним учеником за раз в поле Jim.

Лично я бы разработал вариант первого решения, только немного более гибкий с точки зрения того, какой класс он будет устанавливать, и какой учитель. (., Которые вы также должны выглядеть более в) Вероятно, используя свойства

5

Поскольку вы используете C#, и предполагая, что вы используете .NET 3.5, ваш класс, вероятно, будет искать что-то вроде этого:

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

Grade and Teacher - это автоматические свойства, которые примерно эквивалентны геттерам и сеттерам на Java, которые будут методами. Свойства в C# являются, по существу, ярлыками для получения и установки локальных членов класса.

Ваше использование указанного класса будет выглядеть примерно так:

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 
} 

это то, что вы ищете?

+0

Не совсем. Я хотел бы изменить информацию из другого класса. Тем не менее, я хотел бы изменить информацию от ученика Джима методом из класса программы. Метод вычисления средних баллов для студентов, которые имеют данного учителя. – Xesaniel

+0

Вы можете изменить информацию, класс и учитель, используя свойства так же, как и переменные. s.Grade = 50 ;, s.Teacher = «Jane Doe»; –

0

Хорошо, здесь есть основное недоразумение. Ваши методы связаны с классом. У вас есть в основном структуры с некоторыми функциями, которые их используют; не ошибаюсь, но не OO вообще.

То, что вы действительно хотите что-то вроде этого (в, надеюсь, хорошим экспозиционным псевдокоде):

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 

Дело в том, что класс знает все, что нужно знать о вещах он описывает: как данные, которые он использует и операции, которые могут быть выполнены.

+0

Вопрос задавался с использованием примеров C#, учитывая, что уровень начинающего вопроса в отношении .net с использованием синтаксиса VB будет путать и не поможет. – trampster

+0

@ Даниэль: это псевдокод, а Чарли правильный –

+0

Я уже некоторое время работаю над этим, пытаясь обернуть вокруг себя голову. Может ли кто-нибудь объяснить это немного? Мне, наверное, нужен только небольшой толчок, чтобы заставить меня идти. – Xesaniel

1

lassevk делает хорошую работу , отвечая Ваш вопрос - в основном, как вы получаете доступ к экземпляру ученика по имени Джим через несколько методов.

Я хотел бы указать, однако, что вы здесь делаете процедурный код. Не то, чтобы в этом было что-то не так, просто потому, что вы на самом деле не «получаете» OO здесь.

Быстро, 2 минуты пример ОО-иш образом:

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

Там много церемонии и шума там, но важный бит является то, что учитель и, конечно, знают, как рассчитать свои средние ранги и проверить/обеспечить соблюдение собственного внутреннего состояния. Основной метод действительно отвечает только за координацию настройки и любых взаимодействий между классами.

Технически, многие отношения здесь двунаправленные - например, у учителя много курсов, а курс имеет одного учителя. Но двунаправленные отношения могут быть PITA для управления - и нет никаких веских причин для этого здесь.

0

Ваша модель упрощена и не определена.Но давайте игнорировать, что на данный момент ;-)

в примерах ниже я также игнорировании детали свойств и гася конструкторов, чтобы не путать главный вопрос моделирования

студентов и преподавателей являются оба человека (Чарли Мартин и другие отметили)

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

Студент является человек, и имеет класс и учитель

//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's collection 
    } 
    public int Grade; 
    public Teacher Teacher; 
} 

Учителя являются р eople, с курсом среднего класса и набором учеников.

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

В вашем примере у вас есть несколько студентов и вычислить средний балл

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

В более реалистичной модели, каждый студент, вероятно, будет принимать более чем один курс, и каждый учитель, вероятно, будет учить более одного курса, поэтому вам нужно будет моделировать Курсы. Курсы существуют только на протяжении семестра или квартала и т. Д.

0

Попробуйте подумать о классе как о синей печати для изготовления машины. Объект - это машина. Когда вы используете его, вам все равно, как он работает внутри. Вы просто используете различные рычаги и переключатели снаружи, чтобы управлять им, и светодиоды, которые сообщают вам ответы, и так далее. Это «черный ящик» для вас.

Рычаги и переключатели - это методы и свойства. Они выставляют «пользовательский интерфейс» для взаимодействия с объектом.

Код внутри методов является внутренним. Как это работает: секрет. Это делает объект более простым в использовании (если он хорошо разработан). Поля, которые в конечном счете хранят информацию, также являются секретами. Они не получают прямого доступа по коду вне методов класса.

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

Если вы придерживаетесь этого подхода, вы находитесь на пути к объектной ориентации. У вас еще есть много забавных вещей, чтобы узнать о - за исключением безопасности, злоупотребления наследования, слабой связи ...

Смежные вопросы