Ruby Language
수업
수색…
통사론
- 클래스 이름
- 클래스 행동을 설명하는 # 코드
- 종료
비고
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를 사용하여 인스턴스 변수에 액세스
세 가지 방법이 있습니다.
-
attr_reader
: 클래스 외부에서 변수를read
수있게 해줍니다. -
attr_writer
: 클래스 외부에서 변수를 수정하는 데 사용됩니다. -
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>
singleton
과 class
메소드 모두를 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