클래스와 모듈의 차이점


438

Java에서 왔으며 이제 Ruby와 더 많은 작업을하고 있습니다.

내가 익숙하지 않은 언어 기능은 module입니다. 나는 정확히 무엇 module이고 언제 사용 하는지 궁금 하며 왜 moduleover를 사용 class합니까?


답변:


398

첫 번째 대답은 좋으며 구조적 대답을 제공하지만 다른 접근 방식은 수행중인 작업에 대해 생각하는 것입니다. 모듈은 여러 클래스에서 사용할 수있는 메소드를 제공하는 것에 관한 것입니다. Rails 앱에서 볼 수 있듯이이를 "라이브러리"로 생각하십시오. 클래스는 객체에 관한 것입니다. 모듈은 기능에 관한 것입니다.

예를 들어 인증 및 권한 부여 시스템이 모듈의 좋은 예입니다. 인증 시스템은 여러 앱 수준 클래스에서 작동하며 (사용자는 인증되고, 세션은 인증을 관리하고, 다른 많은 클래스는 인증 상태에 따라 다르게 작동합니다.) 인증 시스템은 공유 API로 작동합니다.

여러 앱에서 메소드를 공유 할 때 모듈을 사용할 수도 있습니다 (다시 말해서 라이브러리 모델이 좋습니다).


7
모듈이 Java의 인터페이스와 동일합니까?
Saad Rehman Shah

14
@Caffeine은 Ruby 모듈이 실제로 구현을 포함하기 때문에 실제로는 아니지만 Java의 인터페이스는 추상적입니다.
Jorge Israel Peña

8
아니요, 모듈과 Java 패키지 / JAR은 완전히 다른 짐승입니다.
Karoly Horvath 2016 년

9
나는 메소드 구현을 가진 추상 클래스와 더 비슷합니다.
Automatico

2
실제로 @Chole은 모듈에 대한 좋은 점 중 하나 인 Namespacing에 영향을줍니다. 따라서 모듈은 Java 패키지와 직접적으로 동일하지는 않지만 이와 유사한 것을 달성하는 데 사용될 수 있습니다. blog.rubybestpractices.com/posts/gregory/…
michaelok

513
╔═══════════════╦═══════════════════════════╦═════════════════════════════════╗
║               ║ class                     ║ module                          ║
╠═══════════════╬═══════════════════════════╬═════════════════════════════════╣
║ instantiation ║ can be instantiated       ║ can *not* be instantiated       ║
╟───────────────╫───────────────────────────╫─────────────────────────────────╢
║ usage         ║ object creation           ║ mixin facility. provide         ║
║               ║                           ║   a namespace.                  ║
╟───────────────╫───────────────────────────╫─────────────────────────────────╢
║ superclass    ║ module                    ║ object                          ║
╟───────────────╫───────────────────────────╫─────────────────────────────────╢
║ methods       ║ class methods and         ║ module methods and              ║
║               ║   instance methods        ║   instance methods              ║
╟───────────────╫───────────────────────────╫─────────────────────────────────╢
║ inheritance   ║ inherits behaviour and can║ No inheritance                  ║
║               ║   be base for inheritance ║                                 ║
╟───────────────╫───────────────────────────╫─────────────────────────────────╢
║ inclusion     ║ cannot be included        ║ can be included in classes and  ║
║               ║                           ║   modules by using the include  ║
║               ║                           ║   command (includes all         ║
║               ║                           ║   instance methods as instance  ║
║               ║                           ║   methods in a class/module)    ║
╟───────────────╫───────────────────────────╫─────────────────────────────────╢
║ extension     ║ can not extend with       ║ module can extend instance by   ║
║               ║   extend command          ║   using extend command (extends ║
║               ║   (only with inheritance) ║   given instance with singleton ║
║               ║                           ║   methods from module)          ║
╚═══════════════╩═══════════════════════════╩═════════════════════════════════╝

'클래스'클래스의 슈퍼 클래스는 무엇입니까?
Aashish P 2016

10
계층 구조-> 모듈-> 객체-> BasicObject가 있습니다. 멋있는!!
Aashish P 2016

클래스와 모듈이 모두 클래스 변수를 지원할 때 왜 "모듈은"변수를 생략합니까? 수락 된 답변보기 stackoverflow.com/questions/5690458/…
kaleidic

이 모든 답변에 많은 다이어그램이 있습니다. 약간의 실행 예제 : rubyfiddle.com/riddles/06081
Donato

16
모듈이 어떻게 "인스턴스화되지"않고 인스턴스 메소드를 가질 수 있습니까?
devius

91

아직 아무도이 말을하지 않은 것에 놀랐습니다.

asker는 Java 배경에서 나왔으므로 (그리고 나도 마찬가지), 여기에 도움이되는 비유가 있습니다.

클래스는 단순히 Java 클래스와 같습니다.

모듈은 Java 정적 클래스와 같습니다. Math자바 클래스를 생각하십시오 . 인스턴스화하지 않고 정적 클래스 (예 :)의 메소드를 재사용합니다 Math.random().


11
그러나 모듈은 포함 클래스에 인스턴스 메소드를 추가 할 수 있지만 Java의 정적 클래스는 클래스 메소드를 추가 할 수 없습니다.
분석 재개 모니카 - notmaynard

4
이 진술은 무거운 C # 배경에서 나온 사실입니다.
데이먼 드레이크

5
이것은 전적으로 사실이 아닙니다. 모듈에는 정적 메소드가 없으며 메소드 만 있습니다. 모듈은 "자신을 확장"(구문은 실제로 extend self)하여 메소드를 self메타 클래스에서 사용할 수있게합니다 . 이로써 같은 방법을 파견 할 수 random()A의 Math모듈. 그러나 본질적으로 모듈의 메소드는 모듈 자체에서 호출 할 수 없습니다 self. 이는 Ruby의 개념 self, 메타 클래스 및 메소드 조회 작동 방식과 관련이 있습니다. 자세한 내용은 "Metaprogramming Ruby"-Paolo Perlotta를 확인하십시오.
scottburton11

나는 모듈은 그들의 방법과 인터페이스에 더 유사하다라고 말하고 싶지만 (자바 8 개 기본 IMPL와 인터페이스)하지만, 다른과는 달리 자바 인터페이스에서 할 수있는 상속하지 일
divideByZero

이 답변에 얼마나 많은 표가 있습니까? 더 나은 단어 1mo 전에 말한 btw : stackoverflow.com/a/17027346/986862
Andre Figueiredo

39

기본적으로 모듈을 인스턴스화 할 수 없습니다. 클래스에 모듈이 포함되면 모든 모듈 메소드와 클래스 메소드에 대한 액세스를 제공하는 프록시 수퍼 클래스가 생성됩니다.

모듈은 여러 클래스로 포함될 수 있습니다. 모듈은 상속 될 수 없지만이 "mixin"모델은 유용한 유형의 "다중 상속"을 제공합니다. OO 순수 주의자들은 그 진술에 동의하지 않지만, 순결이 일을 끝내는 것을 방해하지는 않을 것이다.


(이 답변은 원래에 연결 http://www.rubycentral.com/pickaxe/classes.html되었지만 해당 링크 및 해당 도메인은 더 이상 활성화되어 있지 않습니다.)


그렇습니다, 이것이 작동하는 방식입니다. 따라서 모듈은 Java의 "정적"클래스와 비교할 수 없습니다 . 프록시 슈퍼 클래스 (일부 호출을에 "메타 클래스")이 만드는 모듈의 방법 파견 메시지의 수신기하게 자바에서 정적 클래스에 더 비교를, 그 방법은 정적 메서드처럼 작동합니다. 그러나 루비 클래스 extend는 클래스를 호출하여 "정적"과 같은 메소드를 취할 수 있습니다 . 루비는 실제로 "인스턴스"와 "클래스 / 정적"메소드를 전혀 구분하지 않으며 그 메소드의 수신자 만 구분합니다.
scottburton11

7

Module루비에서 어느 정도는 Java 추상 클래스에 해당합니다. 인스턴스 메소드가 있으며 클래스는 클래스 메소드를 상속 할 수 있지만 ( include루비 녀석은이를 "믹싱"이라고 함) 인스턴스는 없습니다. 다른 사소한 차이가 있지만이 많은 정보는 시작하기에 충분합니다.


6

네임 스페이스 : 모듈은 네임 스페이스입니다 ... Java에는 존재하지 않습니다.)

또한 Java와 Python에서 Ruby로 전환했는데 정확히 같은 질문이 있었음을 기억합니다 ...

따라서 가장 간단한 대답은 모듈이 네임 스페이스이며 Java에는 존재하지 않는다는 것입니다. 자바에서 네임 스페이스에 가장 가까운 사고 방식은 패키지 입니다.

그래서 루비의 모듈은 java의
클래스 와 같습니다 : class? 어떤
인터페이스를하지? 어떤
추상 클래스하지? 어떤
패키지 없다? 예 (아마도)

자바 클래스 내부의 정적 메소드 : 루비의 모듈 내부 메소드와 동일

자바에서 최소 단위는 클래스이므로 클래스 외부에서는 함수를 가질 수 없습니다. 그러나 루비에서는 (파이썬과 같이) 가능합니다.

그렇다면 모듈은 무엇입니까?
클래스, 메소드, 상수. 모듈은 해당 네임 스페이스 아래에서이를 보호합니다.

인스턴스 없음 : 모듈을 사용하여 인스턴스를 만들 수 없음

혼합 기능 : 때로는 상속 모델이 클래스에는 좋지 않지만 기능면에서 클래스 / 메소드 / 상수 세트를 그룹화하려고합니다.

루비의 모듈에 대한 규칙 :
-모듈 이름은 UpperCamelCase입니다
-모듈 내의 상수는 모두 CAPS입니다 (이 규칙은 모듈에 한정되지 않은 모든 루비 상수에 대해 동일합니다)
-액세스 방법 : use. 연산자
-상수 액세스 : use :: symbol

모듈의 간단한 예 :

module MySampleModule
  CONST1 = "some constant"

  def self.method_one(arg1)
    arg1 + 2
  end
end

모듈 내에서 메소드를 사용하는 방법 :

puts MySampleModule.method_one(1) # prints: 3

모듈 상수를 사용하는 방법 :

puts MySampleModule::CONST1 # prints: some constant

모듈에 대한 몇 가지 다른 규칙 :
파일에서 하나의 모듈 사용 (예 : 루비 클래스, 루비 파일 당 하나의 클래스)


“-액세스 방법 : 사용. 연산자-액세스 상수 : use :: symbol”이 답변 만 언급했습니다!
Qiulang

4

결론 : 모듈은 정적 / 유틸리티 클래스와 믹스 인 간의 교차입니다.

믹스 인은 재사용이 가능한 "부분"구현으로, 믹스 앤 매치 방식으로 결합 (또는 구성)되어 새로운 클래스를 작성하는 데 도움이됩니다. 이러한 클래스는 물론 자체 상태 및 / 또는 코드를 가질 수 있습니다.


1

수업

클래스를 정의 할 때 데이터 유형에 대한 청사진을 정의합니다. 클래스 보유 데이터, 해당 데이터와 상호 작용하고 객체를 인스턴스화하는 데 사용되는 메소드가 있습니다.

구성 단위

  • 모듈은 메소드, 클래스 및 상수를 그룹화하는 방법입니다.

  • 모듈은 두 가지 주요 이점을 제공합니다.

    => 모듈은 네임 스페이스를 제공하고 이름 충돌을 방지합니다. 네임 스페이스는 다른 사람이 작성한 것과 동일한 이름을 가진 함수 및 클래스와의 충돌을 피하는 데 도움이됩니다.

    => 모듈은 mixin 기능을 구현합니다.

(Klazz에 모듈을 포함하면 Klazz 인스턴스가 모듈 메소드에 액세스 할 수 있습니다.)

(클래 즈 클래스에 Mods 메소드에 대한 액세스 권한을 부여하는 Mod로 Klazz를 확장하십시오.)


0

첫째, 아직 언급되지 않은 몇 가지 유사점. 루비는 공개 클래스를 지원하지만 개방형 모듈도 지원합니다. 결국 클래스는 클래스 상속 체인의 모듈에서 상속되므로 클래스와 모듈에는 비슷한 동작이 있습니다.

그러나 프로그래밍 언어로 클래스와 모듈을 함께 사용하는 목적이 무엇인지 스스로에게 물어볼 필요가 있습니까? 클래스는 인스턴스를 만들기위한 청사진으로 만들어졌으며 각 인스턴스는 청사진의 실현 된 변형입니다. 인스턴스는 청사진 (클래스)의 실현 된 변형입니다. 당연히 클래스는 객체 생성 기능을합니다. 또한 한 청사진이 다른 청사진에서 파생되기를 원하기 때문에 클래스는 상속을 지원하도록 설계되었습니다.

모듈을 인스턴스화 할 수 없으며 객체를 만들지 않으며 상속을 지원하지 않습니다. 따라서 한 모듈은 다른 모듈을 상속하지 않습니다.

그렇다면 언어로 모듈을 갖는 요점은 무엇입니까? 모듈을 분명히 사용하는 방법 중 하나는 네임 스페이스를 만드는 것이므로 다른 언어에서도이를 알 수 있습니다. 다시, 루비에 대한 멋진 점은 모듈을 다시 열 수 있다는 것입니다 (클래스처럼). 그리고 이것은 다른 Ruby 파일에서 네임 스페이스를 재사용하려고 할 때 큰 사용법입니다.

module Apple
  def a
    puts 'a'
  end
end

module Apple 
  def b
    puts 'b'
  end
end

class Fruit
  include Apple
end

 > f = Fruit.new
 => #<Fruit:0x007fe90c527c98> 
 > f.a
 => a
 > f.b
 => b

그러나 모듈 간에는 상속이 없습니다.

module Apple
  module Green
    def green
      puts 'green'
    end
  end
end

class Fruit
  include Apple
end

> f = Fruit.new
 => #<Fruit:0x007fe90c462420> 
> f.green
NoMethodError: undefined method `green' for #<Fruit:0x007fe90c462420>

Apple 모듈은 Green 모듈에서 메소드를 상속하지 않았으며 Fruit 클래스에 Apple을 포함 시키면 Apple 모듈의 메소드가 Apple 인스턴스의 상위 체인에 추가되지만 Green 모듈의 메소드는 추가되지 않습니다. 모듈은 Apple 모듈에서 정의되었습니다.

그렇다면 친환경 방법에 어떻게 접근 할 수 있습니까? 클래스에 명시 적으로 포함시켜야합니다.

class Fruit
  include Apple::Green
end
 => Fruit 
 > f.green
=> green

그러나 Ruby에는 모듈에 대한 또 다른 중요한 사용법이 있습니다. 이것은 Mixin 시설이며, SO에 대한 다른 답변으로 설명합니다. 그러나 요약하면 믹스 인을 사용하여 객체의 상속 체인에 메소드를 정의 할 수 있습니다. 믹스 인을 통해 객체 인스턴스의 상속 체인 (include) 또는 singleton_class of self (extend)에 메소드를 추가 할 수 있습니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.