私は今やってくる試験の練習としていくつかのことをやっていますが、頭を悩ませることができないことの1つは、あるクラスに属する変数を別のクラスで使用することです。
コースクラスと学生クラスがあります。クラスコースにはさまざまなコースがすべて保存されています。私がやりたいのは、クラスStudentでコースの名前を使用することです。
これが私のコースクラスです:
public class Course extends Student
{
// instance variables - replace the example below with your own
private Award courseAward;
private String courseCode;
public String courseTitle;
private String courseLeader;
private int courseDuration;
private boolean courseSandwich;
/**
* Constructor for objects of class Course
*/
public Course(String code, String title, Award award, String leader, int duration, boolean sandwich)
{
courseCode = code;
courseTitle = title;
courseAward = award;
courseLeader = leader;
courseDuration = duration;
courseSandwich = sandwich;
}
}
そしてここに学生がいます:
public class Student
{
// instance variables - replace the example below with your own
private int studentNumber;
private String studentName;
private int studentPhone;
private String studentCourse;
/**
* Constructor for objects of class Student
*/
public Student(int number, String name, int phone)
{
studentNumber = number;
studentName = name;
studentPhone = phone;
studentCourse = courseTitle;
}
}
コース内で「extends」を使用するのは正しいですか?それともこれは不要ですか?
Studentのコンストラクターで、Courseクラスの「courseTitle」を変数「studentCourse」に割り当てようとしています。しかし、私はこれを行う方法を単純に理解できません!
よろしくお願いします。ご連絡をお待ちしております。
ありがとう!
コース内で「extends」を使用するのは正しいですか?それともこれは不要ですか?
残念ながら、継承が正しいかどうかを知りたい場合は、extendsをis-aに置き換えてください。コースは学生ですか?答えはノーです。つまり、Course
はStudent
を拡張してはなりません
学生はCourse
に参加できるため、Student
クラスはタイプCourse
のメンバー変数を持つことができます。モデルで指定されている場合は、コースのリストを定義できます(学生は複数のコースに参加できます)。
サンプルコードは次のとおりです。
public class Student{
//....
private Course course;
//...
public void attendCourse(Course course){
this.course = course;
}
public Course getCourse(){
return course;
}
}
今、あなたは以下を持つことができます:
Student bob = new Student(...);
Course course = new Course(...);
bob.attendCourse(course);
私はコースを想定していますそうではありません学生なので、これらのクラス間の継承はおそらく悪い考えです。
それらを公開する必要があります。
より良い方法は、それらをプライベートに保ち、その変数のパブリックゲッターをコーディングすることです。例えば:
public Award getCourseAward(){
return this.courseAward;
}
拡張Student
とCouse
は同じ種類ではないため、あるクラスを別のクラスに拡張することは、より一般的な(ある意味で)クラスを専門化するときに起こります。
解決策は、courseTitle
コンストラクターの引数としてStudent
を渡すことです。
ここには、コース、学生、および登録の3つの個別のオブジェクトが必要です。登録は学生をコースに接続し、コースには多くの学生がいて、学生は多くのコースに登録できます。それらのどれもお互いを拡張するべきではありません。
たぶん、学生にコース名を追加する必要はありません。私がすることは、コースのいくつかのデータ構造に学生を追加することです。これはよりクリーンで、コースと学生の間の結合を減らします。これにより、学生を複数のコースに参加させることもできます。例えば:
public class Course extends Student{
private Award courseAward;
private String courseCode;
public String courseTitle;
private Student courseLeader;//change to a student Object
private int courseDuration;
private boolean courseSandwich;
private Set<Student> students;//have course hold a collection of students
/**
* Constructor for objects of class Course
*/
public Course(String code, String title, Award award, Student leader, int duration, boolean sandwich){
courseCode = code;
courseTitle = title;
courseAward = award;
courseLeader = leader;
courseDuration = duration;
courseSandwich = sandwich;
this.students=new HashSet<Student>();
}
public boolean addStudent(Student student){
return students.add(student);
}
public Set<Student> getStudents(){
return students;
}
}
最初、
コースクラスでStudentクラスを拡張します。つまり、Studentクラスはすべてのcoruseクラスプロパティを取得します。したがって、学生クラスにはcourseTitleプロパティがありません。
第二に、はい、それは不要です-あなたは以下をする必要があります:
public class Course
{
private Award courseAward;
private String courseCode;
public String courseTitle;
private String courseLeader;
private int courseDuration;
private boolean courseSandwich;
public Course(String code, String title, Award award, String leader, int duration, boolean sandwich)
{
courseCode = code;
courseTitle = title;
courseAward = award;
courseLeader = leader;
courseDuration = duration;
courseSandwich = sandwich;
}
}
public class Student
{
private int studentNumber;
private String studentName;
private int studentPhone;
// This is where you keep the course object associated to student
public Course studentCourse;
public Student(int number, String name, int phone, Course course)
{
studentNumber = number;
studentName = name;
studentPhone = phone;
studentCourse = course;
}
}
使用例は次のようになります。
Course course = new Course("ASD", "TITLE", null, "ME", 50, true);
Student student = new Student(1, "JOHN", "5551234", course);
次に、必要なコース情報を学生から次のように取得します。
student.studentCourse.courseTitle;
これ以降、student.studentCourseは、すべてのプロパティを備えたコースオブジェクトになります。
乾杯、
Course
はStudent
を拡張しないでください。 courseTitle
のCourse
フィールドにアクセスする場合は、Course
オブジェクトへの参照をStudent
に渡してから、course.CourseTitleを実行する必要があります。 。
クラスのプライベート属性に別のクラスからアクセスすることはできません。これは、OOPの主要な原則の1つであるカプセル化です。これらの属性へのアクセスメソッドを提供する必要があります。クラスの外部に公開する必要があります。一般的なアプローチは、setter/gettersです。クラスを不変にしたい場合は、getterのみです。ここを見てください: http://en.wikipedia.org/wiki/Mutator_method#Java_example
クラスを任意に拡張することは意味がありません。学生はコースではないか、またはその逆であるため、そのように延長することはできません。
あなたがする必要があるのは:
最初にコースを作成します。
Course aCourse = new Course(..);
学生を作成する:
Student aStudent = new Student(..);
コースを学生に割り当てます。
aStudent.setCourse(aCourse.title);
以下に問題の解決策を見つけます。マシンで以下のコードを確認する場合は、Test.Javaという名前のファイルを作成し、以下のコードを貼り付けます。
パッケージcom;
class Course
{
private Award courseAward;
private String courseCode;
public String courseTitle;
private String courseLeader;
private int courseDuration;
private boolean courseSandwich;
public Course(String code, String title, Award award, String leader, int duration, boolean sandwich)
{
courseAward = award;
courseCode = code;
courseTitle = title;
courseLeader = leader;
courseDuration = duration;
courseSandwich = sandwich;
}
public Award getCourseAward() {
return courseAward;
}
public void setCourseAward(Award courseAward) {
this.courseAward = courseAward;
}
public String getCourseCode() {
return courseCode;
}
public void setCourseCode(String courseCode) {
this.courseCode = courseCode;
}
public String getCourseTitle() {
return courseTitle;
}
public void setCourseTitle(String courseTitle) {
this.courseTitle = courseTitle;
}
public String getCourseLeader() {
return courseLeader;
}
public void setCourseLeader(String courseLeader) {
this.courseLeader = courseLeader;
}
public int getCourseDuration() {
return courseDuration;
}
public void setCourseDuration(int courseDuration) {
this.courseDuration = courseDuration;
}
public boolean isCourseSandwich() {
return courseSandwich;
}
public void setCourseSandwich(boolean courseSandwich) {
this.courseSandwich = courseSandwich;
}
}
class Student
{
private int studentNumber;
private String studentName;
private int studentPhone;
private Course studentCourse;
/**
* Constructor for objects of class Student
*/
public Student(int number, String name, int phone, Course course)
{
studentNumber = number;
studentName = name;
studentPhone = phone;
studentCourse = course;
}
public int getStudentNumber() {
return studentNumber;
}
public void setStudentNumber(int studentNumber) {
this.studentNumber = studentNumber;
}
public String getStudentName() {
return studentName;
}
public void setStudentName(String studentName) {
this.studentName = studentName;
}
public int getStudentPhone() {
return studentPhone;
}
public void setStudentPhone(int studentPhone) {
this.studentPhone = studentPhone;
}
public Course getStudentCourse() {
return studentCourse;
}
public void setStudentCourse(Course studentCourse) {
this.studentCourse = studentCourse;
}
}
class Award{
private long awardId;
private String awardName;
Award(long awardId, String awardName){
this.awardId = awardId;
this.awardName = awardName;
}
public long getAwardId() {
return awardId;
}
public void setAwardId(long awardId) {
this.awardId = awardId;
}
public String getAwardName() {
return awardName;
}
public void setAwardName(String awardName) {
this.awardName = awardName;
}
}
public class Test{
public static void main(String ar[]){
// use your all classes here
}
}
前述のように、このための「拡張」には近づかないでください。一般に、「is-a」の関係が意味をなさない限り、これを使用しないでください。
おそらく、Courseクラスのメソッドにゲッターを提供する必要があります。
public class Course {
...
public String getTitle() {
return title;
}
}
そして、Studentクラスがそれを必要とする場合、それはどういうわけかコースを手に入れ(あなたのデザインではあなた次第です)、ゲッターを呼び出します:
public class Student {
private Set<Course> courses = new HashSet<Course>();
public void attendCourse(Course course) {
courses.add(course);
}
public void printCourses(PrintStream stream) {
for (Course course : courses) {
stream.println(course.getTitle());
}
}
}