니샨트 미슈라
컴퓨터 과학 학생으로서 저는 새로운 언어를 배우고 연주하는 데 많은 시간을 할애합니다. 모든 새로운 언어에는 고유 한 것이 있습니다. 즉,대부분의 초보자는 다음과 같은 절차 적 언어 또는 자바 스크립트 및 씨++와 같은 객체 지향 언어로 프로그래밍 여행을 시작합니다.
따라서 객체 지향 프로그래밍의 기초를 통해 개념을 이해하고 배우는 언어에 쉽게 적용 할 수 있습니다. 우리는 루비 프로그래밍 언어를 예로 사용할 것입니다.
왜 루비인가? 왜냐하면 그것은”프로그래머를 행복하게 만들기 위해”설계 되었기 때문에 그리고 루비의 거의 모든 것이 객체이기 때문입니다.
의 객체-지향적 패러다임(OOP)
는 객체 지향 프로그래밍에서,우리는 식별하는”것”이 우리의 프로그램으로 처리합니다. 인간으로서 우리는 사물을 속성과 행동을 가진 사물로 생각하고 이러한 속성과 행동을 기반으로 사물과 상호 작용합니다. 것은 자동차,책 등이 될 수 있습니다. 그러한 것들은 클래스(객체의 청사진)가되며,우리는 이러한 클래스에서 객체를 만듭니다.
각 인스턴스(개체)에는 개체(속성)의 상태인 인스턴스 변수가 포함되어 있습니다. 개체 동작은 메서드로 표시됩니다.
자동차의 예를 들어 보겠습니다. 자동차는 그것을 클래스로 만들 것입니다 것입니다. 특정 유형의 자동차는 클래스 자동차의 개체입니다. 색상 및 모델 번호와 같은 속성/속성을 인스턴스 변수에 저장할 수 있습니다. 그리고 운전과 같은 객체의 작업을 수행하려는 경우”드라이브”는 메소드로 정의 된 동작을 설명합니다.
빠른 구문 수업
- 루비 프로그램에서 세미콜론(;(일반적으로 사용되지 않음)
- 2-각 중첩 수준에 대한 공백 들여 쓰기가 권장됩니다(파이썬에서와 같이 필요하지 않음)
- 중괄호 없음
{}
는 사용되지 않으며 최종 키워드는 흐름 제어 블록의 끝을 표시하는 데 사용됩니다 - 논평하기 위해
#
기호
class Car def initialize(name, color) @name = name @color = color end
def get_info "Name: #{@name}, and Color: #{@color}" endend
my_car = Car.new("Fiat", "Red")puts my_car.get_info
위의 코드에서 무슨 일이 일어나고 있는지 이해하려면:
- 우리는 두 가지 방법,
initialize
와get_info
와Car
라는 클래스가 있습니다. - 루비의 인스턴스 변수는
@
(예:@name
)로 시작합니다. 흥미로운 부분은 변수가 처음에 선언되지 않았다는 것입니다. 그들은 처음 사용될 때 존재하게되고,그 후에는 클래스의 모든 인스턴스 메소드에서 사용할 수 있습니다. new
메서드를 호출하면initialize
메서드가 호출됩니다.initialize
는 생성자로 사용되는 특수 메서드입니다.
데이터 액세스
인스턴스 변수는 비공개이며 클래스 외부에서 액세스 할 수 없습니다. 그(것)들에 접근하기 위하여,우리는 방법을 창조할 필요가 있다. 인스턴스 메서드는 기본적으로 공용 액세스 권한을 갖습니다. 이 문서의 뒷부분에서 볼 수 있듯이 이러한 인스턴스 메서드에 대한 액세스를 제한할 수 있습니다.
데이터를 가져오고 수정하려면 각각”게터”및”세터”방법이 필요합니다. 의 자동차의 동일한 예를 복용 이러한 방법을 살펴 보자.
class Car def initialize(name, color) # "Constructor" @name = name @color = color end
def color @color end
def color= (new_color) @color = new_color endend
my_car = Car.new("Fiat", "Red")puts my_car.color # Red
my_car.color = "White"puts my_car.color # White
루비에서”게터”와”세터”는 우리가 다루는 인스턴스 변수와 동일한 이름으로 정의됩니다.
위의 예에서my_car.color
이라고 할 때 실제로color
메서드를 호출하여 색상의 이름을 반환합니다.
참고:메서드 이름이color=
이 게터/세터 메서드를 작성하더라도 루비가 세터를 사용하는 동안color
와 같음 사이의 공백을 어떻게 허용하는지주의하십시오. 그러나 대부분의 경우 기존 값을 얻고 새 값을 설정하는 것은 간단합니다. 따라서 게터/세터 방법을 실제로 정의하는 대신 더 쉬운 방법이 있어야합니다.
쉬운 방법
대신attr_*
양식을 사용하면 기존 값을 가져 와서 새 값을 설정할 수 있습니다.
-
attr_accessor
: 게터와 세터 모두 -
attr_reader
: 게터 전용 -
attr_writer
: 세터 전용
의 자동차의 동일한 예를 복용이 양식을 살펴 보자.
class Car attr_accessor :name, :colorend
car1 = Car.newputs car1.name # => nil
car1.name = "Suzuki"car1.color = "Gray"puts car1.color # => Gray
car1.name = "Fiat"puts car1.name # => Fiat
이 방법으로 게터/세터 정의를 모두 건너 뛸 수 있습니다.
모범 사례에 대한 설명
위의 예제에서는@name
및@color
인스턴스 변수의 값을 초기화하지 않았습니다. 또한 인스턴스 변수가 전무로 설정되므로 개체car1
는 의미가 없습니다. 아래 예제와 같이 생성자를 사용하여 인스턴스 변수를 설정하는 것이 좋습니다.
class Car attr_accessor :name, :color def initialize(name, color) @name = name @color = color endend
car1 = Car.new("Suzuki", "Gray")puts car1.color # => Gray
car1.name = "Fiat"puts car1.name # => Fiat
클래스 메서드 및 클래스 변수
클래스 메서드는 클래스의 인스턴스가 아닌 클래스에서 호출됩니다. 이들은 자바의 정적 메소드와 유사하다.
주: self
메소드 정의의 외부 클래스 객체를 참조한다. 클래스 변수는@@
로 시작 이제,루비에서 클래스 메소드를 정의하는 세 가지 방법이 실제로있다:
클래스 정의 내부
- 메소드의 이름과 키워드 자체를 사용하여:
class MathFunctions def self.two_times(num) num * 2 endend
# No instance createdputs MathFunctions.two_times(10) # => 20
2. 사용<<
;자기
class MathFunctions class << self def two_times(num) num * 2 end endend
# No instance createdputs MathFunctions.two_times(10) # => 20
클래스 정의 외부
3. 메서드 이름과 클래스 이름 사용
class MathFunctionsend
def MathFunctions.two_times(num) num * 2end
# No instance createdputs MathFunctions.two_times(10) # => 20
클래스 상속
루비에서는 모든 클래스가 개체 클래스에서 암시적으로 상속됩니다. 의 예를 살펴 보자.
class Car def to_s "Car" end
def speed "Top speed 100" endend
class SuperCar < Car def speed # Override "Top speed 200" endend
car = Car.newfast_car = SuperCar.new
puts "#{car}1 #{car.speed}" # => Car1 Top speed 100puts "#{fast_car}2 #{fast_car.speed}" # => Car2 Top speed 200
위의 예에서SuperCar
클래스는Car
클래스에서 상속된speed
메서드를 재정의합니다. 기호&
중위;상속을 나타냅니다.
참고:루비는 다중 상속을 지원하지 않으므로 믹스 인이 대신 사용됩니다. 이 기사의 뒷부분에서 논의 할 것입니다.
루비 모듈
루비 모듈은 루비 프로그래밍 언어의 중요한 부분입니다. 언어의 주요 객체 지향 기능이며 간접적으로 다중 상속을 지원합니다.
모듈은 클래스,메서드,상수 또는 다른 모듈의 컨테이너입니다. 클래스와 마찬가지로 모듈은 인스턴스화 될 수 없지만 두 가지 주요 용도로 사용됩니다:
- 네임 스페이스
- 믹스
네임 스페이스와 같은 모듈
자바 같은 언어의 많은 단지 두 클래스 사이의 충돌을 방지하기 위해,패키지 구조의 아이디어를 가지고있다. 의 그것이 어떻게 작동하는지 이해하는 예를 살펴 보자.
module Patterns class Match attr_accessor :matched endend
module Sports class Match attr_accessor :score endend
match1 = Patterns::Match.newmatch1.matched = "true"
match2 = Sports::Match.newmatch2.score = 210
위의 예에서Match
라는 두 개의 클래스가 있으므로 단순히 다른 모듈로 캡슐화하여 두 클래스를 구별하고 충돌을 방지 할 수 있습니다.
모듈 믹스 인
객체 지향 패러다임에서 우리는 인터페이스의 개념을 가지고 있습니다. 믹스 인은 여러 클래스간에 코드를 공유 할 수있는 방법을 제공합니다. 뿐만 아니라,우리는 또한Enumerable
와 같은 내장 모듈을 포함하고 우리의 작업을 훨씬 쉽게 만들 수 있습니다. 예를 보자.
module PrintName attr_accessor :name def print_it puts "Name: #{@name}" endend
class Person include PrintNameend
class Organization include PrintNameend
person = Person.newperson.name = "Nishant"puts person.print_it # => Name: Nishant
organization = Organization.neworganization.name = "freeCodeCamp"puts organization.print_it # => Name: freeCodeCamp
우리는 한 번만 코드를 작성하고 필요에 따라 다음 어디서나 포함 할 수 있습니다 믹스 인은 매우 강력하다.
범위 루비
에서 범위가 어떻게 작동하는지 볼 것입니다:
- 변수
- 상수
- 블록
변수 범위
메서드와 클래스는 변수의 새 범위를 정의하고 외부 범위 변수는 내부 범위로 이월되지 않습니다. 이것이 무엇을 의미하는지 보자.
name = "Nishant"
class MyClass def my_fun name = "John" puts name # => John end
puts name # => Nishant
외부name
변수와 내부name
변수는 동일하지 않습니다. 외부name
변수는 내부 범위로 이월되지 않습니다. 즉,다시 정의하지 않고 내부 범위에 인쇄하려고하면 예외가 발생합니다.
상수 범위
내부 범위는 외부 범위에 정의 된 상수를 볼 수 있으며 외부 상수를 무시할 수도 있습니다. 그러나 내부 범위의 상수 값을 재정의 한 후에도 외부 범위의 값은 변경되지 않는다는 것을 기억하는 것이 중요합니다. 행동에서 그것을 보자.
module MyModule PI = 3.14 class MyClass def value_of_pi puts PI # => 3.14 PI = "3.144444" puts PI # => 3.144444 end end puts PI # => 3.14end
블록 범위
블록은 외부 범위를 상속합니다. 나가 인터넷에 발견한 환상적인 보기를 사용하여 그것을 이해하자.
class BankAccount attr_accessor :id, :amount def initialize(id, amount) @id = id @amount = amount endend
acct1 = BankAccount.new(213, 300)acct2 = BankAccount.new(22, 100)acct3 = BankAccount.new(222, 500)
accts =
total_sum = 0accts.each do |eachAcct| total_sum = total_sum + eachAcct.amountend
puts total_sum # => 900
위의 예에서total_sum
를 계산하는 방법을 사용하면total_sum
변수는 방법 내에서 완전히 다른 변수가 될 것입니다. 그래서 때때로 블록을 사용하면 많은 시간을 절약 할 수 있습니다.
블록 내부에 생성된 변수는 블록에서만 사용할 수 있다.
액세스 제어
클래스를 디자인할 때는 클래스를 얼마나 많이 세계에 노출시킬지 생각해 보는 것이 중요하다. 이를 캡슐화라고 하며 일반적으로 개체의 내부 표현을 숨기는 것을 의미합니다.
루비에는 세 가지 수준의 액세스 제어가 있습니다:
- 공개-액세스 제어가 적용되지 않습니다. 누구나 이러한 방법을 호출 할 수 있습니다.
- 보호됨-정의 클래스 또는 하위 클래스의 객체에 의해 호출 될 수 있습니다.
- 개인-명시 적 수신기를 제외하고는 호출 할 수 없습니다.
동작중인 캡슐화의 예를 살펴 보겠습니다.:
class Car def initialize(speed, fuel_eco) @rating = speed * comfort end
def rating @rating endend
puts Car.new(100, 5).rating # => 500
이제 등급 계산 방법에 대한 세부 사항이 클래스 내에 유지되므로 다른 변경없이 언제든지 변경할 수 있습니다. 또한,우리는 외부에서 등급을 설정할 수 없습니다.
액세스 제어를 지정하는 방법에 대해 이야기,그 중 두 가지가 있습니다:
- 다음 액세스 제어 키워드까지 공개,보호 또는 비공개 및 모든 항목을 지정하면 해당 액세스 제어 수준이 됩니다.
- 메서드를 정기적으로 정의한 다음 공용,개인 및 보호된 액세스 수준을 지정하고 메서드 기호를 사용하여 해당 수준 아래에 쉼표(,)로 구분된 메서드를 나열합니다.
첫 번째 방법의 예:
class MyClass private def func1 "private" end protected def func2 "protected" end public def func3 "Public" endend
두 번째 방법의 예:
class MyClass def func1 "private" end def func2 "protected" end def func3 "Public" end private :func1 protected :func2 public :func3end
참고:공용 및 개인 액세스 제어가 가장 많이 사용됩니다.
결론
이것들은 루비의 객체 지향 프로그래밍의 기본이다. 이제 이러한 개념을 알면 더 깊이 들어가서 멋진 것을 만들어 배울 수 있습니다.
당신이 즐길 경우 박수를 따라하는 것을 잊지 마세요! 여기 나와 함께 계속.