수색…


통사론

  • 클래스 이름
  • 클래스 행동을 설명하는 # 코드
  • 종료

비고

Ruby의 클래스 이름은 상수이므로 첫 글자는 대문자 여야합니다.

class Cat # correct
end  

class dog # wrong, throws an error
end

수업 만들기

class 키워드를 사용하여 새 클래스를 정의 할 수 있습니다.

class MyClass
end

일단 정의되면 .new 메소드를 사용하여 새 인스턴스를 만들 수 있습니다.

somevar = MyClass.new
# => #<MyClass:0x007fe2b8aa4a18>

건설자

클래스는 하나의 생성자 만 가질 수 있습니다. 즉 initialize 라는 메서드입니다. 메소드는 클래스의 새 인스턴스가 생성 될 때 자동으로 호출됩니다.

class Customer
  def initialize(name)
     @name = name.capitalize 
  end
end

sarah = Customer.new('sarah')
sarah.name #=> 'Sarah'

클래스 및 인스턴스 변수

클래스가 데이터를보다 쉽게 ​​공유하기 위해 사용할 수있는 몇 가지 특수 변수 유형이 있습니다.

인스턴스 변수 앞에는 @ 붙습니다. 다른 메소드에서 동일한 변수를 사용하려는 경우 유용합니다.

class Person
  def initialize(name, age)
    my_age = age # local variable, will be destroyed at end of constructor
    @name = name # instance variable, is only destroyed when the object is
  end

  def some_method
    puts "My name is #{@name}." # we can use @name with no problem
  end
   
  def another_method
    puts "My age is #{my_age}." # this will not work!
  end
end

mhmd = Person.new("Mark", 23)

mhmd.some_method #=> My name is Mark.
mhmd.another_method #=> throws an error

클래스 변수 앞에 @@ . 클래스의 모든 인스턴스에서 동일한 값을 포함합니다.

class Person
  @@persons_created = 0 # class variable, available to all objects of this class
  def initialize(name)
    @name = name

    # modification of class variable persists across all objects of this class
    @@persons_created += 1
  end  
      
  def how_many_persons
    puts "persons created so far: #{@@persons_created}"
  end 
end
    
mark = Person.new("Mark")
mark.how_many_persons #=> persons created so far: 1
helen = Person.new("Helen")

mark.how_many_persons #=> persons created so far: 2
helen.how_many_persons #=> persons created so far: 2
# you could either ask mark or helen

전역 변수 앞에는 $ 붙습니다. 이러한 프로그램은 프로그램의 어느 곳에서나 사용할 수 있으므로 현명하게 사용하십시오.

$total_animals = 0

class Cat
  def initialize
    $total_animals += 1
  end
end

class Dog
  def initialize
    $total_animals += 1
  end
end

bob = Cat.new()
puts $total_animals #=> 1
fred = Dog.new()
puts $total_animals #=> 2

getter 및 setter를 사용하여 인스턴스 변수에 액세스

세 가지 방법이 있습니다.

  1. attr_reader : 클래스 외부에서 변수를 read 수있게 해줍니다.
  2. attr_writer : 클래스 외부에서 변수를 수정하는 데 사용됩니다.
  3. attr_accessor : 두 메소드를 결합합니다.
class Cat
  attr_reader :age # you can read the age but you can never change it
  attr_writer :name # you can change name but you are not allowed to read
  attr_accessor :breed # you can both change the breed and read it

  def initialize(name, breed)
    @name = name
    @breed = breed
    @age = 2 
  end
  def speak
    puts "I'm #{@name} and I am a #{@breed} cat"
  end
end
 
my_cat = Cat.new("Banjo", "birman")
# reading values:

my_cat.age  #=> 2
my_cat.breed #=> "birman"
my_cat.name #=> Error

# changing values
 
my_cat.age = 3 #=> Error
my_cat.breed = "sphynx" 
my_cat.name = "Bilbo"

my_cat.speak #=> I'm Bilbo and I am a sphynx cat

매개 변수는 기호임을 유의하십시오. 이는 메소드를 작성하여 작동합니다.

class Cat
  attr_accessor :breed
end

기본적으로 다음과 같습니다 :

class Cat
  def breed
    @breed
  end
  def breed= value
    @breed = value
  end
end

액세스 수준

Ruby에는 세 가지 액세스 레벨이 있습니다. 그들은 public 적이고 private 이며 protected .

private 또는 protected 키워드를 따르는 메소드는 이와 같이 정의됩니다. 이들 앞에 오는 메소드는 암시 적으로 public 메소드입니다.

Public 메서드

public 메소드는 생성되는 객체의 동작을 설명해야합니다. 이 메소드는 작성된 오브젝트의 | 위 외부에서 호출 될 수 있습니다.

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

  def speak
    puts "I'm #{@name} and I'm 2 years old"
  end
  
  ...
end

new_cat = Cat.new("garfield")
#=> <Cat:0x2321868 @name="garfield">
 
new_cat.speak
#=> I'm garfield and I'm 2 years old

이 메소드는 공개 루비 메소드이며, 새 cat을 초기화하는 동작과 speak 메소드의 동작을 설명합니다.

public 키워드는 불필요하지만 private 또는 protected 를 이스케이프하는 데 사용할 수 있습니다.

def MyClass
  def first_public_method
  end

  private

  def private_method
  end

  public

  def second_public_method
  end
end

비공개 메소드

개인 메서드는 개체 외부에서 액세스 할 수 없습니다. 객체에 의해 내부적으로 사용됩니다. cat 예제를 다시 사용 :

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

  def speak
    age = calculate_cat_age # here we call the private method 
    puts "I'm #{@name} and I'm #{age} years old"
  end

  private
     def calculate_cat_age
       2 * 3 - 4 
     end
end

my_cat = Cat.new("Bilbo")
my_cat.speak #=> I'm Bilbo and I'm 2 years old
my_cat.calculate_cat_age #=> NoMethodError: private method `calculate_cat_age' called for #<Cat:0x2321868 @name="Bilbo">

위 예제에서 볼 수 있듯이 새로 생성 된 Cat 객체는 내부적으로 calculate_cat_age 메소드에 액세스 할 수 있습니다. cat의 이름과 나이를 콘솔에 출력하는 private calculate_cat_age 메소드를 실행 한 결과 변수 age 를 할당합니다.

my_cat 객체 외부에서 calculate_cat_age 메소드를 호출하려고하면 private이기 때문에 NoMethodError 수신합니다. 알 겠어?

보호 된 메서드

보호 된 메소드는 개인 메소드와 매우 유사합니다. 개인 메소드가 될 수없는 것과 같은 방법으로 객체의 인스턴스 외부에서 액세스 할 수 없습니다. 그러나 self ruby 메서드를 사용하면 보호 된 메서드를 같은 유형의 개체 컨텍스트 내에서 호출 할 수 있습니다.

class Cat
  def initialize(name, age)
    @name = name
    @age = age
  end

  def speak
    puts "I'm #{@name} and I'm #{@age} years old"
  end

  # this == method allows us to compare two objects own ages. 
  # if both Cat's have the same age they will be considered equal.
  def ==(other)
     self.own_age == other.own_age
  end

  protected
     def own_age
        self.age
     end
end

cat1 = Cat.new("ricky", 2)
=> #<Cat:0x007fe2b8aa4a18 @name="ricky", @age=2>

cat2 = Cat.new("lucy", 4)
=> #<Cat:0x008gfb7aa6v67 @name="lucy", @age=4>

cat3 = Cat.new("felix", 2)
=> #<Cat:0x009frbaa8V76 @name="felix", @age=2>

cat 클래스에 age 매개 변수를 추가하고 이름과 나이가있는 세 개의 새 cat 객체를 만들었습니다. 우리는 cat 객체의 연령을 비교하기 위해 own_age protected 메소드를 호출 할 것입니다.

cat1 == cat2
=> false

cat1 == cat3
=> true

cat1의 나이를 self.own_age protected 메소드를 사용하여 검색하고 cat2의 나이와 cat1의 cat2.own_age 를 호출하여 비교할 수 cat2.own_age .

클래스 메소드 유형

클래스에는 3 가지 유형의 메소드가 있습니다 : 인스턴스, 싱글 톤 및 클래스 메소드.

인스턴스 메소드

이것들은 클래스의 instance 에서 호출 할 수있는 메소드입니다.

class Thing
  def somemethod
    puts "something"
  end
end

foo = Thing.new # create an instance of the class
foo.somemethod # => something

클래스 메서드

이것은 정적 메소드입니다. 즉, 클래스에서 인스턴스화 될 수있는 것이 아니라 클래스에서 호출 될 수 있습니다.

class Thing
  def Thing.hello(name)
    puts "Hello, #{name}!"
  end
end

클래스 이름 대신에 self 를 사용하는 것과 같습니다. 다음 코드는 위의 코드와 동일합니다.

class Thing
  def self.hello(name)
    puts "Hello, #{name}!"
  end
end

작성하여 메소드 호출

Thing.hello("John Doe")  # prints: "Hello, John Doe!"

싱글 톤 메소드

이들은 클래스의 특정 인스턴스에서만 사용할 수 있지만 모든 클래스에서 사용할 수는 없습니다.

# create an empty class
class Thing
end

# two instances of the class
thing1 = Thing.new
thing2 = Thing.new

# create a singleton method
def thing1.makestuff
  puts "I belong to thing one"
end

thing1.makestuff # => prints: I belong to thing one
thing2.makestuff # NoMethodError: undefined method `makestuff' for #<Thing>

singletonclass 메소드 모두를 eigenclass class ( eigenclass 라고합니다. 기본적으로 루비는 생성 된 인스턴스를 방해하지 않도록 그러한 메서드를 포함하는 익명 클래스를 만드는 것입니다.

이 작업을 수행하는 또 다른 방법은 class << 생성자입니다. 예 :

# a class method (same as the above example)
class Thing
  class << self # the anonymous class
    def hello(name)
      puts "Hello, #{name}!"
    end
  end
end

Thing.hello("sarah") # => Hello, sarah!

# singleton method

class Thing
end

thing1 = Thing.new

class << thing1
  def makestuff
    puts "I belong to thing one"
  end
end

thing1.makestuff # => prints: "I belong to thing one"

동적 클래스 생성

클래스는 Class.new 사용하여 동적으로 생성 될 수 있습니다.

# create a new class dynamically
MyClass = Class.new

# instantiate an object of type MyClass
my_class = MyClass.new

위의 예제에서 새 클래스가 만들어져 MyClass 상수에 할당됩니다. 이 클래스는 다른 클래스와 마찬가지로 인스턴스화되고 사용될 수 있습니다.

Class.new 메소드는, 동적으로 작성된 클래스의 슈퍼 클래스가되는 Class 를 받아들입니다.

# dynamically create a class that subclasses another
Staffy = Class.new(Dog)

# instantiate an object of type Staffy
lucky = Staffy.new
lucky.is_a?(Staffy) # true
lucky.is_a?(Dog)    # true

Class.new 메서드는 블록을 받아들입니다. 블록의 컨텍스트는 새로 생성 된 클래스입니다. 이를 통해 메소드를 정의 할 수 있습니다.

Duck = 
  Class.new do
    def quack
      'Quack!!'
    end
  end

# instantiate an object of type Duck
duck = Duck.new
duck.quack # 'Quack!!'

새로 만들기, 할당 및 초기화

많은 언어에서 특별한 new 키워드를 사용하여 클래스의 새 인스턴스가 만들어집니다. Ruby에서 new 는 클래스의 인스턴스를 만드는 데에도 사용되지만 키워드가 아닙니다. 대신 정적 / 클래스 메서드이며 다른 정적 / 클래스 메서드와 다릅니다. 정의는 대략 다음과 같습니다.

class MyClass
   def self.new(*args)
     obj = allocate
     obj.initialize(*args) # oversimplied; initialize is actually private
     obj
   end
end

allocate 는 클래스의 초기화되지 않은 인스턴스를 생성하는 실제 '마법'을 수행합니다.

또한 initialize 의 반환 값은 무시되고 대신 obj가 반환됩니다. 이것에 의해, self 을 돌려주는 것에 대해 걱정하지 않고 initialize 메소드를 코딩 할 수있는 이유가 즉시 명확 해집니다.

모든 클래스가 Class 로부터 얻는 '일반적인' new 메소드는 위와 같이 작동하지만 원하는대로 재정의하거나 다른 방식으로 작동하는 대체 방법을 정의 할 수 있습니다. 예 :

class MyClass
  def self.extraNew(*args)
    obj = allocate
    obj.pre_initialize(:foo)
    obj.initialize(*args)
    obj.post_initialize(:bar)
    obj
  end
end


Modified text is an extract of the original Stack Overflow Documentation
아래 라이선스 CC BY-SA 3.0
와 제휴하지 않음 Stack Overflow