추상화와 캡슐화의 차이점은 무엇입니까?


답변:


263

여기서 대부분의 답변은 OOP에 중점을두고 있지만 캡슐화는 훨씬 일찍 시작됩니다.

  • 모든 기능은 캡슐화입니다 . 의사 코드에서 :

    point x = { 1, 4 }
    point y = { 23, 42 }
    
    numeric d = distance(x, y)
    

    여기서는 distance평면에서 두 점 사이의 (유클리드) 거리 계산을 캡슐화합니다. 구현 세부 정보를 숨 깁니다. 이것은 순수하고 간단한 캡슐화입니다.

  • 추상화일반화 프로세스입니다 . 구체적으로 구현하고 다소 관련이 있지만 다른 유형의 데이터에 적용 할 수 있습니다. 추상화의 전형적인 예는qsort데이터를 정렬하는C의함수입니다.

    중요한 것은 qsort정렬하는 데이터에 신경 쓰지 않고 실제로 어떤 데이터를 정렬하는지 알지 못한다는 것입니다. 오히려 입력 유형은 유형이없는 포인터 ( void*)이며 C의 방식으로 "데이터 유형에 신경 쓰지 않습니다"라고 말합니다 (이 유형은 유형 지우기라고도 함). 중요한 점은 구현 qsort이 데이터 유형에 관계없이 항상 동일하게 유지 된다는 것입니다 . 유일하게 갖는다 변화는 다르다 데이터 유형에서 데이터 유형으로 비교 기능이다. qsort따라서, 사용자는 상기 비교 함수를 함수 인수로서 제공 할 것을 기대한다.

캡슐화와 추상화는 너무나 밀접한 관계가 있기 때문에 실제로 분리 할 수없는 지점을 만들 수 있습니다. 실제적인 목적으로 이것은 아마도 사실 일 것입니다. 즉, 추상화가 많지 않은 캡슐화가 있습니다.

class point {
    numeric x
    numeric y
}

우리는 점의 좌표를 캡슐화하지만 논리적으로 그룹화하는 것 이상으로 실질적으로 추상화하지는 않습니다.

캡슐화되지 않은 추상화의 예는 다음과 같습니다.

T pi<T> = 3.1415926535

이것은 주어진 값 (π)을 가진 일반 변수 pi 이며 선언은 변수의 정확한 유형에 신경 쓰지 않습니다. 분명히, 나는 실제 코드에서 이와 같은 것을 찾기가 어려울 것입니다 : 추상화는 사실상 항상 캡슐화를 사용합니다. 그러나, 위에서 언급 않는 사실로, C ++ (14)에 존재하는 가변 템플릿 (= 변수 일반적인 템플릿); 약간 더 복잡한 구문으로 예를 들면 다음과 같습니다.

template <typename T> constexpr T pi = T{3.1415926535};

26
모든 방법은 캡슐화이지만 추상화 할 때도 있습니다. 왜냐하면 어떤 것을 조합하고 이름을 지정할 때마다 새로운 개념을 만듭니다. 추상화없는 캡슐화는 쓸모가 없습니다. 따라서 공통점이없는 것은 사실이 아닙니다.
proskor

@proskor 나는 개념이 도메인이 겹치더라도 직교한다는 것을 유지합니다. 모든 캡슐화가 추상화라는 것은 사실 일 수도 있습니다 (그러나 확신 할 수는 없지만). 그러나이 개념이 두 개념의 고유 한 속성이 아니라 부수적이라고 생각합니다.
Konrad Rudolph

8
그것들은 별개이지만 직교하지는 않습니다. 사실, 캡슐화는 실제로 특별한 종류의 추상화, 즉 구조적 추상화라고 생각합니다. 전체적으로 복합적인 것을 고려함으로써 우리는 기본적으로 그것이 어떻게 다른 것으로 구성되어 있는지, 즉 내부 구조를 무시하는 방법에 대한 세부 사항을 무시 (추상)합니다.
proskor

추상화는 사용자로부터 구현 수준 세부 정보를 숨기고 Sum (1,10)과 같은 필요한 값에만 액세스하면 합산됩니다. 우리는 방법을 모른다. 우리는 사용자의 합 과정을 추상화했습니다. 캡슐화의 표준 정의는 우리가 캡슐화 할 때 제안합니다. 즉 하나의 데이터와 그에 작용하는 방법을 만드는 것입니다. 수업과 같은 것. 그것들을 단일 엔티티로 바인딩. 내가 여기에 가져 오려는 요점은 아무것도 아닙니다. 둘 다 존재하기 위해서는 서로가 필요합니다. 하나가 없으면 다른 것이 없습니다.
사라 스 아리아

2
@psylogic 나는“왜”가 너무 사소한 것처럼 보이기 때문에 건너 뛴 것 같아요. 추상화와 캡슐화가 없으면 복잡한 시스템을 작성할 수 없었습니다. 약간 복잡한 문제라도 처음부터 실패 할 정도로 복잡한 프로그램 코드가 필요합니다. 추상화없이, 당신도 숫자 인쇄 할 수있는 프로그램을 쓸 수 없습니다 : 수많은 추상화를 개념 "인쇄"를 포함 (화면의 어떤 문자는 무엇 픽셀 ... 무엇???)
콘라드 루돌프

130

캡슐화 에서 일반 또는 특수 동작에 대한 구현 세부 정보가 숨겨져 있습니다.

추상화 는 일반화를 제공합니다 (예 : 일련의 동작).

여기에 좋은 읽기는 다음과 같습니다 추상화, 캡슐화, 정보 숨기기 개체 기관의 에드워드 V. 베라 르로는.


6
네 하의 연결도 이제 끊어졌지만, 그래. 우리는 항상 기사 이름을 구글 할 수 있습니다. 이것은 내가 tonymarston.co.uk/php-mysql/abstraction.txt에
Abhijeet Apsunde

1
"일반적으로 추상화는 정보를 숨기고있는 용어로 정의되지 않습니다. 예를 들어"무시 "및"추출 "과 같은 단어의 사용에 주목하십시오. 그러나" 요컨대, 추상화는 다른 정보보다 일부 정보가 더 중요하지만 중요하지 않은 정보를 처리하기위한 특정 메커니즘을 지정하지는 않는다고 말할 수 있습니다. "
Chiel ten Brinke

1
OOP의 캡슐화는 무언가를 숨기는 것이 아닙니다. 변하지 않는 사람들을 보호하기 위해 상태와 행동을 결합하는 것입니다.
Eugene Khudoy

121

많은 답변과 그 예가 오도됩니다.

캡슐화 는 해당 데이터 에서 작동하는 데이터기능을 단일 구성 요소로 묶고 일부 객체 구성 요소에 대한 액세스를 제한합니다.
캡슐화는 객체의 내부 표현이 일반적으로 객체 정의 외부의보기에서 숨겨져 있음을 의미합니다.

추상화 는 구현 세부 사항을 포함하지 않고 필수 기능을 나타내는 메커니즘입니다.

캡슐화 : - 정보 숨기기 .
추상화 : - 구현 숨기기 .

예:

class foo{
    private:
        int a, b;
    public:
        foo(int x=0, int y=0): a(x), b(y) {}

        int add(){    
            return a+b;   
        } 
}  

foo클래스 객체의 내부 표현은 클래스 외부에 숨겨져 있습니다. -> 캡슐화.
개체의 액세스 가능한 멤버 (데이터 / 기능) foo는 제한되어 있으며 해당 개체 만 액세스 할 수 있습니다.

foo foo_obj(3, 4);
int sum = foo_obj.add();

방법의 구현 add은 숨겨져 있습니다. -> 추상화.


답변을 업데이트하고 추상화에 반하거나 그렇지 않은 캡슐화의 예와 캡슐화에 반하거나 그렇지 않은 추상화의 예를 보여 줄 수 있습니까?
bjan

1
@bjan; qsortC에서 함수를 사용 하는 것은 추상화의 예입니다. 당신은 그것의 구현의 세부 사항을 모른다. 여기에는 캡슐화가 없습니다. C ++에서 생성자를 사용하여 객체의 데이터 필드를 초기화하는 것은 캡슐화의 예입니다 (생성자를 통해 객체의 구성 요소에 대한 액세스 제어).
haccks

"추상 :-구현 숨기기." 무엇으로부터 구현을 숨기고 있습니까?
Arun Raaj

@ArunRaaj; 그것을 사용하는 다른 개체에서.
haccks

3
이것이 가장 좋은 대답이어야합니다. 간단하고 명확하며 간단한 예제가 있습니다.
Don Dilanga

99

캡슐화는 상자에 물건을 넣고 들여다 보는 구멍을 제공합니다. 이렇게하면 기어를 사용하지 않아도됩니다.

추상화 플랫 아웃은 기어, 래칫, 플라이휠 또는 핵 코어가 있는지 여부와 같이 중요하지 않은 세부 사항을 무시합니다. 그들은 단지 "가"

캡슐화의 예 :

  • 팬티
  • 공구 상자
  • 지갑
  • 핸드백
  • 캡슐
  • 냉동 탄산염
  • 버튼이 있거나없는 상자
  • 부리 토 (기술적으로 부리 토 주변의 옥수수)

추상화의 예 :

  • "사물 그룹"은 추상화 (우리는 집계라고 함)
  • "다른 것들을 포함하는 것들"은 추상화 (우리가 작곡이라고 부릅니다)
  • "컨테이너"는 또 다른 종류의 "다른 것들을 포함하는 것들"추상화입니다. 모든 캡슐화 예는 용기의 종류이지만 모든 용기가 캡슐화를 나타내거나 제공하는 것은 아니다. 예를 들어 바구니는 내용물을 캡슐화하지 않는 용기입니다.

12
이것이 왜 다운 보트입니까? 이 큰 해답에 대한 유일한 올바른 설명 중 하나입니다.
Konrad Rudolph

3
들여다 보는 구멍 만 제공함으로써 캡슐화에서 사용자에게 중요하지 않은 세부 사항을 무시하지 않았습니다. 이것은 추상화가 무엇인지에 대한 것입니다. 두 가지가 어떻게 다른가요? 더 정교하게 만들 수 있습니다.
Sanjeev Kumar Dangi

63
@ Sanjeev 캡슐화는 구체적이며 추상화는 ... 추상적입니다! ;-) 캡슐화는 사용할 수있는 객체이며 추상화는 논의 할 수있는 이상적입니다. 캡슐화는 속옷을 입는 이유이며, 추상화는 속옷과 수영복의 차이점을 설명하는 방법입니다
.

6
@psylogic 추상화는 우리가 생각하는 존재들이 복잡성을 다루는 방법입니다 : 우리는 관련없는 세부 사항을 무시하고, 관련된 일반적인 패턴을 강조하며, 실제 객체의 대체물로 심볼을 사용하고, (다른 추상화 패턴 중에서) 유사한 방식으로 행동하는 방식으로 유사한 것을 특성화합니다. 추상화는 컴퓨터 과학에 의해 발명되지 않았으며, 고대입니다. 상형 문자는 추상화, 단어는 추상화, 생각은 추상화입니다. 캡슐화도 마찬가지로 고대입니다 (속옷, 갑옷, 상자). 이러한 개념을 실제보다 훨씬 어렵게 만들려고 할 수 있습니다.
Steven A. Lowe

1
@ bjan : 나는 그들이 컨테이너가 아니라고 말하지 않았다. 그들은. 나는 컨테이너가 덜 분명한 것을 추가했지만 캡슐화 개념에는 '컨테이너'가 암시됩니다. "컨테이너"는 추상화입니다. 바스켓은 컨테이너이지만 내용물을 완전히 덮거나 숨기거나 보호하지는 않습니다. 도움이 되나요?
Steven A. Lowe

64

캡슐화 는 getter 및 setter 등을 사용하는 것과 같은 데이터 숨기기를 의미합니다.

추상화는 추상 클래스 및 인터페이스 등을 사용하여 구현을 숨기는 것을 의미합니다.


귀하의 답변이 "추상화는 일반화 과정"과 관련되는 방법-추상 클래스 및 인터페이스를 통해 일반화를 달성하는 방법. 예가 있습니까?
N Sharma

43

추상화는 일반화 된 용어입니다. 즉, 캡슐화는 추상화의 하위 집합입니다.

여기에 이미지 설명을 입력하십시오

  • 예 2 : 솔루션 아키텍트는 높은 수준 만드는 사람 추상적 인 전체 솔루션의 기술적 인 디자인,이 디자인은 다음하여 넘겨되어 개발 팀 을 위해 구현 .

    여기서 솔루션 아키텍트는 추상적 인 역할을하고 개발 팀은 캡슐화 역할을합니다.

  • 예 3 : 사용자 데이터의 캡슐화 (네트워킹)

여기에 이미지 설명을 입력하십시오

예의

추상화 (또는 모듈화) – 유형을 사용하면 프로그래머가 비트 또는 바이트보다 높은 수준에서 생각할 수 있으며 낮은 수준의 구현에는 신경 쓰지 않습니다. 예를 들어, 프로그래머는 문자열을 단순한 바이트 배열 대신 문자 값 세트로 생각하기 시작할 수 있습니다. 더 높은 유형의 프로그래머는 프로그래머가 두 가지 크기의 하위 시스템 간의 인터페이스를 생각하고 표현할 수 있습니다. 이는 더 많은 레벨의 지역화를 가능하게하여 서브 시스템의 상호 운용성에 필요한 정의가 두 서브 시스템이 통신 할 때 일관성을 유지하도록합니다. 출처


이것은 다른 모든 답변에 대한 "가장 간단한"설명이며 답변도 받아 들여야합니다.
vikramvi

31

많은 좋은 답변이 위에 제공되었지만 여기에 내 (Java) 관점을 제시하려고합니다.

데이터 캡슐화는 단순히 클래스에서 논리적으로 그룹화 된 데이터의 액세스를 래핑하고 제어하는 ​​것을 의미합니다. 일반적으로 다른 키워드 인 데이터 숨기기 와 연결됩니다 . 이것은 액세스 수정자를 사용하여 Java에서 수행됩니다 .

간단한 예는 전용 변수를 정의하고 getter 및 setter 메소드를 사용하여 액세스하거나 클래스를 사용하는 것만으로 전용 메소드를 만드는 것입니다. 사용자가 이러한 방법과 변수에 대해 알 필요가 없습니다.

참고 : 캡슐화가 모든 데이터 숨기기에 관한 것임을 오해해서는 안됩니다. 캡슐화라고 할 때 관련 데이터와 동작을 그룹화하거나 패키징 또는 번들링해야합니다.

반면에 데이터 추상화 는 복잡한 논리 아래에 사용자에게 노출되지 않도록 일반화하는 개념입니다. Java에서는 인터페이스추상 클래스를 사용하여이 작업을 수행합니다 .

예 -

우리는이 말을하자 인터페이스 동물을 하고 함수가 makeSound ()을 . 이 인터페이스를 구현하는 두 개의 구체적인 클래스 인 DogCat 이 있습니다. 이 구체적인 클래스에는 makeSound () 함수의 개별 구현이 있습니다. 이제 동물을 가지고 있다고 가정 해 봅시다 (우리는 이것을 외부 모듈에서 얻습니다). 모든 사용자가 수신하는 대상은 일부 동물이며 동물 소리를 인쇄하는 것은 사용자의 책임입니다. 무차별 대입 방법 중 하나는 수신 한 객체를 확인하여 해당 유형 을 식별 한 다음 해당 Animal 유형으로 타입 캐스트 한 다음 makeSound () 를 호출 하는 것입니다. 그러나 더 깔끔한 방법은 사물추상화하는 것 입니다. 동물을다형성 참조 및 그것에 makeSound ()를 호출하십시오. 에서 런타임 실제 개체 유형이 적절한 기능을 호출됩니다 무엇에 따라 달라집니다.

자세한 내용은 여기를 참조 하십시오 .

여기에 이미지 설명을 입력하십시오

복잡한 로직은 터치 패드에 캡슐화 된 회로 보드에 있으며 사용자에게이를 추상화하기 위해 멋진 인터페이스 (버튼)가 제공됩니다.

추신 : 위의 링크는 내 개인 블로그로 연결됩니다.


2
블로그가 너무 좋습니다! 내 모든 oops 개념은 이제 응용 프로그램과 함께 완전히 명확합니다!
minigeek

2
지금까지 가장 좋은 답변입니다. 감사합니다.
Mario Levesque

29
  • 추상화를 사용하면 객체가 수행하는 방식 대신 객체가 수행하는 작업에 집중할 수 있습니다
  • 캡슐화 란 개체가 어떻게 동작하는지에 대한 내부 세부 사항이나 메커니즘을 숨기는 것을 의미합니다.

자동차를 운전할 때와 마찬가지로 가스 페달이 무엇을하는지 알지만 캡슐화되어 있기 때문에 배후의 프로세스를 알지 못할 수 있습니다.

C #으로 예를 들어 보겠습니다. 정수가 있다고 가정하십시오.

int Number = 5;
string aStrNumber = Number.ToString();

Number.ToString ()과 같은 메소드를 사용하여 숫자 5의 문자 표현을 리턴하고이를 문자열 오브젝트에 저장합니다. 이 방법은 수행 방식 대신 수행 방식을 알려줍니다.


나는 이것을 짧고 정확한 답으로 거의 올렸지 만, 나는 그 차의 은유가 다시 나를
당황

미안한 친구 hehe, 나는 더 나은 설명을 추가했다.
jasonco

C의 함수도 추상화입니까?
레디

사용되는 언어 나 패러다임에 관계없이 추상화를 작성할 수 있습니다. 짧은 대답으로 그렇습니다. C에는 추상화가있을 수 있습니다. 왜 그렇지 않습니까?
jasonco

17
추상화와 캡슐화에 대한 정의는 동일합니다. 이것이 내가 이해하는 것입니다-그것이 수행되는 방법은 숨겨져 있으며 수행 된 것이 노출됩니다. 자동차와 Number.ToString ()의 예에서 추상화와 캡슐화가 무엇인지 정확하게 지적 할 수 있습니까? 이것은 사물을 지우는 데 도움이 될 것입니다.
Sanjeev Kumar Dangi

28

이것들은 컴퓨터 과학과 프로그래밍에 고유하지 않은 다소 퍼지 개념입니다. 다른 사람들이 이러한 중요한 개념을 이해하는 데 도움이되는 몇 가지 추가 생각을 제시하고 싶습니다.


짧은 답변

캡슐화 -필요한 인터페이스를 노출시키면서 시스템의 특정 부분에 대한 액세스를 숨기거나 제한합니다.

추상화 -구체적인 현실, 특정 물체 또는 실제 인스턴스를 제외하고 특정 특성이 제거 된 것을 고려하여 복잡성을 줄입니다.

주요한 유사점 은 이러한 기술이 이해력과 유용성을 향상시키는 것입니다.

가장 큰 차이점추상화는 사물을 좀 더 단순하게 표현하는 수단이며 (종종 표현을 더 널리 적용 할 수 있도록)하는 반면 캡슐화는 다른 사물과 무언가 상호 작용하는 방식을 변경하는 방법입니다.


긴 답변

캡슐화

희망적으로 더 명확하게 만드는 캡슐화의 예는 다음과 같습니다.

아두 이노 캡슐화

여기에서 우리는이 아두 이노 인클로저 내에서 우노 및 아두 이노 우노을. 인클로저는 캡슐화가 무엇인지에 대한 훌륭한 표현입니다.

캡슐화는 외부의 영향과 지식으로부터 특정 구성 요소를 보호하고 다른 것들과 상호 작용해야하는 구성 요소를 노출시키는 것을 목표로합니다. 프로그래밍 관점에서,이 관련 정보를 숨기는 하지만 액세스 한정자 특정 변수 및 / 또는 속성을 판독 및 기록 할 수있는 정도를 변경.

그러나 그 외에도 캡슐화는 이러한 외부 인터페이스를 훨씬 더 효과적으로 제공하는 것을 목표로합니다. Arduino 예제에서 멋진 버튼과 화면이 포함되어 사용자와 장치의 상호 작용을 훨씬 간단하게 만듭니다. 그들은 사용자에게 장치의 동작에 영향을 미치는 간단한 방법을 제공하고, 그렇지 않으면 훨씬 어려운 작동에 대한 유용한 정보를 얻습니다.

프로그래밍이 그러한 것처럼, 분리 가능한 구조에 다양한 구성 요소의 그룹을 포함한다 function, class또는 object. 또한 이러한 구조와 상호 작용하는 방법뿐만 아니라 구조에 대한 유용한 정보를 얻는 방법을 제공합니다.

캡슐화는 프로그래머가 여러 가지 추가 방법으로 도움을 주며 코드 유지 관리 및 테스트 가능성이 향상됩니다.

추출

여기에 많은 다른 답변이 추상화를 일반화로 정의했지만 개인적으로 정의가 잘못되었다고 생각합니다. 일반화는 실제로는 특정한 유형의 추상화 라고 할 수 있습니다. 다시 말해서, 모든 일반화는 추상화이지만 모든 추상화가 반드시 일반화 는 아닙니다 .

추상화를 생각하는 방법은 다음과 같습니다.

픽셀 트리

이미지에 나무가 있다고 말할 수 있습니까? 당신이 할 가능성이 있습니다. 그러나 그것은 정말로 나무인가? 물론 아닙니다! 우리가 나무라고 부르는 것처럼 보이도록 만들어진 많은 픽셀입니다. 우리는 그것이 실제 나무의 추상화를 나타낸다고 말할 수 있습니다. 트리에 대한 몇 가지 시각적 세부 사항이 생략되었습니다. 또한 자라거나 물을 소비하거나 산소를 생성하지 않습니다. 어떻게 할 수 있습니까? 컴퓨터 메모리의 바이트로 표시되는 화면의 여러 색상 일뿐입니다.

그리고 여기 추상화의 본질이 있습니다. 이해하기 쉽도록 일을 단순화하는 방법입니다. 당신의 머리를 통과하는 모든 아이디어는 현실의 추상화입니다. 나무의 당신의 정신적 이미지는이 JPEG보다 더 실제적인 나무가 아닙니다.

프로그래밍에서, 우리는 Tree시뮬레이션 된 성장, 물 소비 및 산소 생산을위한 방법 으로 클래스를 생성함으로써 이것을 우리의 이점으로 사용할 수 있습니다 . 우리의 창조는 실제 나무에 대한 우리의 경험을 나타내는 것이며, 우리가 특정 시뮬레이션에 정말로 관심을 갖는 요소만을 포함합니다. 우리는 바이트와 수학에 대한 경험을 나타내는 방법으로 추상화를 사용합니다.

추상 클래스

프로그래밍의 추상화를 통해 여러 "콘크리트"객체 유형 (실제로 존재하는 유형) 간의 공통성을 고려하고 고유 한 엔터티 내에서 공통성을 정의 할 수 있습니다. 예를 들어, 우리의 Tree클래스는 상속 할 수 있습니다 abstract class Plant몇 가지 속성과 우리의 식물처럼 모든 클래스에 적용 할 수있는 방법이 있지만, 이는 제거 식물의 각 유형에 고유 한 것들입니다. 이를 통해 코드 중복을 크게 줄이고 유지 관리 성을 향상시킬 수 있습니다.

abstract class와 플레인 의 실제 차이점은 class개념적으로의 "실제"인스턴스가 없다는 것 abstract class입니다. Plant충분히 구체적이지 않기 때문에 객체 를 구성하는 것은 의미가 없습니다 . 모든 "실제" Plant는보다 구체적인 유형입니다 Plant.

또한 우리의 프로그램이보다 현실적이기를 원한다면, 우리 Tree클래스가 너무 추상적 이라는 사실을 고려하고 싶을 것입니다. 실제로, 모든이 Tree의 더 구체적인 유형입니다 Tree우리가 같은 그 유형에 대한 클래스를 만들 수 있도록 Birch, Maple등, 우리, 아마 지금부터 어떤 상속 abstract, Tree클래스입니다.

JVM

추상화의 또 다른 좋은 예는 JVM (Java Virtual Machine) 이며 Java 코드를 실행할 가상 또는 추상 컴퓨터를 제공합니다. 기본적으로 시스템의 모든 플랫폼 특정 구성 요소를 제거하고 특히 시스템에 관계없이 "컴퓨터"의 추상 인터페이스를 제공합니다.

차이점

캡슐화는 어떤 것이 '실제'인지 '정확한'지와 관련이 없다는 점에서 추상화와 다릅니다. 더 단순하거나 광범위하게 적용하기 위해 구성 요소를 제거 하지 않습니다 . 오히려 유사한 목적을 달성하기 위해 특정 구성 요소를 숨길 수 있습니다 .


22

캡슐화 : 실제 객체 사용자의 원치 않는 / 예기치 않은 / 독점적 구현 세부 사항을 숨기고 있습니다. 예 :

List<string> list = new List<string>();
list.Sort(); /* Here, which sorting algorithm is used and hows its 
implemented is not useful to the user who wants to perform sort, that's 
why its hidden from the user of list. */

추상화 : 일반화를 제공하는 방법으로 광범위한 개체를 다루는 일반적인 방법입니다. 예 :

class Aeroplane : IFlyable, IFuelable, IMachine
{ // Aeroplane's Design says:
  // Aeroplane is a flying object
  // Aeroplane can be fueled
  // Aeroplane is a Machine
}
// But the code related to Pilot, or Driver of Aeroplane is not bothered 
// about Machine or Fuel. Hence,
// pilot code:
IFlyable flyingObj = new Aeroplane();
flyingObj.Fly();
// fighter Pilot related code
IFlyable flyingObj2 = new FighterAeroplane();
flyingObj2.Fly();
// UFO related code 
IFlyable ufoObj = new UFO();
ufoObj.Fly();
// **All the 3 Above codes are genaralized using IFlyable,
// Interface Abstraction**
// Fly related code knows how to fly, irrespective of the type of 
// flying object they are.

// Similarly, Fuel related code:
// Fueling an Aeroplane
IFuelable fuelableObj = new Aeroplane();
fuelableObj.FillFuel();
// Fueling a Car
IFuelable fuelableObj2 = new Car(); // class Car : IFuelable { }
fuelableObj2.FillFuel();

// ** Fueling code does not need know what kind of vehicle it is, so far 
// as it can Fill Fuel**

4
캡슐화의 예는 실제로 추상화의 예입니다.
haccks

13

추상화와 캡슐화의 차이점.

추상화와 캡슐화의 차이점


다른 사람이 추상화가 디자인 수준에 있고 캡슐화가 구현 수준에 있다는 차이점을 확인할 수 있습니까? 그렇다면 이것이 실제로 나를 위해 정리했습니다!
Adam Carter

12

추상화 : 이해하기 쉽고 사용하기 쉬우거나 상황과 관련이있는 단순화 된 방식으로 표현하는 아이디어.

이메일을 보내는 클래스를 생각해보십시오. 추상화를 사용하여 일종의 메신저 소년으로 자신을 보여 주므로 emailSender.send (mail, recipient)로 전화 할 수 있습니다. 실제로 수행하는 작업-POP3 / SMTP, 호출 서버, MIME 변환 등을 선택하면 추상화됩니다. 당신은 당신의 메신저 소년을 볼 수 있습니다.

캡슐화 : 개체의 개인 데이터와 메서드를 보호하고 숨기려는 아이디어. 그것은 독립적이고 절대적인 것을 만드는 데 더 많은 것을 다룬다.

예를 들어주세요. 나는 다른 세계에서 내 심장 박동을 캡슐화합니다. 다른 사람이 그 변수를 변경하는 것을 원하지 않기 때문에, 내가 기능하기 위해 다른 사람이 변수를 설정할 필요가 없기 때문입니다. 그것은 나에게 매우 중요하지만 그것이 무엇인지 알 필요는 없으며 어쨌든 신경 쓰지 않아도됩니다.

주위를 둘러 보면 여러분이 만지는 거의 모든 것이 추상화와 캡슐화의 예라는 것을 알 수 있습니다. 예를 들어, 휴대 전화는 GSM, 프로세서 아키텍처, 무선 주파수 및 이해하지 못하거나 신경 쓰지 않는 백만 가지 사항을 포함하여 다른 사람에게 말한 것을 말할 수있는 추상화를 제공합니다. 또한 일련 번호, ID 번호, 주파수 등과 같은 특정 데이터를 캡슐화합니다.

그것은 모두 세상을 살기 좋은 곳으로 만듭니다. : D


10

추상화 : 필요한 정보 만 표시됩니다. 컴퓨터를 켜는 예에 초점을 맞추겠습니다. 사용자는 시스템이 계속로드되는 동안 진행되는 작업을 알 필요가 없습니다 (정보가 사용자에게 표시되지 않음).

ATM의 또 다른 예를 들어 봅시다. 고객은 기계가 PIN을 읽고 거래를 처리하는 방법을 알 필요가 없으며 PIN을 입력하고 현금을 가지고 떠나기 만하면됩니다.

캡슐화 : 클래시의 민감한 데이터를 숨겨서 일부를 민영화하는 것을 다룹니다. 외부에서 정보에 액세스 할 수 없도록하여 일부 정보를 클라이언트에게 비공개로 유지하는 방법입니다.


2
"정보를 비공개로 유지하는 방법"은 정보를 숨기는 것이라고 생각합니다. 캡슐화는 개인 또는 공개 정보 일 수 있습니다.
버그 아님

데이터 숨김으로 캡슐화가 잘못 이해되었습니다.
thesummersign

8

다른 예시:

다음과 같이 불변의 Rectangle 클래스를 만들었다 고 가정 해보십시오.

class Rectangle {
 public:
  Rectangle(int width, int height) : width_(width), height_(height) {}
  int width() const { return width_; }
  int height() const { return height_; }

 private:
  int width_;
  int height_;
}

이제 너비와 높이를 캡슐화 했음 이 분명합니다 (접근 방식은 어떻게 든 제한되어 있음). 어떤 것도 추상화 하지 않았습니다 (아마, 사각형이 좌표 공간에서 어디에 있는지 무시했을 것입니다. 그러나 이것은 결함입니다. 예).

좋은 추상화는 일반적으로 좋은 캡슐화를 의미합니다.

좋은 추상화의 예는 일반적인 데이터베이스 연결 클래스입니다. 공용 인터페이스는 데이터베이스와 무관하며 매우 간단하지만 연결을 통해 원하는 작업을 수행 할 수 있습니다. 그리고 당신은 참조하십시오? 클래스에는 모든 저수준 핸들과 호출이 있어야하기 때문에 캡슐화도 있습니다.


8

AbstractionEncapsulation 하나의 일반화 된 예를 사용하여

-------------------------------------------------- -------------------------------------------------- --------------------------------

우리는 모두 복잡한 문제를 계산하기 위해 계산기를 사용합니다!

영상


2
@NehaChoudhary, 나는 당신이 말하는 것을 의미한다고 생각합니다 Your both example tell about just encapsulation, not abstraction; 추상화는 hiding오히려 아무 관련이 없다Generalizing
Rahul

@Rahul 이제 둘 다 캡슐화를 설명하지 않는다고 생각합니다!
Neha Choudhary

3
@Devrath Calulcator를 사용하여 추상화를하려면 다음과 같이하십시오. 일반화되고 다른 종류의 계산기를 만들기위한 기본 개념으로 사용할 수있는 계산기의 추상 개념이 있습니다. 예를 들어 BasicCalculator와 ScientificCalculator는 모두 고유 한 계산 방법을 구현하지만 결국 일반화 된 계산기의 기준을 충족합니다.
Neha Choudhary

지금까지 오답의 바다에서 가장 좋은 답변
Aman

7

외부 기능에 의한 의도적이거나 우발적 인 오용으로부터 안전한 특정 개체의 데이터를 방지하는 메커니즘을 " 데이터 캡슐화"라고합니다.

배경 세부 사항이나 설명을 포함하지 않고 필수 기능을 나타내는 행위를 추상화라고합니다.


7

추상화 : 추상화는 보여줍니다What 는 기능의 일부 합니다.

캡슐화 : 캡슐화는How 는 기능 일부 합니다.

아주 간단한 예를 들어 보겠습니다

/// <summary>
/// We have an Employee class having two properties EmployeeName and EmployeeCode
/// </summary>
public class Employee
{
    public string EmplpyeeName { get; set; }
    public string EmployeeCode { get; set; }

    // Add new employee to DB is the main functionality, so are making it public so that we can expose it to external environment
    // This is ABSTRACTION
    public void AddEmployee(Employee obj)
    {
        // "Creation of DB connection" and "To check if employee exists" are internal details which we have hide from external environment
        // You can see that these methods are private, external environment just need "What" part only
        CreateDBConnection();
        CheckIfEmployeeExists();
    }


    // ENCAPLUSATION using private keyword
    private bool CheckIfEmployeeExists()
    {
        // Here we can validate if the employee already exists
        return true;
    }

    // ENCAPLUSATION using private keyword
    private void CreateDBConnection()
    {
        // Create DB connection code
    }
}

콘솔 응용 프로그램의 프로그램 클래스

class Program
{
    static void Main(string[] args)
    {
        Employee obj = new Employee();
        obj.EmplpyeeName = "001";
        obj.EmployeeCode = "Raj";

        // We have exposed only what part of the functionality
        obj.AddEmployee(obj);
    }
}

6

스택 예제를 보자. 배열 또는 연결된 목록을 사용하여 구현할 수 있습니다. 그러나 지원하는 작업은 푸시 앤 팝입니다.

이제 추상화 는 인터페이스 푸시 및 팝만 노출합니다. 기본 표현은 숨겨져 있으며 (배열 또는 연결된 목록입니까?) 잘 정의 된 인터페이스가 제공됩니다. 이제 추상화 된 데이터에 실수로 액세스하지 않도록하려면 어떻게해야합니까? 여기에서 캡슐화 가 시작됩니다. 예를 들어 C ++의 클래스는 액세스 지정자를 사용하여 우발적 인 액세스 및 수정을 방지합니다. 또한 위에서 언급 한 인터페이스를 공용으로 만들어 스택을 조작 할 수있는 유일한 방법은 잘 정의 된 인터페이스를 통하는 것입니다. 이 과정에서 데이터와 데이터를 조작 할 수있는 코드를 결합했습니다 (여기서 친구 기능을 사용하지 마십시오). 즉, 코드와 데이터가 함께 결합되거나 묶이거나 캡슐화됩니다.


5

캡슐화는 클래스 및 따라서 캡슐화라는 하나의 캡슐로 복잡성을 줄입니다 ... 추상화는 다른 객체와 차별화되는 객체의 특성입니다 ...

추상화는 하나 이상의 메소드를 추상적으로 갖는 클래스 요약을 만들어서 달성 할 수 있습니다. 어느 것이 그것을 확장하는 클래스에 의해 구현되어야하는 특성 일 뿐이다. 예를 들어 자동차를 발명 / 설계 할 때는 자동차에 4 개의 문, 브레이크, 스티어링 휠 등이 있어야한다는 특성을 정의해야합니다. 따라서이 디자인을 사용하는 사람은 누구나이 특성을 포함해야합니다. 구현은 각 추상화의 머리가 아닙니다. 포함해야 할 특성을 정의 할뿐입니다.

캡슐화는 상속, 집계 또는 구성과 함께 public, private, protected와 같은 액세스 수정자를 사용하여 클래스 및 하나의 캡슐에 데이터와 동작을 유지함으로써 달성됩니다. 따라서 필요한 것만 보여주고 싶은 정도로만 표시합니다. 즉, 공공, 보호, 친근감 및 개인 카 펀다 …… 예를 들어 GM은 위의 자동차의 추상 디자인을 사용하기로 결정합니다. 그러나 그들은 동일한 특성을 가지고 있으며 거의 ​​동일한 기능을 수행하는 다양한 제품을 보유하고 있습니다. 그래서 그들은 위의 추상 클래스를 확장하는 클래스를 작성합니다. 기어 박스 작동 방식, 브레이크 작동 방식, 스티어링 휠 작동 방식을 설명합니다. 그런 다음 모든 제품은이 공통 기능을 사용합니다. 그들은 기어 박스가 어떻게 작동하는지 또는 작동을 중단하거나 스티어링 휠 작동을 알 필요가 없습니다.

둘 다 강력하다. 그러나 추상화를 사용하려면 캡슐화보다 더 많은 기술이 필요하며 더 큰 응용 프로그램 / 제품은 추상화없이 생존 할 수 없습니다.


"추상화를 사용하려면 캡슐화보다 더 많은 기술이 필요합니까?" 인용이 필요했습니다.
Johnsyweb 2013

5

추상화-디자인 구현에서 인터페이스 숨기기-추상 계산 사용

캡슐화-데이터 숨기기-개발시 ---- 액세스 수정 자 사용 (공개 / 개인)


4

에서

OOPS의 캡슐화와 추상화의 차이점

추상화 및 캡슐화는 두 가지 중요한 객체 지향 프로그래밍 (OOPS) 개념입니다. 캡슐화와 추상화는 서로 관련된 용어입니다.

캡슐화와 추상화의 실제 차이점

캡슐화는 숨는 것을 의미합니다. 캡슐화를 데이터 숨기기라고도합니다. 캡슐화는 캡슐 안에 약을 숨기는 캡슐 (의약품 정제)과 같은 것으로 생각할 수 있습니다. 캡슐화는 속성과 메서드를 숨기면서 줄 바꿈됩니다. 캡슐화는 외부에서 데이터를 보호하기 위해 단일 단위로 코드와 데이터를 숨기는 데 사용됩니다. 클래스는 캡슐화의 가장 좋은 예입니다.

추상화는 원하는 사용자에게 필요한 세부 정보 만 표시하는 것을 말합니다. 이름에서 알 수 있듯이 추상화는 "추상적 인 형태"입니다. 우리는 프로그래밍 언어에서 추상화를 사용하여 추상 클래스를 만듭니다. 추상 클래스는 클래스의 메서드 및 속성에 대한 추상 뷰를 나타냅니다.

캡슐화와 추상화의 구현 차이

  1. 추상화는 인터페이스와 추상 클래스를 사용하여 구현되고 캡슐화는 개인 및 보호 된 액세스 수정자를 사용하여 구현됩니다.

  2. OOPS는 캡슐화를 사용하여 프로그래머가 의도하지 않은 방식으로 데이터에 액세스하지 못하도록하여 형식의 무결성을 유지 (즉, 데이터가 적절한 방식으로 사용되도록)합니다. 캡슐화를 통해 미리 결정된 기능 그룹 만 데이터에 액세스 할 수 있습니다. 액세스 제한 (공개 / 개인 등)과 함께 묶인 데이터 유형 및 작업 (방법)에 대한 총칭은 클래스입니다.


4

간단한 방법으로 캡슐화를 시연 해 보도록하겠습니다.

  • 데이터와 함수를 단일 단위 (클래스라고 함)로 정리하는 것을 캡슐화라고합니다. 내부 데이터 구조 및 코드와 같은 개체에 대한 정보를 포함하고 숨기는 캡슐화

캡슐화는-

  • 복잡성 숨기기,
  • 데이터와 기능의 결합
  • 복잡한 방법을 비공개로 만들기
  • 인스턴스 변수를 비공개로 설정
  • 최종 사용자의 불필요한 데이터 및 기능 숨기기.

캡슐화는 추상화를 구현합니다.

그리고 추상화는-

  • 필요한 것을 보여주는,
  • 데이터는 최종 사용자로부터 추상화되어야합니다.

예를 보자.

아래 이미지는 "데이터베이스에 추가 할 고객 정보"의 GUI를 보여줍니다.

고객 화면 GUI

이미지를 보면 고객 클래스가 필요하다고 말할 수 있습니다.

1 단계 : 내 고객 클래스에는 무엇이 필요합니까?

  • 고객 코드 및 고객 이름을 저장하는 2 개의 변수.
  • 1 고객 코드 및 고객 이름을 데이터베이스에 추가하는 기능.

    네임 스페이스 CustomerContent {공개 클래스 고객 {공개 문자열 CustomerCode = ""; 공개 문자열 CustomerName = ""; public void ADD () {// 내 DB 코드는 여기로 간다}

이제 ADD 방법 만 여기서는 작동하지 않습니다.

2 단계 : ADD 기능이 어떻게 작동합니까?

데이터베이스 연결 코드 및 유효성 검사 코드 (추가 방법)가 필요합니다.

public bool Validate()
{
    //Granular Customer Code and Name
    return true;
}

public bool CreateDBObject()
{
    //DB Connection Code
    return true;
}


class Program
{
static void main(String[] args)
{
CustomerComponent.Customer obj = new CustomerComponent.Customer;

obj.CustomerCode = "s001";
obj.CustomerName = "Mac";

obj.Validate();
obj.CreateDBObject();

obj.ADD();
}
}

이제 최종 사용자에게 Extra Methods (Validate (); CreateDBObject () [Complicated and Extra method])를 표시 할 필요가 없습니다. 최종 사용자는 추가 할 고객 코드, 고객 이름 및 ADD 버튼 만보고 알아야합니다. 최종 사용자는 데이터를 데이터베이스에 추가하는 방법에 대해 신경 쓰지 않습니다.

3 단계 : 최종 사용자의 상호 작용이 필요하지 않은 추가적이고 복잡한 방법을 비공개로 설정하십시오.

따라서 Complicated 및 Extra 메서드를 Private 대신 Public (즉, 해당 메서드 숨기기)으로 만들고 obj.Validate (); obj.CreateDBObject (); 메인 프로그램에서 우리는 캡슐화를 달성합니다.

즉, 최종 사용자에 대한 인터페이스 단순화는 캡슐화입니다.

이제 코드는 다음과 같습니다.

namespace CustomerContent
{
public class Customer
{
public string CustomerCode = "";
public string CustomerName = "";
public void ADD()
{
   //my DB code will go here
}

private bool Validate()
{
    //Granular Customer Code and Name
    return true;
}

private bool CreateDBObject()
{
    //DB Connection Code
    return true;
}


class Program
{
static void main(String[] args)
{
CustomerComponent.Customer obj = new CustomerComponent.Customer;

obj.CustomerCode = "s001";

obj.CustomerName = "Mac";

obj.ADD();
}
}

요약 :

1 단계 : 고객 클래스에 필요한 것은 무엇입니까? 추상화입니다.

-3 단계 : -3 단계 : 최종 사용자의 상호 작용과 관련이없는 추가적이고 복잡한 방법은 전용 캡슐화입니다.

추신-위의 코드는 어렵고 빠릅니다.


4

아래 단락은 그들이 어떻게 다른지 이해하는 데 도움이되었습니다.

데이터 캡슐화는 데이터를 묶는 메커니즘이며이를 사용하는 함수와 데이터 추상화는 인터페이스 만 노출하고 구현 세부 정보를 사용자에게 숨기는 메커니즘입니다.

자세한 내용은 여기를 참조 하십시오 .


3

추상화 나 캡슐화에 정보 숨기기가 반드시 필요한 것은 아닙니다. 정보는 무시할 수 있지만 숨길 필요는 없습니다.

캡슐화 는 여러 복잡한 부분이나 아이디어로 구성되어 있어도 무언가를 하나의 것으로 취급하는 기능입니다.예를 들어, 나는 특정 디자인과 기능을 가진 의자의 여러 다양한 부분을 언급하기보다는 "의자"에 앉아 있다고 말할 수 있습니다. 바닥에서 멀리 떨어지십시오.

캡슐화를 통해 추상화 가 가능합니다. 객체를 캡슐화하기 때문에 내부 객체 구조의 미묘한 세부 사항에 얽매이지 않고 어떤 방식 으로든 서로 관련이있는 것으로 생각할 수 있습니다. 추상화는 작은 세부 사항에 대한 우려에서 제거 된 더 큰 그림을 고려하는 기능입니다. 단어의 근본은 학술 논문의 맨 위에 표시되는 요약에서와 같이 추상적이며 파생 된 서브 클래스로만 인스턴스화 할 수있는 클래스에서는 추상적이 아닙니다.

나는 의자에 엉덩이를 내릴 때 의자의 구조가 어떻게 몸무게를 잡고 붙잡을 지 생각하지 않는다고 솔직하게 말할 수있다. 세부 사항에 대해 걱정할 필요가없는 적절한 의자입니다. 그래서 나는 내 컴퓨터에 관심을 돌릴 수 있습니다. 그리고 다시, 나는 컴퓨터의 구성 요소에 대해 생각하지 않습니다. 나는 입력 할 수있는 텍스트 영역을 나타내는 웹 페이지의 일부를보고 있으며, 손가락으로 키보드에서 항상 올바른 문자를 항상 어떻게 찾는 지 거의 생각하지 않고 단어로 의사 소통하고 있습니다. 이러한 키를 두드리고이 포럼에 게시하는 것은 궁극적으로 연결됩니다. 이것이 추상화의 큰 힘입니다. 낮은 수준의 시스템은 일관성과 정확성으로 작동하도록 신뢰할 수 있기 때문에 더 큰 작업을 위해 여분의주의가 필요합니다.


2
class Aeroplane : IFlyable, IFuelable, IMachine
{ // Aeroplane's Design says:
  // Aeroplane is a flying object
  // Aeroplane can be fueled
  // Aeroplane is a Machine
}
// But the code related to Pilot, or Driver of Aeroplane is not bothered 
// about Machine or Fuel. Hence,
// pilot code:
IFlyable flyingObj = new Aeroplane();
flyingObj.Fly();
// fighter Pilot related code
IFlyable flyingObj2 = new FighterAeroplane();
flyingObj2.Fly();
// UFO related code 
IFlyable ufoObj = new UFO();
ufoObj.Fly();
// **All the 3 Above codes are genaralized using IFlyable,
// Interface Abstraction**
// Fly related code knows how to fly, irrespective of the type of 
// flying object they are.

// Similarly, Fuel related code:
// Fueling an Aeroplane
IFuelable fuelableObj = new Aeroplane();
fuelableObj.FillFuel();
// Fueling a Car
IFuelable fuelableObj2 = new Car(); // class Car : IFuelable { }
fuelableObj2.FillFuel();

// ** Fueling code does not need know what kind of vehicle it is, so far 
// as it can Fill Fuel**

2

추상화는 사용자로부터 유용하지 않은 데이터를 숨기고 캡슐화는 데이터를 캡슐 (클래스)로 묶습니다. 캡슐화는 추상화를 달성하는 방법이라고 생각합니다.


2

추상화 및 캡슐화 프로세스는 모두 인터페이스를 생성합니다.

캡슐화를 통해 생성 된 인터페이스는 구현 세부 사항을 숨 깁니다.

추상화를 통해 생성 된 인터페이스는 추상화 이전에 비해 더 많은 데이터 유형에 적용 할 수 있습니다.


2

Abstraction우리가 할 구현에 대한 계약 입니다. 구현은 시간이 지남에 따라 변경 될 수 있습니다. 다양한 구현 자체는 숨겨져 있거나 숨겨져 있지는 않지만 마스크되어 있습니다. 추상화 뒤에.

APIs클래스의 모든 클래스를 정의한 interface다음 코드 사용자에게 정의 된 정의 APIs에 따라달라고 요청 한다고 가정 합니다 interface. 우리는 정해진 계약을 따라야 만 구현을 개선하거나 수정할 수 있습니다. 사용자는되지 않습니다 결합 된 우리의 구현.

우리는 추상화에서 모든 NECESSARY 규칙 (방법)을 노출하고, 규칙 구현은 구현 자 엔티티에 남겨두고, 구현은 추상화의 일부가 아닙니다. 추상화를 만드는 것은 서명선언 일뿐 입니다.

Encapsulation단순히 숨어 상태와 행동의 ACESS을 줄여 내부 세부 사항을. 캡슐화 된 클래스는 잘 정의되어 있거나 없을 수 있습니다 Abstraction.

java.util.List에 대한 추상화입니다 java.util.ArrayList. 액세스 수정 자로 java.util.ArrayList표시되는 내부 상태 non public는 캡슐화입니다.

편집 클래스를 가정 Container.nava implements IContainer, IContainer방법처럼 선언 할 수 addElement, removeElements, contains여기서, 등 IContainer의 구현 클래스의 추상화를 나타낸다. 추상화는 클래스 또는 모듈 또는 시스템의 API를 외부 세계에 선언합니다. 이러한 API는 contract입니다. 이 시스템은 아직 개발되었거나 개발되지 않았을 수 있습니다. 시스템 사용자는 이제 선언 된 API에 의존 할 수 있으며 그러한 계약을 구현하는 모든 시스템은 항상 선언 된 API를 준수해야하며 해당 API에 대해 항상 구현을 제공해야합니다. 일단 우리가 구체적인 실체를 쓰고 있다면 내부 상태를 숨기기로 결정하는 것은 캡슐화입니다.



1

짧은

추상화 사용-> 캡슐화캡슐화 사용-> 데이터 숨기기

또는

데이터 숨기기는 캡슐화의 하위 집합 이고 캡슐화는 추상화의 하위 집합입니다

참조 : http://www.tonymarston.co.uk/php-mysql/abstraction.txt


캡슐화는 데이터 숨기기를 어떻게 사용합니까? Acc. 마 스턴 캡슐화를 토니하는 것은 숨어있는 행동에 대해 언급 된 것이 아니라 엔티티를 감싸는 것입니다. 캡슐화가 "정보 숨기기와 같은 것"이라면 "캡슐화 된 모든 것도 숨겨져있다"고 주장 할 수 있습니다. 이것은 사실이 아닙니다. 예를 들어, 정보가 레코드 구조 및 배열 내에 캡슐화 될 수 있지만이 정보는 일반적으로 숨겨지지 않습니다 (다른 메커니즘을 통해 숨겨져 있지 않은 경우).
Harshul Sharma
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.