2012-03-02 3 views
1

Я хочу, чтобы иметь возможность инициализировать новый объект Car и передать ему объект Person в параметрах, чтобы его можно было сохранить в массиве @cars этого Person. В настоящее время, я беру этот подход:Как связать экземпляры из разных классов в Ruby

person = Person.new("Michael") 
car = Car.new("Honda", "Accord") 
person.add_car(car) 
person.add_car(Car.new("Ford", "Taurus")) 
person.add_car(Car.new("Toyota", "Prius")) 
person.display 

Однако, я хотел бы быть в состоянии создать новый экземпляр автомобиля и передать ему объект Person Я хочу это связанно с. Например:

person = Person.new("Michael") 
Car.new("Honda", "Accord", person) 
Car.new("Toyota", "Camry", person) 
Car.new("Chevy", "Tahoe", person) 
person.display 

Возможно ли это?

class Person 

    attr_accessor :name 

    def initialize(name) 
    super 
    @name = name 
    @cars = [] 
    end 

    def display 
    puts "#{@name} has #{@cars.length} cars" 
    puts "----------------------------" 
    @cars.each do |car| 
     puts "#{car.make} #{car.model}" 
    end 
    end 

    def add_car(car) 
    @cars.push(car) 
    end 

end 

class Car 

    attr_accessor :make, :model 

    def initialize(make, model) 
    @model = model 
    @make = make 
    end 

    def display 
    puts "#{@make} #{@model}" 
    end 

end 

ответ

2

Да, это возможно, Car#initialize может вызывать методы на своих аргументов:

+0

Именно то, что я искал. Благодаря! – Abundnce10

1

Это будет моя реализация:

class Car 
    attr_accessor :make, :model 

    def initialize(make, model) 
    self.make = make 
    self.model= model 
    end 
end 

класс Person

class Person 
    attr_accessor :name, :cars 

    def initialize(name, cars=[]) 
    self.name = name 
    self.cars = cars || [] 
    end 

    def add_car(*args) 
    raise ArgumentError, 'invalid arguments' if (
     (args.size > 2 or args.size == 0) or 
     (args.size == 1 and !args[0].is_a?(Car)) 
    ) 
    new_car = (args.size == 2) ? Car.new(*args) : args[0] 
    self.cars << new_car 
    new_car 
    end 

end 

Теперь вы можете:

person = Person.new("Michael") 
car = Car.new("Honda", "Accord") 
person.add_car(car) 
person.add_car("Ford", "Taurus") 
person.add_car("Toyota", "Prius") 
person.display 

Метод add_car создает новый автомобиль, когда марка и модель передаются в качестве параметров.

0

Да, возможно, как ответ mu is too short, но на мой взгляд это не имеет смысла. Ваши автомобили не могут использоваться в любом контексте без Person, и указанный параметр не вносит никаких данных, необходимых для создания объекта Car.

Я хотел бы разработать такой API следующим образом:

class Person 
    def initialize(name) 
    @name = name 
    end 

    def cars 
    @cars ||= Array.new # Equivalent to @cars || @cars = [] 
    end 
end 

person = Person.new 'Michael' 

taurus = Car.new 'Ford', 'Taurus' 
prius = Car.new 'Toyota', 'Prius' 

person.cars << taurus << prius << Car.new('Honda', 'Accord') 

Это более простой и прямой формой реализации KandadaBoggu о том, что имеет преимущество метода Array#<< для того, чтобы естественным образом связать Car с с Person , а также удваивается как читатель атрибутов.

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