2012-01-11 5 views
0

구현 또는 확장하기 위해 추상 클래스 또는 인터페이스를 사용하는 이유에 대해 혼란 스럽습니다. 인터페이스는 어떤 코드도 포함하지 않으므로 추상 메소드도 마찬가지입니다. 왜 우리가 그들을 사용하는지. 우리가 직접 인터페이스를 만들거나 추상 클래스를 사용하는 대신에 우리는 직접 클래스의 메소드를 만들고 정의하지 않는 것이 좋습니다. 그들은 어떤 종류의 코드도 포함하고 있지 않으므로 클래스에서 확장 한 후에 정의해야합니다. 왜 우리는 우리 자신의 클래스에서 이러한 메소드를 정의하지 않고 인터페이스를 확장 한 다음 정의합니다. 나는 그런 종류의 질문 stackoverflow에서 여러 번 요청했지만 대답을 이해하지 못했습니다. 누구든지 간단한 방법으로 설명해 주시겠습니까?추상 클래스, 인터페이스 또는 추상 메소드의 사용법

+0

이것은 아주 간단한 설명입니다. http://stackoverflow.com/a/1221524/690897 - 알아요, 자바 태그가 붙어 있지만 개념은 특정 언어에 구속되지 않습니다. 이것은 또한 매우 유용하게 보인다 : http://stackoverflow.com/questions/479142/when-to-use-an-interface-instead-of-an-abstract-class-and-vice-versa – Quasdunk

+0

글쎄, 나는 그것을 읽었다. 내가 왜 그것을 필요로하는지 이해할 수 없었다. 왜 우리는 우리 자신의 클래스에서 이러한 메소드를 선언하지 않고 인터페이스를 구현하고 선언하지 않는가? 두 가지 방법으로 할 수 있을까요? – ScoRpion

+0

http://geekswithblogs.net/mahesh/archive/2006/07/05/84120.aspx –

답변

3

추상화와 인터페이스의 힘은 책임을 분리하고 모듈화 된 코드를 작성할 수 있다는 사실에서 비롯된 것입니다. 귀하의 (또는 다른 사람의) 코드 중 일부는 귀하가 Animal 동물이 어떻게 움직이고 먹는지 알 필요없이 동물을 다루는 시설을 제공합니다. 코드의 다른 부분은 Dog, Bird 등의 구체적인 동물을 정의하는 데에만 신경을 쓸 수 있으며 실제로 의 모든 기능을 구현하는 방법에 대한 모든 세부 정보가 포함되어 있습니다.

구체적인 클래스 (Dog, Bird, ...)를 일반 추상 인터페이스 (Animal)로 확장하면 추상 인터페이스 용으로 작성된 라이브러리에서 현재 및 향후 콘크리트 클래스를 사용할 수 있습니다. 새로운 동물을 수용하기 위해 도서관을 변경하도록 도서관 제작자에게 요청할 필요가 없으며 도서관 저자는 기능이 어떻게 구체적으로 구현되는지 알 필요가 없습니다. 당신이 M * N로 끝날 것 즉 - 당신이 멤버 함수 Animal::gobble()을 필요로 두 개의 단일 알고리즘, FeedBreakfastFeedDinner을 한 경우

는 예를 들어, 상속없이 각 동물 각 알고리즘 를 구현해야합니다 코드의 양! 일반적인 추상 인터페이스를 사용하면 M + N-M 알고리즘과 N 구체적인 클래스로 줄일 수 있으며 어느 쪽도 다른 것을 알아야 할 필요가 없습니다. 둘 다 인터페이스를 알아야합니다.

+0

구현할 클래스의 기능을 기억하기 위해 인터페이스를 만들 것이라고 결론 내릴 수 있습니다. – ScoRpion

+0

@Showket : 단지 기억하기 만하면됩니다. 이는 다른 * 사용자 (자신 포함)에게 계약을 제공하고 구현 세부 정보를 숨겨 관련 정보 *를 노출하기 만하면됩니다. 이것은 추상적 인 인터페이스의 사용자가 당신의 구현을 알지 못하고 그것에 따라 시작할 수 없다는 것을 의미합니다. 그래서 나중에 구체적인 클래스를 리펙토링하려는 경우 기존 코드를 깨뜨릴 필요가 없습니다. 공개 인터페이스는 가능한 한 작게 유지해야하며 앞으로 * 인터페이스 * 만 보증하면됩니다. –

+0

정말 고마워. 고마워. 인터페이스가 어떻게 양을 줄이는 지 설명해주세요. (M + N - M) – ScoRpion

1

정적 형식의 언어는 다형성을 사용하려면이 메서드를 사용해야합니다. 즉, 추상 기본 클래스의 측면에서 코드를 작성할 수 있습니다. 그런 다음 모든 하위 클래스를 확장으로 "플러그"할 수 있습니다. 이를 Liskov Substitution principle 또는 Open/Closed principle이라고합니다. 기술적으로 이것은 dynamic binding입니다. 즉, 호출 할 메소드는 서브 클래스에 따라 런타임 중에 선택됩니다.

동적 유형 지정 언어의 상황은 완전히 다릅니다. PHP가 동적으로 입력되었는지는 모르겠지만 Ruby 나 Javascript에서는 특정 인터페이스를 준수하는 의 객체를 프로그래밍 할 수 있습니다 (). 즉, 코드에서 Print라는 메서드가있는 개체를 예상하는 경우 공통 기본 클래스에서 파생하지 않고 Print 메서드도있는 다른 개체로 대체 할 수 있습니다. 이 메서드는 런타임 중에 조회 될 것이므로이 언어는 "dynamic"입니다.

희망이 도움이됩니다.

+0

자바 스크립트는 다른 동물입니다. 객체 모델이 프로토 타입 기반이고 클래스 기반이 아니기 때문입니다. PHP (더 좋든 나쁘 든) PHP와 같은 클래스 기반 OO 언어의 경우 인터페이스는 구현보다 설계상의 문제이므로 동적 타이핑은 강력한 주장을하지 않습니다. –

1

protocol을 설정하려면 추상 클래스 또는 인터페이스를 사용합니다.

간단하게 들리지만 아주 강력한 개념입니다. 규칙을 지키도록 강요 당하면 규칙을 어길 수 없습니다. 규칙을 위반할 수없는 경우 프로토콜을 준수해야합니다. 따라서 인터페이스를 구현하는 모든 클래스는 본질적으로 서로 호환되어야합니다.당연히 예외적으로 해석자가 해석해야 할 때 울어도 코드를 생성하여 이러한 규칙을 위반할 수있는 예외가 있습니다. 그러나 그 이유는 다소 불투명합니다.

1

인터페이스의 경우 클래스가 있다고 상상해보십시오. "메시지". 이 메소드는 Send 메소드 정의가있는 SendMessage라는 인터페이스를 구현합니다.

"Message"라는 두 개의 하위 클래스를 만드는 경우. 하나는 "이메일"이고 하나는 "InstantMessage"일 수 있습니다.

이 두 가지 모두 SendMessage 인터페이스에 정의 된 Send() 메소드를 가지며 비어 있습니다. 이제 Send() 메소드가하는 일을 다르게 정의 할 수 있습니다. 그러나 Email 클래스와 InstantMessage 클래스가 SendMessage 인터페이스를 사용한다는 것을 알기 때문에 둘 다 Send() 메소드를 가지고 있습니다.

그래서 Email.Send() 및 InstantMessage.Send()를 호출 할 수 있지만 두 가지 작업을 수행 할 수 있습니다. 인터페이스는 여러 객체에서 사용할 수있는 메소드를 정의하지만 동일한 메소드 이름을 사용합니다.

+0

그래서 내가 직접 메쏘드 클래스를 내부 또는 하위 클래스로 보내고 인터페이스를 구현하는 방법을 만든 다음 동일한 메소드를 사용하여 동일한 메소드를 정의 할 수 있습니다. – ScoRpion

+0

이것은 일종의 프레임 워크를 정의합니다. 코드의 한 비트 (Email 클래스)를 작성하고 다른 누군가가 InstantMessage 클래스를 작성할 수 있습니다. 하지만 그들은 둘 다 .Send() 메소드 식별자를 공유하지만, Send 메소드는 서로 다른 두 가지 일을하기 때문에 다른 내부 구조를 가질 가능성이 큽니다. Send() 메서드가 두 클래스 모두에서 똑같은 작업을 수행하기를 원한다면 상속을 사용합니다. 예 이러한 클래스 내에 자신의 비 인터페이스 메소드를 작성할 수 있지만 인터페이스는 메소드 이름의 엄격한 정의를 허용합니다. – Davos555

+0

그들이 취하는 매개 변수와 반환 값은 무엇입니까? 다른 프로그래머도 인터페이스 정의를보고이 인터페이스를 구현하는 모든 클래스에 이러한 메소드가 있음을 알 수 있습니다. – Davos555

1

추상 클래스/인터페이스는 대부분 디자인 타임을 고려해야합니다. 메소드를 추상 클래스로 정의함으로써 클래스를 추상적으로 정의함으로써 클래스를 파생시킴으로써 이러한 메소드가 확실히 구현되도록합니다. 그들이 구현하지 않으면 추상이됩니다.

인터페이스는 필요한 메소드를 구현할 수 있도록 필요한 메소드를 다른 카테고리에 구현할 수있는 방법을 제공합니다.

1

추상 클래스는 인스턴스화 할 수 없다는 것을 보장합니다. 이는 일반화 때문입니다. 예를 들어, 게임에서 , 클래스 플레이어가 존재하지만, 또한 클래스 수비수와 앞으로 존재합니다. 클래스 플레이어는 두 클래스 모두의 부모 클래스입니다. 팀이 특별한 플레이어를 필요로하기 때문에 연습은 오브젝트 플레이어를 만드는 것이 아닙니다.

인터페이스는 다형성과 관련이 있습니다. 모든 클래스는 그 동작에 따라 메서드를 사용합니다.

내가이 도움말을 희망 당신

1

추상 클래스 뒤에 아이디어는 비슷한 클래스 집합의 몇 가지 일반적인 기능을 정의하지만, 구현 (확장) 클래스까지 기타 세부 사항을 떠날 수 있다는 것입니다. 어떤면에서는 인터페이스와 비슷하지만 추상 클래스에서 일부 기능을 실제로 구현할 수 있다는 점만 다릅니다.

하지만 요점은 무엇입니까? 글쎄, 당신은 한번만 공통 코드를 작성해야한다. 비록 당신이 concrete (비 abstract) 기본 클래스에서도 그렇게 할 수있다. 그러나 다른 프로그래머가 기본 클래스를 인스턴스화하는 것을 원하지 않을 수도 있으므로 여기가 추상 클래스의 진정한 힘이 들어오는 곳입니다.

요점을 설명하는 예제를 보여 드리겠습니다. 동물원에있는 모든 동물을 분류하는 프로그램을 작성한다고 상상해보십시오. 동물은 조류, 파충류, 포유 동물, 곤충, 거미류, 물고기 등의 특정 유형으로 분류 할 수 있으며, 개, 고양이, 앵무새 또는 ​​캥거루와 같은 동물의 종으로 분류 할 수 있습니다. 기본 클래스 인 Animal은 이러한 모든 기능에 공통적 인 기능을 제공 할 수 있습니다. 모든 동물이 비슷한 방식으로하는 함수 인 eat()이라는 함수가있을 수 있으므로 함수는 동물이 먹는 과정을 설명하기 위해 작성됩니다. 그것은 다른 함수 walk()를 포함 할 수 있습니다. 그러나 이것은 다른 동물들이 이것을 다른 방식으로 구현할 것이기 때문에 추상적입니다. Animal 클래스의 모든 서브 클래스는이 메소드를 구현해야합니다.

이 코드의 주요 장점은 Animal을 매개 변수로 사용하는 함수를 호출 할 수 있다는 것입니다. 모든 동물들이 먹고 걸을 수 있기 때문에이 매개 변수에 대해 eat() 및 walk() 함수를 호출 할 수 있다는 것을 알고 있습니다.이를 다형성 (polymorphism)이라고하며, 객체 지향 프로그래밍의 중요한 특징입니다.

도움이 되었기를 바랍니다. 여전히 추상적 인 수업의 가치를 볼 수 없다면 자유롭게 토론하거나 질문하십시오.

관련 문제