Heim >Backend-Entwicklung >PHP-Problem >Was sind die drei Hauptmerkmale und fünf Hauptprinzipien der Objektorientierung?

Was sind die drei Hauptmerkmale und fünf Hauptprinzipien der Objektorientierung?

步履不停
步履不停Original
2019-06-21 16:45:393369Durchsuche

Was sind die drei Hauptmerkmale und fünf Hauptprinzipien der Objektorientierung?

Drei Hauptmerkmale der objektorientierten

Kapselung, Vererbung, Polymorphismus

Was ist Kapselung?

Kapseln Sie objektive Dinge in abstrakte Klassen. Klassen können nur vertrauenswürdigen Klassen oder Objekten erlauben, ihre Daten und Methoden zu betreiben und Informationen vor nicht vertrauenswürdigen Klassen zu verbergen. Einfach ausgedrückt: Die Kapselung trennt den Designer des Objekts vom Benutzer des Objekts. Der Benutzer muss nur wissen, was das Objekt tun kann, und muss nicht wissen, wie es implementiert ist. Die Kapselung kann dazu beitragen, die Klassen- und Systemsicherheit zu verbessern.

Was ist Vererbung?

Vererbung bezieht sich auf die Erstellung einer neuen abgeleiteten Klasse, die Daten und Funktionen von einer oder mehreren zuvor definierten Klassen erbt. Sie kann neue Daten und Funktionen neu definieren und so eine Klasse oder Klasse festlegen.

Was ist Polymorphismus?

Polymorphismus bezieht sich auf: Die gleiche Operation, die an Instanzen verschiedener Klassen ausgeführt wird, führt zu unterschiedlichen Ausführungsergebnissen, d. h. wenn Objekte verschiedener Klassen dieselbe Nachricht erhalten, erhalten sie unterschiedliche Ergebnisse.

Codebeispiel

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());

Ausgabe:

Frühstücken! Tippen!

Fünf Prinzipien der Objektorientierung

Einzelverantwortungsprinzip, offenes und geschlossenes Prinzip, Liskov-Substitutionsprinzip, Abhängigkeitsinversionsprinzip, Schnittstellenisolationsprinzip

Was Ist das Prinzip der Einzelverantwortung?

Um es einfach auszudrücken: Eine Klasse macht nur eine Sache, implementiert nicht zu viele Funktionspunkte für die Klasse und vermeidet die Verteilung der gleichen Verantwortlichkeiten auf verschiedene Klassen. Wenn eine Klasse zu viele Verantwortlichkeiten hat, kann es mehr Gründe für Änderungen geben, wodurch der Code stärker gekoppelt wird. Wenn die Verantwortlichkeiten gemischt und unklar sind, wird es schwierig, den Kodex beizubehalten und sich auf den gesamten Körper auszuwirken.

Zum Beispiel: Factory-Muster Der Grund, warum das Factory-Muster Factory-Muster genannt wird, liegt darin, dass es für die „Produktion“ von Objekten verantwortlich ist.

Codebeispiel

Vorteile des Factory-Musters: Ein Objekt ist an mehreren Stellen neu. Wenn sich solche Namen ändern, müssen sie nicht einzeln geändert werden, sondern nur an einer Stelle geändert.

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

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

$instance = MyFactory::factory();//test code

Was ist das Offen-Geschlossen-Prinzip?

Offenes und geschlossenes Prinzip: Eine Klasse ist erweiterbar, kann aber nicht geändert werden. Mit anderen Worten: Es ist offen für Erweiterungen und geschlossen für Änderungen.

1. Offen für Erweiterungen bedeutet, dass bei neuen Anforderungen oder Änderungen der vorhandene Code erweitert werden kann, um ihn an neue Situationen anzupassen.

2. Bei der Erweiterung von Modulfunktionen sind bestehende Programmmodule nicht betroffen.

Der entscheidende Punkt bei der Verwirklichung des Prinzips der Offenheit und Schließung: abstrakte Programmierung statt konkreter Programmierung, da die Abstraktion relativ stabil ist und Klassen von festen abstrakten Klassen und Schnittstellen abhängig macht, sodass Änderungen geschlossen sind. Was die objektorientierten Vererbungs- und Polymorphismusmechanismen betrifft, können Sie abstrakte Klassen erben oder Schnittstellen implementieren, und Sie können ihre Methoden neu schreiben, um das inhärente Verhalten zu ändern und neue Methodenerweiterungen zu implementieren, sodass es offen ist.

Zum Beispiel: Der Dekoratormodus (Decorator) kann die Funktionalität einer Klasse dynamisch hinzufügen und ändern. Wenn Sie im herkömmlichen Programmiermodus eine Funktion ändern und hinzufügen möchten, müssen Sie eine Unterklasse schreiben, um diese zu erben und die Klassenmethode erneut zu implementieren. Im Dekoratormodus müssen Sie sie nur zur Laufzeit hinzufügen . Dies kann mit einem einzigen Dekoratorobjekt implementiert werden, was maximale Flexibilität ermöglicht.

<?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();

Was ist das Richter-Substitutionsprinzip?

Da die Vererbung in der objektorientierten Programmiertechnologie in der spezifischen Programmierung zu einfach ist, denken wir beim Entwurf und der Programmierimplementierung vieler Systeme nicht ernsthaft und rational über die Beziehungen zwischen verschiedenen Klassen in der Anwendung nach Ob die Vererbungsbeziehung angemessen ist und ob die abgeleitete Klasse bestimmte Methoden in der Basisklasse korrekt überschreiben kann. Daher kommt es häufig zu Missbrauch oder falscher Vererbung, was große Probleme bei der späteren Wartung des Systems mit sich bringt.

Kernidee: Unterklassen müssen in der Lage sein, ihre übergeordneten Klassen zu ersetzen. Diese Idee ist in der Einschränkungsspezifikation des Vererbungsmechanismus verankert. Nur wenn die Unterklasse die übergeordnete Klasse ersetzen kann, kann das System die Unterklasse zur Laufzeit erkennen.

<?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;
    }
}

Das Liskov-Substitutionsprinzip ist eine Einschränkung der Klassenvererbung. Es gibt zwei Verständnisse des Liskov-Substitutionsprinzips:

1 Sie können nicht einfach ungeeignete Klassen mit redundanten Methoden oder Attributen erben (Beispiel 1).

2. Unterklassen können die Funktionen der übergeordneten Klasse erweitern, jedoch nicht die ursprünglichen Funktionen der übergeordneten Klasse ändern (Beispiel 2).

Das Liskov-Substitutionsprinzip enthält die folgenden versteckten Bedeutungen:

1. Unterklassen können abstrakte Methoden der übergeordneten Klasse implementieren, jedoch keine nicht-abstrakten Methoden der übergeordneten Klasse überschreiben.

2. Unterklassen können ihre eigenen einzigartigen Methoden hinzufügen.

3. Wenn eine Methode einer Unterklasse eine Methode einer übergeordneten Klasse überschreibt, sind die Voraussetzungen der Methode (d. h. die formalen Parameter der Methode) lockerer als die Eingabeparameter der Methode der übergeordneten Klasse.

4. Wenn eine Methode einer Unterklasse eine abstrakte Methode einer übergeordneten Klasse implementiert, sind die Nachbedingungen der Methode (d. h. der Rückgabewert der Methode) strenger als die der übergeordneten Klasse.

Was ist das Abhängigkeitsinversionsprinzip?

Um es einfach auszudrücken: Eine Klasse sollte nicht gezwungen werden, von einer anderen Klasse abhängig zu sein. Jede Klasse ist durch eine andere Klasse ersetzbar.

Spezifische Konzepte:

1. Das obere Modul sollte nicht vom unteren Modul abhängen, sie alle hängen von einer Abstraktion ab (die übergeordnete Klasse kann nicht von der Unterklasse abhängen, sie alle hängen von der Abstraktion ab). Klasse).

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)的概念:使用多个专门的接口,而不使用单一的总接口,即客户端不应该依赖那些它不需要的接口。

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

结语

实践出真理

Das obige ist der detaillierte Inhalt vonWas sind die drei Hauptmerkmale und fünf Hauptprinzipien der Objektorientierung?. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn