답변:
시스템 (자체 포함)에서 작업하는 개발자가 빌드 할 클래스에서 일련의 메소드를 구현하도록하려면 인터페이스를 사용하십시오.
당신이 당신의 시스템에서 작업하는 개발자를 강제로 할 때 추상 클래스를 사용하여 메소드 세트 번호를 구현하기 위해 (자신을 포함) 및 당신은 그들의 자식 클래스를 개발하는 데 도움이됩니다 몇 가지 기본 방법을 제공하고자합니다.
명심해야 할 또 다른 사항은 클라이언트 클래스는 하나의 추상 클래스 만 확장 할 수있는 반면 여러 인터페이스를 구현할 수 있다는 것입니다. 따라서 추상 클래스에서 행동 계약을 정의하는 경우 각 하위 클래스는 단일 계약 만 준수 할 수 있습니다. 때로는 사용자 프로그래머에게 특정 경로를 따라 가고 싶을 때 좋은 일입니다. 다른 경우에는 나쁠 것입니다. PHP의 Countable 및 Iterator 인터페이스가 인터페이스 대신 추상 클래스인지 상상해보십시오.
(가 언급 한 바와 같이 당신이있는 거 확실 어떤 방법으로 갈 때 흔한 한 가지 방법 은 아래 클리 터스는 ) 인터페이스를 만든 다음 추상 클래스가 인터페이스를 구현하는 것입니다.
의 차이점 Abstract Class
과 Interface
:
추상 클래스
추상 클래스는 수 몇 가지 기능을 제공 하고 파생 클래스의 나머지를 떠나 .
파생 클래스 는 기본 클래스에 정의 된 구체적 함수를 무시하거나 무시할 수 있습니다 .
추상 클래스에서 확장 된 자식 클래스는 논리적으로 관련되어야합니다.
상호 작용
인터페이스 에는 기능이 포함될 수 없습니다 . 그것은 단지 방법의 정의가 포함되어 있습니다.
파생 된 클래스는 반드시 인터페이스에 정의 된 모든 메소드에 대한 코드를 제공해야합니다 .
완전히 다른 클래스와 관련이없는 클래스는 인터페이스를 사용하여 논리적으로 그룹화 할 수 있습니다.
abstract class X implements Y
와 class X implements Y
?
abstract class X implements Y
여러분은 X의 대량 기능이 파생 클래스에서 구현되어야하고 추상 클래스와 파생 클래스 모두 Y에 정의 된 함수를 포함해야하고 클래스 X는 Y에 정의 된 함수를 포함해야 함을 선언 합니다class X implements Y
. 인터페이스 Y XI 이외의 다른 클래스에 의해 구현되도록 의도 된 것이 아니며 실제로 Y를 인터페이스로 정의하는 것을 건너 뛰고 Y의 함수를 퍼블릭 / 보호 / 개인 추상 함수로 구현하여 파생 클래스에서 구현되도록합니다.
왜 추상 클래스를 사용해야합니까? 다음은 간단한 예입니다. 다음 코드가 있다고 가정 해 봅시다.
<?php
class Fruit {
private $color;
public function eat() {
// chew
}
public function setColor($c) {
$this->color = $c;
}
}
class Apple extends Fruit {
public function eat() {
// chew until core
}
}
class Orange extends Fruit {
public function eat() {
// peeling
// chew
}
}
이제 나는 사과를주고 당신은 그것을 먹습니다. 어떤 맛이야? 사과 맛이나요.
<?php
$apple = new Apple();
$apple->eat();
// Now I give you a fruit.
$fruit = new Fruit();
$fruit->eat();
그 맛은 어때? 글쎄, 그건 말이되지 않으므로 그렇게 할 수 없어야합니다. 이것은 Fruit 클래스를 추상적이고 내부의 eat 메소드로 만들어서 수행됩니다.
<?php
abstract class Fruit {
private $color;
abstract public function eat(){}
public function setColor($c) {
$this->color = $c;
}
}
?>
추상 클래스는 인터페이스와 비슷하지만 추상 클래스에서 메소드를 정의 할 수 있지만 인터페이스에서는 모두 추상입니다. 추상 클래스는 빈 메소드와 작동하는 / 콘크리트 메소드를 모두 가질 수 있습니다. 인터페이스에서 정의 된 함수는 본문을 가질 수 없습니다. 추상 수업에서는 가능합니다.
실제 예 :
<?php
abstract class person {
public $LastName;
public $FirstName;
public $BirthDate;
abstract protected function write_info();
}
final class employee extends person{
public $EmployeeNumber;
public $DateHired;
public function write_info(){
//sql codes here
echo "Writing ". $this->LastName . "'s info to emloyee dbase table <br>";
}
}
final class student extends person{
public $StudentNumber;
public $CourseName;
public function write_info(){
//sql codes here
echo "Writing ". $this->LastName . "'s info to student dbase table <br>";
}
}
///----------
$personA = new employee;
$personB = new student;
$personA->FirstName="Joe";
$personA->LastName="Sbody";
$personB->FirstName="Ben";
$personB->LastName="Dover";
$personA->write_info();
// Writing Sbody's info to emloyee dbase table
$personB->write_info();
// Writing Dover's info to student dbase table
What does that taste like? Well, it doesn't make much sense, so you shouldn't be able to do that.
이제 초록을 알고 있습니다!
final
할 키워드? 좋은 포스트, 감사합니다.
이것을 믹싱에 던지기 위해 Cletus가 추상 클래스와 함께 인터페이스를 사용한다고 언급했듯이, 나는 종종 인터페이스를 사용하여 디자인 사고를 명확히합니다.
예를 들어 :
<?php
class parser implements parserDecoratorPattern {
//...
}
이렇게하면 내 코드를 읽는 사람 (및 데코레이터 패턴이 무엇인지 아는 사람)은 a) 내 파서를 작성하는 방법과 b) 데코레이터 패턴을 구현하는 데 사용되는 방법을 알 수 있습니다.
또한 Java / C ++ / etc 프로그래머가 아닌 기본이 될 수 있지만 여기에서 데이터 유형을 사용할 수 있습니다. 당신의 객체는 유형이며, 당신이 객체를 전달할 때 프로그래밍 방식으로 문제가됩니다. 계약 가능 항목을 인터페이스로 이동하면 메소드가 리턴하는 유형 만 지시하지만이를 구현하는 클래스의 기본 유형은 아닙니다.
늦었고 더 나은 의사 코드 예제를 생각할 수는 없지만 다음과 같습니다.
<?php
interface TelevisionControls {};
class Remote implements TelevisionControls {};
class Spouse implements TelevisionControls {};
Spouse spouse = new Spouse();
Remote remote = new Remote();
isSameType = (bool)(remote == spouse)
또한 다른 OO 언어에 일종의 인터페이스와 추상화가 있다고해서 PHP와 동일한 의미와 목적을 갖는 것은 아닙니다. PHP의 인터페이스에는 실제로 실제 기능이 없지만 추상화 / 인터페이스 사용은 약간 다릅니다. 시맨틱 및 스킴 관련 이유로 사용됩니다. 요점은 개발자가 나중에 완전히 다른 사용 계획을 가지고 있는지 여부에 관계없이 향후 확장을 위해 가능한 한 유연하고 확장 가능하며 안전한 프로젝트를 만드는 것입니다.
영어가 모국어가 아닌 경우 추상화 및 인터페이스가 실제로 무엇인지 찾아 볼 수 있습니다. 동의어도 찾으십시오.
그리고 이것은 당신을 은유로 도울 수 있습니다.
상호 작용
딸기로 새로운 종류의 케이크를 굽고 재료와 단계를 설명하는 레시피를 만들었습니다. 왜 맛이 좋으며 손님이 좋아하는지 알 수 있습니다. 그런 다음 다른 사람들도 그 케이크를 맛볼 수 있도록 레시피를 게시하기로 결정했습니다.
여기 요점은
-제대로 만들기 위해
-조심스럽게
-너무 많은 딸기 나 다른 것들과 같이 나빠질 수있는 것들을 막기 위해
-그것을 시도하는 사람들을 위해 쉽게 유지하기
-얼마나 오래해야 할지를 말해주는 것 )
-할 수 있지만 할 수없는 일을 말하십시오.
정확하게 THIS는 인터페이스를 설명합니다. 가이드, 레시피의 내용을 관찰하는 일련의 지침입니다. PHP로 프로젝트를 생성하고 GitHub 또는 동료와 함께 코드를 제공하려는 경우와 동일합니다. 인터페이스는 사람들이 할 수있는 것과하지 말아야 할 것입니다. 그것을 지키는 규칙-하나를 불순종하면 전체 구조물이 파손됩니다.
추출
여기에서이 은유를 계속하려면 ... 이번에는 그 케이크를 먹는 손님이라고 상상해보십시오. 그럼 당신은 지금 레시피를 사용하여 그 케이크를 시도하고 있습니다. 그러나 레시피에 설명 된 단계를 새 재료를 추가하거나 변경 / 건너 뛰기를 원합니다. 그럼 다음은 무엇입니까? 그 케이크의 다른 버전을 계획하십시오. 이번에는 스트로 베리가 아닌 검은 딸기와 더 많은 바닐라 크림이 있습니다.
이것이 원래 케이크의 확장을 고려할 수있는 것입니다. 기본적으로 릴과 다르기 때문에 새로운 레시피를 생성하여 추상화를 수행합니다. 몇 가지 새로운 단계와 다른 재료가 있습니다. 그러나 블랙 베리 버전에는 원본에서 가져온 부분이 있습니다. 이것은 모든 종류의 케이크가 가져야하는 기본 단계입니다. 우유처럼 재료처럼-그것은 모든 파생 클래스가 가진 것입니다.
이제 재료와 단계를 교환하고 싶다면 반드시 그 케이크의 새 버전에서 정의해야합니다. 이것들은 새로운 케이크에 대해 정의되어야하는 추상적 인 방법 입니다. 케이크에 과일이 있어야하는데 어떤 것이 있습니까? 이번에는 검은 딸기를 먹습니다. 끝난.
거기에서 케이크를 확장하고 인터페이스와 추상 단계 및 재료를 따랐습니다.
이미 훌륭한 답변 중 일부에 추가하려면 다음을 수행하십시오.
추상 클래스를 사용하면 어느 정도의 구현을 제공 할 수 있으며 인터페이스는 순수한 템플릿입니다. 인터페이스는 기능 만 정의 할 수 있으며 구현할 수 없습니다.
인터페이스를 구현하는 모든 클래스는 자신이 정의한 모든 메소드를 구현하기 위해 커밋하거나 추상으로 선언해야합니다.
인터페이스는 Java와 같이 PHP가 다중 상속을 지원하지 않는다는 사실을 관리하는 데 도움이 될 수 있습니다. PHP 클래스는 단일 부모 만 확장 할 수 있습니다. 그러나 원하는만큼 인터페이스를 구현하도록 클래스 약속을 할 수 있습니다.
type : 구현하는 각 인터페이스마다 클래스가 해당 유형을 사용합니다. 모든 클래스는 인터페이스 (또는 더 많은 인터페이스)를 구현할 수 있으므로 인터페이스는 관련이없는 유형을 효과적으로 조인합니다.
클래스는 수퍼 클래스를 확장하고 여러 인터페이스를 구현할 수 있습니다.
class SubClass extends ParentClass implements Interface1, Interface2 {
// ...
}
인터페이스를 사용해야 할 때와 추상 클래스를 사용해야 할 때를 알려주세요.
구현이없는 템플릿 만 제공해야하는 경우 인터페이스를 사용하고 해당 인터페이스를 구현하는 모든 클래스가 해당 클래스를 구현하는 다른 클래스와 동일한 메서드를 갖도록해야합니다.
다른 객체 (부분적으로 빌드 된 클래스)의 기초를 만들려면 추상 클래스를 사용하십시오. 추상 클래스를 확장하는 클래스는 정의 / 구현 된 일부 속성 또는 메서드를 사용합니다.
<?php
// interface
class X implements Y { } // this is saying that "X" agrees to speak language "Y" with your code.
// abstract class
class X extends Y { } // this is saying that "X" is going to complete the partial class "Y".
?>
추상 클래스를 인터페이스로 변경하려면 어떻게해야합니까?
다음은 간단한 사례 / 예입니다. 구현 세부 사항을 모두 제거하십시오. 예를 들어, 추상 클래스를 다음에서 변경하십시오.
abstract class ClassToBuildUpon {
public function doSomething() {
echo 'Did something.';
}
}
에:
interface ClassToBuildUpon {
public function doSomething();
}
철학적 관점에서 :
추상 클래스는 "is"관계를 나타냅니다. 과일을 가지고 있다고하자. 일반적인 책임과 행동을 공유하는 과일 추상 클래스가 있습니다.
인터페이스는 "해야 할"관계를 나타냅니다. 내 의견으로는 (주니어 개발자의 의견 인) 인터페이스는 행동 또는 행동과 가까운 것으로 이름을 붙여야합니다 (죄송합니다, 나는 영어를 모국어로 사용하지 않습니다) IEatable이라고 말하십시오. 당신은 그것이 먹을 수 있다는 것을 알고 있지만, 당신이 무엇을 먹는지 모릅니다.
코딩 관점에서 :
객체에 코드가 중복 된 경우 이는 일반적인 동작이 있음을 나타내므로 인터페이스를 사용하여 코드를 재사용 할 수없는 추상 클래스가 필요할 수 있습니다.
또 다른 차이점은 객체가 필요한만큼 많은 인터페이스를 구현할 수 있지만 "다이아몬드 문제"로 인해 하나의 추상 클래스 만 가질 수 있다는 것입니다 (이유를 확인하려면 여기를 확인하십시오! http://en.wikipedia.org/wiki/ Multiple_inheritance # The_diamond_problem )
아마도 몇 가지 요점을 잊었을 수도 있지만, 명확하게 이해할 수 있기를 바랍니다.
추신 : "는"/ "해야한다"는 Vivek Vermani의 답변에 의해 가져옵니다. 나는 그의 답변을 훔치려는 것이 아니 었습니다.
추상 클래스와 인터페이스의 기술적 차이점은 이미 다른 답변에 정확하게 나와 있습니다. 객체 지향 프로그래밍을 위해 코드를 작성하면서 클래스와 인터페이스 중에서 선택하는 설명을 추가하고 싶습니다.
클래스는 엔티티를 나타내야하지만 인터페이스는 동작을 나타냅니다.
예를 들어 봅시다. 컴퓨터 모니터는 엔터티이며 클래스로 표현해야합니다.
class Monitor{
private int monitorNo;
}
디스플레이 인터페이스를 제공하도록 설계되었으므로 기능은 인터페이스로 정의해야합니다.
interface Display{
void display();
}
다른 답변에서 설명한 것처럼 고려해야 할 다른 것들이 많이 있지만, 이것이 코딩하는 동안 대부분의 사람들이 무시하는 가장 기본적인 것입니다.
PHP
둘 다 사용해야 할 때의 예를 추가하고 싶었습니다. 현재 범용 ERP 솔루션에서 데이터베이스 모델에 바인딩 된 파일 핸들러를 작성 중입니다.
이런 식으로, 서로 다른 파일을위한 여러 템플릿과 명확한 구별을 가진 공통 인터페이스 메소드 세트를 갖게됩니다. 이 인터페이스는 기본 추상 클래스와 달리 액세스 방법에 대한 올바른 비유를 제공합니다.
다른 파일 스토리지 서비스에 대한 어댑터를 만들 때 줄을 따라 가면이 구현을 통해 완전히 다른 컨텍스트에서 인터페이스를 다른 곳에서 사용할 수 있습니다.
abstract
과interface
수업 을 이해하려고 노력했지만 , 당신의 게시물은 그것을 명확하게했습니다. 감사합니다 Alan