> 백엔드 개발 > PHP 문제 > 객체지향의 세 가지 주요 특징과 다섯 가지 주요 원칙은 무엇입니까?

객체지향의 세 가지 주요 특징과 다섯 가지 주요 원칙은 무엇입니까?

步履不停
풀어 주다: 2023-02-23 08:46:01
원래의
3374명이 탐색했습니다.

객체지향의 세 가지 주요 특징과 다섯 가지 주요 원칙은 무엇입니까?

객체지향의 세 가지 주요 특징

캡슐화, 상속, 다형성

무엇인가 캡슐화?

객관적인 것을 추상 클래스로 캡슐화하고, 클래스는 신뢰할 수 있는 클래스나 객체만 데이터와 메서드를 작동하도록 허용하고 신뢰할 수 없는 클래스에는 정보를 숨길 수 있습니다. 간단히 말하면, 캡슐화는 객체의 디자이너와 객체의 사용자를 분리합니다. 사용자는 객체가 무엇을 할 수 있는지 알 필요가 있고 구현 방법을 알 필요는 없습니다. 캡슐화는 클래스 및 시스템 보안을 향상시키는 데 도움이 될 수 있습니다.

상속이란 무엇인가요?

상속은 이전에 정의된 하나 이상의 클래스에서 데이터와 기능을 상속하는 새로운 파생 클래스를 만드는 것을 의미하며, 이를 통해 새로운 데이터와 기능을 재정의하거나 추가할 수 있습니다. 설립되었습니다.

다형성이란 무엇인가요?

다형성은 다음을 의미합니다. 서로 다른 클래스의 인스턴스에서 수행되는 동일한 작업이 서로 다른 실행 결과를 생성합니다. 즉, 서로 다른 클래스의 객체가 동일한 메시지를 받으면 서로 다른 결과를 얻게 됩니다. 결과.

코드 예

class eat
{
    public function breakfast()
    {
        echo "吃早饭!";
    }
}

class typist
{
    public function type()
    {
        echo "打字!";
    }

}

function printWorking($obj)
{
    if ($obj instanceof eat) {
        echo $obj->breakfast();
    } elseif ($obj instanceof typist) {
        echo $obj->type();
    } else {
        echo "error";
    }
}

printWorking(new eat());
echo PHP_EOL;
printWorking(new typist());
로그인 후 복사

출력:

아침 식사하세요! 타이핑!

객체지향의 5가지 원칙

단일 책임 원칙, 개방형 및 폐쇄형 원칙, Liskov 대체 원칙, 종속성 반전 원칙, 인터페이스 격리 원칙

#🎜 🎜 #

단일 책임 원칙이란 무엇인가요?

간단히 말하면, 클래스는 한 가지 일만 하고, 클래스에 너무 많은 기능적 포인트를 구현하지 않으며, 동일한 책임을 다른 클래스에 분산시키는 것을 피합니다. 클래스에 책임이 너무 많으면 변경 이유가 많아져 코드가 더 결합될 수 있습니다. 책임이 혼합되고 불분명하면 코드 유지 관리가 어려워지고 전체에 영향을 미치게 됩니다.

예: 팩토리 패턴. 팩토리 패턴이라고 불리는 이유는 객체를 "생산"하는 역할을 담당하기 때문입니다.

코드 예시

팩토리 패턴의 장점: 객체는 여러 위치에서 새로운 이름이므로 하나씩 수정할 필요가 없습니다. 한 곳만 수정하면 됩니다.

<?php
class MyObject
{
    public function __construct()
    {
        echo "test code";
    }
}

//工厂类
class MyFactory
{
    public static function factory()
    {
        return new MyObject();
   }
}

$instance = MyFactory::factory();//test code
로그인 후 복사

개방-폐쇄 원칙이 무엇인가요?

개방 및 폐쇄 원칙: 클래스는 확장 가능하지만 수정할 수는 없습니다. 즉, 확장에는 열려 있고 수정에는 닫혀 있습니다.

1. 확장을 위한 개방형은 새로운 요구 사항이나 변경 사항이 있을 때 기존 코드를 새로운 상황에 맞게 확장할 수 있다는 의미입니다.

2. 모듈 기능 확장 시 기존 프로그램 모듈에 영향을 주지 않아야 합니다.

개방성과 폐쇄성의 원칙을 구현하는 핵심: 구체적인 프로그래밍이 아닌 추상 프로그래밍, 추상화는 상대적으로 안정적이고 클래스를 고정된 추상 클래스 및 인터페이스에 종속시키므로 수정이 폐쇄되기 때문입니다. 객체 지향 상속 및 다형성 메커니즘의 경우 추상 클래스를 상속하거나 인터페이스를 구현할 수 있으며 해당 메서드를 다시 작성하여 고유 동작을 변경하고 메서드의 새로운 확장을 구현할 수 있으므로 개방적입니다.

예: 데코레이터 모드(Decorator)는 클래스의 기능을 동적으로 추가하고 수정할 수 있습니다. 클래스는 함수를 제공합니다. 기존 프로그래밍 모드에서는 함수를 수정하고 추가하기 위해 하위 클래스를 작성하고 데코레이터 모드를 사용하면 런타임에만 추가하면 됩니다. . 이는 단일 데코레이터 객체로 구현될 수 있으므로 유연성이 극대화됩니다.

<?php

/**
 * 输出一个字符串
 * 装饰器动态添加功能
 * Class EchoText
 */
class EchoText
{
    protected $decorator = [];

    public function Index()
    {
        //调用装饰器前置操作
        $this->beforeEcho();
        echo "你好,我是装饰器。";
        //调用装饰器后置操作
        $this->afterEcho();
    }

    //增加装饰器
    public function addDecorator(Decorator $decorator)
    {
        $this->decorator[] = $decorator;
    }

    //执行装饰器前置操作 先进先出原则
    protected function beforeEcho()
    {
        foreach ($this->decorator as $decorator)
            $decorator->before();
    }

    //执行装饰器后置操作 先进后出原则
    protected function afterEcho()
    {
        $tmp = array_reverse($this->decorator);
        foreach ($tmp as $decorator)
            $decorator->after();
    }
}

/**
 * 装饰器接口
 * Class Decorator
 */
interface Decorator
{
    public function before();

    public function after();
}

/**
 * 颜色装饰器实现
 * Class ColorDecorator
 */
class ColorDecorator implements Decorator
{
    protected $color;

    public function __construct($color)
    {
        $this->color = $color;
    }

    public function before()
    {
        echo "<dis style=&#39;color: {$this->color}'>";
    }

    public function after()
    {
        echo "</div>";
    }
}

/**
 * 字体大小装饰器实现
 * Class SizeDecorator
 */
class SizeDecorator implements Decorator
{
    protected $size;

    public function __construct($size)
    {
        $this->size = $size;
    }

    public function before()
    {
        echo "<dis style=&#39;font-size: {$this->size}px'>**";
    }

    public function after()
    {
        echo "</div>";
    }
}

//实例化输出类
$echo = new EchoText();
//增加装饰器
$echo->addDecorator(new ColorDecorator('red'));
//增加装饰器
$echo->addDecorator(new SizeDecorator('22'));
//输出
$echo->Index();
로그인 후 복사

리히터 치환 원리란 무엇인가요?

객체지향 프로그래밍 기술에서의 상속은 특정 프로그래밍에서 너무 단순하기 때문에, 많은 시스템의 설계와 프로그래밍 구현에 있어서 우리는 객체지향 프로그래밍의 다양한 측면에 대해 진지하고 합리적으로 생각하지 않습니다. 응용 프로그램 시스템 클래스 간의 상속 관계가 적절한지, 파생 클래스가 기본 클래스의 특정 메서드를 올바르게 재정의할 수 있는지 여부입니다. 따라서 상속의 남용이나 잘못된 상속이 자주 발생하며, 이는 향후 시스템 유지관리에 많은 어려움을 가져온다.

핵심 아이디어: 하위 클래스는 상위 클래스를 대체할 수 있어야 합니다. 이 아이디어는 상속 메커니즘의 제약 조건 사양에 구현되어 있습니다. 하위 클래스가 상위 클래스를 대체할 수 있는 경우에만 시스템이 런타임 중에 하위 클래스를 인식할 수 있습니다. 이는 상속 재사용을 보장하는 기반입니다.

<?php
//例子1
class Bird{
    protect function fly(){

    }
}
//翠鸟
class KingFisher extends Bird{

}

//鸵鸟
class Ostrich extends Bird{
    //鸵鸟不会飞啊
}

//例子2

class A{
    protect function add($a, $b){
        return $a + $b;
    }
}

//重载
class B extends A{

    protected function add($a, $b){
        return $a + $b + 100;
    }
}
로그인 후 복사

리스코프 대체 원칙은 클래스 상속에 대한 제약입니다. Liskov 대체 원칙에는 두 가지 이해가 있습니다:

1. 중복된 메서드나 속성이 있는 부적절한 클래스를 상속할 수는 없습니다(예제 1).

2. 하위 클래스는 상위 클래스의 기능을 확장할 수 있지만 상위 클래스의 원래 기능을 변경할 수는 없습니다(예 2).

Liskov 대체 원칙에는 다음과 같은 숨겨진 의미가 포함되어 있습니다.

1 하위 클래스는 상위 클래스의 추상 메서드를 구현할 수 있지만 상위 클래스의 비추상 메서드를 재정의할 수는 없습니다.

2. 서브클래스는 고유한 메서드를 추가할 수 있습니다.

3. 하위 클래스의 메서드가 상위 클래스의 메서드를 재정의하는 경우 메서드의 전제 조건(즉, 메서드의 형식 매개변수)은 상위 클래스의 입력 매개변수보다 느슨합니다. 방법.

4. 하위 클래스의 메서드가 상위 클래스의 추상 메서드를 구현할 때 메서드의 사후 조건(즉, 메서드의 반환 값)이 상위 클래스의 사후 조건보다 엄격합니다. .

종속성 역전 원칙이란 무엇인가요?

간단히 말하면, 클래스는 다른 클래스에 의존하도록 강요되어서는 안 됩니다. 각 클래스는 다른 클래스로 대체 가능합니다.

특정 개념:

1. 상위 모듈은 하위 모듈에 의존해서는 안 되며 모두 추상화에 의존해야 합니다(상위 클래스는 하위 클래스에 의존할 수 없습니다. 추상 클래스에 따라 다름).

2.抽象不能依赖于具体,具体应该依赖于抽象。

为什么要依赖接口?因为接口体现对问题的抽象,同时由于抽象一般是相对稳定的或者是相对变化不频繁的,而具体是易变的。因此,依赖抽象是实现代码扩展和运行期内绑定(多态)的基础:只要实现了该抽象类的子类,都可以被类的使用者使用。

<?php

interface employee
{
    public function working();
}

class teacher implements employee//具体应该依赖与抽象
{
    public function working(){
        echo &#39;teaching...&#39;;
    }
}

class coder implements employee
{
    public function working(){
        echo &#39;coding...&#39;;
    }
}

class workA//例子1
{
    public function work(){
        $teacher = new teacher;
        $teacher->working();
    }
}

class workB//例子2
{
    private $e;
    public function set(employee $e){
        $this->e = $e;
    }

    public function work(){
        $this->e->working();
    }
}

$worka = new workA;//workA 依赖于 teacher 类 不符合依赖倒置原则
$worka->work();
$workb = new workB;//workB 不依赖与某个类 既可以注入 teacher 也可以 注入 coder
$workb->set(new teacher());
$workb->work();
로그인 후 복사

在workA(例子1)中,work方法依赖于teacher实现;在workB(例子2)中,work转而依赖抽象,这样可以把需要的对象通过参数传入。上述代码通过接口,实现了一定程度的解耦,但仍然是有限的。不仅是使用接口,使用工厂等也能实现一定程度的解耦和依赖倒置。

在workB中,teacher实例通过set方法传入,从而实现了工厂模式。由于这样的实现仍然是硬编码的,为了实现代码的进一步扩展,把这个依赖关系写在配置文件里,指明workB需要一个teacher对象,专门由一个程序配置是否正确(如所依赖的类文件是否存在)以及加载配置中所依赖的实现,这个检测程序,就称为IOC容器(这里不清楚IOC的小伙伴可以自行谷歌)。

什么是接口隔离原则?

其核心思想是:使用多个小的专门的接口,而不要使用一个大的总接口(只需要关心接口,不需要关心实现)。

接口隔离原则体现在:

1.接口应该是内聚的,应该避免 “胖” 接口。

2.不要强迫依赖不用的方法,这是一种接口污染。

3.表明客户端不应该被强迫实现一些不会使用的接口,应该把胖接口分组,用多个接口代替它,每个接口服务于一个子模块。简单地说,就是使用多个专门的接口比使用单个接口要好很多。

隔离的手段主要有以下两种:
1、委托分离,通过增加一个新的类型来委托客户的请求,隔离客户和接口的直接依赖,但是会增加系统的开销(设计模式中,如:代理模式,策略模式中都用到了委托的概念,好奇的小伙伴可以自行谷歌,这里就不贴代码了)。

2、多重继承分离,通过接口多继承来实现客户的需求,这种方式是较好的。

胖接口的实例说明

<?php
interface Animal{
  public function walk();
  public function speak();
}

//实现狗的一个接口

class Dog implements Animal{
  public function walk(){
    echo "dogs can walk";
  }
  public function speak(){
    echo "dogs can speak";
  }
}

//ok,现在我们想创建一个鱼类,它会游泳,怎么办呢?
//我们必须要修改接口,还会影响到dog类的实现,而fish也需要实现walk和speak方法,如下代码所示:

interface Animal{
  public function walk();
  public function speak();
  public function swim();
}

//修改后的Gog类
class Dog implements Animal{
  public function walk(){
    echo "dogs can walk";
  }
  public function speak(){
    echo "dogs can speak";
  }
  public function swim(){
  }
}

//鱼类
class Fish implements Animal{
  public function walk(){
  }
  public function speak(){
  }
  public function swim(){
    echo "fish can swim";
  }
}
로그인 후 복사

这时Animal接口类就呈现出了”胖“接口的特征了。所谓胖接口其实就是接口中定义了不是所有实现类都需要的方法,就像Animal接口类,有些动物是不会游泳的,有些动物是不会行走的,还有些动物是不会飞的。如果将这些方法都写在一个Animal接口类中,那么后期的扩展和维护简直就是一场灾难。

那么,怎么解决以上问题呢?

很简单,接口细化即可,将Animal接口类拆分成三个接口类,然后用多继承分离接口就ok了。

<?php
interface animalCanSpeak{
  public function speak();
}

interface AnimalCanSwim{
  public function swim();
}

interface animalCanSpeak{
  public function speak();
}

//定义好这几个接口类之后,dog和fish的实现就容易多了

//狗类
class Dog implements animalCanSpeak,animalCanWalk{
  public function walk(){
    echo "dogs can walk";
  }
  public function speak(){
    echo "dogs can speak";
  }
}

//鱼类
class Fish implements AnimalCanSwim{
  public function swim(){
    echo "fish can swim";
  }
}
로그인 후 복사

接口隔离原则(Interface  Segregation Principle, ISP)的概念:使用多个专门的接口,而不使用单一的总接口,即客户端不应该依赖那些它不需要的接口。

在使用接口隔离原则时,我们需要注意控制接口的粒度,接口不能太小,如果太小会导致系统中接口泛滥,不利于维护;接口也不能太大,太大的接口将违背接口隔离原则,灵活性较差,使用起来很不方便。一般而言,接口中仅包含为某一类用户定制的方法即可,不应该强迫客户依赖于那些它们不用的方法。

结语

实践出真理

위 내용은 객체지향의 세 가지 주요 특징과 다섯 가지 주요 원칙은 무엇입니까?의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

관련 라벨:
원천:php.cn
본 웹사이트의 성명
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.
최신 이슈
인기 튜토리얼
더>
최신 다운로드
더>
웹 효과
웹사이트 소스 코드
웹사이트 자료
프론트엔드 템플릿