2013-04-24 3 views
0

Я пошел в this page, чтобы узнать о классах Ruby. Код на этой странице, заключается в следующем:Рубиновые определяющие переменные класса

class Customer 
    @@no_of_customers=0 
    def initialize(id, name, addr) 
     @cust_id=id 
     @cust_name=name 
     @cust_addr=addr 
    end 
    def display_details() 
     puts "Customer id #@cust_id" 
     puts "Customer name #@cust_name" 
     puts "Customer address #@cust_addr" 
    end 
    def total_no_of_customers() 
     @@no_of_customers += 1 
     puts "Total number of customers: #@@no_of_customers" 
    end 
end 

Я понимаю @@ означает переменную класса, но я не понимаю, как вы можете создать переменную в initialize метода (конструктор) и использовать его внутри другого метода, как будто это переменная класса. Как это возможно? В чем смысл определения переменных класса, если вы можете просто определить его в конструкторе?

+1

где он определял переменную класса в конструкторе? – yngccc

+0

@yngum '@ cust_id = id'. Я предполагаю, что это не определение переменной класса, но мой вопрос в большей степени заключается в том, как вы можете определить переменную в функции и использовать ее вне этой функции. – Richard

+1

'@ cust_id' - это переменная экземпляра, вы, очевидно, можете использовать переменную экземпляра в любом методе экземпляра. – yngccc

ответ

4

Если я правильно понимаю ваш вопрос (просьба прокомментировать, если нет), вы спрашиваете, почему мы обычно не определяем переменные класса в конструкторах.

В приведенном выше примере кода переменная класса @@no_of_customers не определена в конструкторе, поскольку она предназначена для доступа ко всем членам этого класса и отслеживает количество клиентов. Так, если наш конструктор выглядит следующим образом:

def initialize(id, name, addr) 
    @@no_of_customers=0 
    @cust_id=id 
    @cust_name=name 
    @cust_addr=addr 
end 

мы будем перезаписывать эту переменную с 0 каждый раз, когда кто-то определяет новый экземпляр этого класса. Более подходящее определение класса будет выглядеть следующим образом:

class Customer 
    @@no_of_customers=0 
    def initialize(id, name, addr) 
    @@no_of_customers += 1 
    @cust_id=id 
    @cust_name=name 
    @cust_addr=addr 
    end 
    ... 
end 

Таким образом, переменная класса @@no_of_customers инициализируется в ноль перед мы создаем какие-либо объекты. Затем каждый раз, когда мы создаем новый объект, мы увеличиваем его.

Конечно, причины можно было бы использовать переменный класс для этого примера:

  • Это имеет смысл инкапсулировать количество клиентов с клиентами, а не использовать некоторые глобальные

  • Потому что он привязан к классу клиентов, внешний мир не может его изменить и сделать его означающим нечто иное, чем оно должно означать, или сделать что-то неожиданное с ним.

Это все, что сказать, это похоже на правило «не играй с незнакомцами».

@ против @@

Когда @ используется в качестве префикса в рубина, оно обозначает, что переменная является переменной экземпляра.

Когда используется @@, это означает, что это переменная класса.

Вот хорошая статья на difference between these, если вы не знаете.

+0

Одна вещь, которую я не получаю, в C++ при создании объекта класса, у этого объекта есть свои собственные значения переменных набора. Поэтому, если вы ошибаетесь в функции, которую вы написали, независимо от того, сколько объектов класса клиента вы создали, значение каждого объекта «no_of_customer» будет 1. То, что вы предлагаете, противоречит всем концепциям ООП, которые я знаю из C++. Мог бы объяснить немного больше? – Richard

3

Я думаю, вы смешиваете переменные класса (@@) и экземпляра (@). В Ruby переменная класса больше похожа на статическую переменную класса в C++, и переменные экземпляра, как переменные regual класса в C++:

class Test 
    @@cvar = 1 
    def initialize 
     @ivar = 0 
    end 
end 

более или менее эквивалентно (извините, мой C++ ржавый):

class Test { 
    public: 
     Test() : ivar(0) {} 
    private: 
     static int cvar; 
     int ivar; 
}; 
int Test::cvar = 1; 
Смежные вопросы