2010-02-18 5 views
11

PHP에서 OOP를 배우려고하는데 인터페이스와 추상 클래스에 대해 혼란스러워합니다. 둘 다 구현이없고 정의 만 포함되어 있으며 하위 클래스를 통해 구현해야합니다. 추상 클래스의 어떤 부분이 인터페이스와 인터페이스를 명확하게 구분합니까? 또한, 겉보기 유사성으로 인해 어떤 이유로 다른 것을 사용할지 결정해야합니다.추상 클래스의 목적은 무엇입니까?

답변

6

그것은 이러한 방법 또는 속성 콘크리트 멤버를 포함 추상 클래스를 만들 수 있습니다. 여전히 추상 클래스를 직접 인스턴스화 할 수는 없지만 모든 인스턴스화 된 하위 클래스는 추상 클래스에 정의 된 구현 된 멤버의 이점을 누릴 수 있습니다.

인터페이스에는 비교 로직이 포함되어 있지 않습니다. 인터페이스에 정의 된 모든 구성원의 구현을 제공하는 것은 각 구현 클래스에 달려 있습니다.

차이점을 보는 방법에 따라 추상 클래스의 하위 클래스는 클래스입니다. 예 : DogAnimal입니다. 내가 - 관계로 인터페이스를 참조하십시오. 예 : ICanDisplayImages은 구현 클래스가 이미지를 표시 할 수 있지만 클래스가 실제로 무엇을 나타내는 지 알려주지 않습니다.

+0

클래스에 구현이 없으면 하위 클래스에 명확하게 어떤 목적으로 제공됩니까? ...? – SpikETidE

+6

구현 방식을 표준화합니다. 예를 들어, 데이터베이스 어댑터 인터페이스는 구현해야하는 메소드를 정의 할 수 있습니다. 사용자는 하나의 어댑터를 다른 어댑터로 바꿀 수 있고 인터페이스가 동일하기 때문에 작동하도록 기대할 수 있습니다. –

+0

또한 하위 클래스가 될 수있는 모든 클래스와 마찬가지로 하위 클래스가 자체 하위 클래스를 제공하지 않아도 모든 하위 클래스에 기능을 제공 할 수 있습니다. –

0

추상 클래스는 메소드가 추상으로 정의되지 않은 경우 메소드 구현을 포함 할 수 있습니다. 메소드가 추상으로 정의 된 경우 구현을 포함하지 않지만 상속자가 구현해야합니다. 추상 클래스는 상속자가 자신의 행동을 사용할 수 있도록 인스턴스화 할 수는 없지만 상속 만합니다.

인터페이스는 메서드 시그니처 만 정의하며이 메서드 시그니처를 상속하는 모든 클래스는 인터페이스에 포함 된 모든 메서드를 구현해야합니다.

3

그들은 모두 어떤 구현을 포함하지 ..

추상 클래스는 전부 또는 방법의 일부를 구현 할 수 있습니다. 그러나 기본 철학은 하위 클래스 (기본 기능을 확장)에 새 메서드를 추가하기 위해 기존 추상 클래스를 확장하는 것입니다.

하위 클래스에서는 하나의 클래스 (추상 클래스) 만 확장 할 수 있습니다. 추상 클래스는 구현해야하는 기능을 정의하거나 하위 클래스의 다른 메소드로 확장합니다.

인터페이스는 클래스 비헤이비어를 정의하는 데 사용됩니다. 하나 이상의 추상 클래스를 확장 할 수 있지만 하나 이상의 인터페이스를 구현할 수 있습니다. interface는 다음과-A 관계를 생성하면서

4

abstract 클래스는 자체 서브 클래스 간의 관계 형성-A이다. 따라서 추상 클래스는 인터페이스보다 훨씬 구체적이며 콘크리트 구현 (예 : Template methods)을 포함 할 수 있지만 인터페이스는 구현 클래스가 따라야하는 계약상의 일련의 메소드를 정의합니다. 구현 클래스가 추상 클래스 일 필요는 없으므로 훨씬 더 추상화 된 수준입니다. 이를 사용하여 API를 표준화하십시오.

관련 질문 : https://stackoverflow.com/search?q=abstract+vs+interface

3

다른 답변에서 설명한 OOP 철학 이외에도 추상 클래스의 주요 용도는 일종의 해골이라고 생각합니다.

응용 프로그램을 설계하거나 팀과 함께 작업 할 때 유용합니다. 작업 할 기본 코드가 있고 인터페이스와 비슷하지만 확장 된 워크 플로우로 확장 되었기 때문입니다.

0

일반적으로 인터페이스는 계약을 정의하는 데 사용되므로 유형을 확인할 수 있습니다. "인터페이스에 대한 프로그래밍"이라는 프로그래밍 스타일도 있습니다. 이는 좋은 아이디어입니다. Dependency Inversion Principle :

A를 참조하십시오. 상위 모듈은 하위 모듈에 종속되어서는 안됩니다. 둘 다 추상화에 의존해야합니다.

B. 추상화는 세부 사항에 의존해서는 안됩니다. 자세한 사항은 추상화에 의존해야한다. "

을 그래서 당신은 기능 및 방법, 대신 클래스에 대한 type hinting를 정의하는 경우, 당신은 단지 인터페이스에 대한 힌트. 여기

은 예입니다.의 말을하자, 당신은 입력 인터페이스를 정의 스트림 및 출력 스트림을 다음과 같이

interface OutputStream{ 
    write($string); // Writes a string to the output. 
    close(); // Closes the output stream. 
} 

interface InputStream{ 
    read($length); // Reads at most $length characters. 
    eof(); // TRUE, if the input stream is empty. 
} 

이제 copy 함수 또는 방식을 만들 수있는 어떤 복사본 그들없이 입력에 스트림의 전체 출력 :

,
// 50 is just chosen randomly. 
function copy(InputStream $input, OutputStream $output){ 
    while(!$input->eof()){ 
    $output->write($input->read(50));}} 

축하합니다, 당신의 copy 구현은 지금도 하나를 구현하지 않고, 입력 및 출력 스트림의 모든 조합을 사용할 수 있습니다. 반면에 클래스는 완전한 기능 클래스를 구현하지 않고도 공통 기능을 구현하는 데 사용할 수 있습니다.

또 다시 예입니다. 출력 스트림을 원한다고 가정 해 보겠습니다. 출력에 문자열을 쓰는 메서드 write($s)이 필요하며 문자열과 추가 줄 바꿈을 출력에 쓰는 메서드 writeLine($s)이 필요합니다. 그런 다음이 적절할 것 :

abstract class AbstractOutputStream{ 
    public function writeLine($s){ 
    $this->write($s."\n");}} 

콘크리트 출력 스트림 이제 추상적 출력 스트림에서 상속 수있는, 단지 write를 구현하고 무료 writeLine를 얻을!

1

추상 클래스와 인터페이스 간의 주요 차이점은 인터페이스가 상속을위한 기초 클래스 인 공용 동작을 정의한다는 것입니다. 즉, 추상 클래스는 하위 클래스가 공유 할 수있는 몇 가지 핵심 메서드 및 속성 집합을 정의합니다. 라이센스를 정의하는 클래스를 고려하십시오. 모든 라이센스에는 특정 유형의 ID 번호가 있으며 일부 개인 또는 그룹에게 발행됩니다. 라이센스 클래스는 운전 면허증 클래스, 자전거 라이센스 클래스 및 헌팅 라이센스 클래스 등으로 확장 될 수 있습니다. 라이센스 클래스를 추상적으로 만드는 주된 이유는 라이센스의 추상 아이디어를 정의하기 때문입니다. 라이센스와 같은 것은 없으므로 클래스 추상을 선언함으로써 인스턴스화 할 수 없습니다.
인터페이스는 개체를 전혀 정의하지 않습니다. 메소드 서명을 정의합니다. 인터페이스를 구현하는 비 추상 클래스는 인터페이스의 모든 메소드에 대한 구현을 제공해야합니다. 여기서 이점은 다른 유형의 객체 (예 : 객체)에 공통 인터페이스를 제공한다는 것입니다. compareTo()는 String 또는 다른 객체와 함께 사용할 때 동일하게 보입니다.

+0

코드 예제를 추가하여 명확하게 만들 수도 있습니다. – nakashu

관련 문제