我有一个数组用作以下结构的输入:
> student_data = [
> {
> :first_name => "James",
> :last_name => "Smith",
> :date_of_birth => { :day => 5, :month => 10, :year => 1994 },
> :study_results => {
> :CAR => nil,
> :PR1 => 1,
> :MA1 => 1,
> :BEN => 2,
> :SDP => nil
> }
> }, ...]
我正在用代码创建Student类的实例:
student_data.each do |student|
UC::Student.new(student[:first_name], student[:last_name], student[:date_of_birth], student[:study_results])
end
该类如下:
require_relative("person.rb")
module UC
class Student < Person
include Comparable
@@students = []
def initialize(first_name, last_name, date_of_birth, study_results)
@date_of_birth = date_of_birth
@study_results = study_results
super(first_name, last_name)
@@students << self
end
def <=>(other)
return last_name_comparison = @last_name <=> other.last_name unless last_name_comparison == 0
return first_name_comparison = @first_name <=> other.first_name unless first_name_comparison == 0
return date_of_birth_comparison = @date_of_birth <=> other.date_of_birth
end
def list_study_results
return @study_results
end
end
end
现在,例如,如果我想使用方法list_study_results,如何从@@ students访问实例?
其他问题,在方法<=>中,我将调用了该方法的实例的实例变量(@last_name,...)与其他实例的实例变量进行比较。为什么我必须使用other.last_name而不是other。@ last_name?
答案 0 :(得分:2)
当您定义或访问以@
开头的变量时,您正在创建/访问实例变量。将实例变量视为学生的“一部分”。学生的名字,姓氏,出生日期等。
关于实例变量的规则之一是只能从实例的内部中访问它们。因此,如果您在特定学生内部的方法中,则只能从该学生读取实例变量。在OOP编程中,这通常称为封装-您可以控制有关公开学生的哪些信息,因此您无法从学生A的上下文访问有关学生B的信息。
您可以做的是定义一个公共界面,该界面可让您从“外部”访问有关学生的信息。您可以使用常规方法执行此操作:
def first_name
@first_name
end
或Ruby为您提供了执行相同操作的快捷方式:
attr_reader :first_name
对于它的价值,即使在一个类中,使用这些阅读器通常也是最佳实践。
您已经通过list_study_results
将学习结果定义为班级公共界面的一部分。因此,要让任何学生访问它,只需致电:
student.list_study_results
@@students.first.list_study_results
为了简化操作,通常将公用接口的名称与内部变量的名称相同,因此您可以考虑将list_study_results
重命名为study_results
。