PHP オブジェクト指向プログラミングの 3 つの主要な特徴は、カプセル化、継承、ポリモーフィズムです。この記事ではphp
の3大特徴を紹介します。
カプセル化とは、オブジェクトのメンバープロパティやメンバーメソッドにアクセス修飾子(パブリック(public)、プロテクト(protected)、プライベート(プライベート))を追加し、オブジェクトの内部詳細を可能な限り隠蔽することを目的としています。メンバーの最善の保護
publicとして定義されたクラスメンバーにはどこからでもアクセスできます。 protected として定義されたクラス メンバーは、それ自体、そのサブクラス、およびその親クラスからアクセスできます。プライベートとして定義されたクラスメンバーには、そのメンバーが定義されているクラスからのみアクセスできます
クラス属性は、public、protected、privateのいずれかとして定義する必要があります。 var で定義されている場合、パブリックとみなされます
クラス内のメソッドは、パブリック、プライベート、または保護として定義できます。これらのキーワードが設定されていない場合、メソッドはデフォルトで public になります
継承はよく知られたプログラミング機能であり、PHP のオブジェクト モデルも継承を使用します。継承はクラス、オブジェクト、オブジェクト間の関係に影響します
クラスを拡張すると、サブクラスは親クラスの public メソッドと protected メソッドをすべて継承します。サブクラスが親クラスのメソッドをオーバーライドしない限り、継承されたメソッドは元の機能を保持します
継承は機能設計と抽象化に非常に役立ち、同様のオブジェクトに新しい関数を追加すると、これらの共通関数を書き直す必要がなくなります
クラスの継承
クラスは、宣言内で extends キーワードを使用して、別のクラスのメソッドとプロパティを継承できます。 PHP は多重継承をサポートしていません。クラスは 1 つの基本クラスのみを継承できます
継承されたメソッドとプロパティは、同じ名前で再宣言することでオーバーライドできます。ただし、親クラスがメソッドを定義するときに Final を使用する場合、メソッドをオーバーライドすることはできません
メソッドをオーバーライドするときは、パラメーターの一貫性を保つ必要があります。そうでないと、PHP は E_STRICT レベルのエラー メッセージを発行します。例外はコンストラクターで、オーバーライド時に別のパラメーターを使用できます
サブクラスでは、parentを使用して親クラスのオーバーライドされたプロパティとメソッドにアクセスします
要約
オブジェクト指向言語では、クラスは 1 つ以上のサブクラスを持つことができ、各クラスには外部コードがアクセスするためのインターフェイスとして少なくとも 1 つのパブリック メソッドがあります。継承を容易にするために抽象メソッドが導入されました
クラス内にメソッドがある場合、メソッド本体がなく、中括弧がなく、直接セミコロンで終わっているメソッドを抽象メソッドと呼び、abstractというキーワードを使って定義する必要があります。
このメソッドを含むクラスは抽象クラスである必要があり、キーワードabstractを使用して宣言する必要があります
抽象として定義されたクラスはインスタンス化できません。クラス内の少なくとも 1 つのメソッドが抽象宣言されている場合、クラスは抽象宣言されている必要があります。抽象として定義されたメソッドは、その呼び出しメソッド (パラメーター) を宣言するだけであり、その特定の関数実装を定義することはできません
抽象メソッドの役割は、サブクラスにこのメソッドの実装が必要であることを規定することであり、関数はサブクラスに渡され、実装は特定のサブクラスに任せられます。独自の関数によると、抽象クラス この関数はサブクラスの構造を必要とするため、抽象クラスは仕様です
抽象クラスを継承する場合、サブクラスは親クラスのすべての抽象メソッドを定義する必要があります。さらに、これらのメソッドのアクセス制御は親クラスと同じ (またはより緩和された) 必要があります。たとえば、抽象メソッドが protected として宣言されている場合、サブクラスに実装されているメソッドは protected または public として宣言する必要があり、private として定義することはできません。さらに、メソッドを呼び出すメソッドは一致している必要があります。つまり、必要なパラメータの型と数が一致している必要があります。たとえば、サブクラスがオプションのパラメーターを定義しているが、それが親クラスの抽象メソッドの宣言に含まれていない場合、2 つの宣言の間に競合はありません
接口
PHP与大多数面向对象编程语言一样,不支持多重继承,也就是说每个类只能继承一个父类。为了解决这个这个问题,PHP引入了接口,接口的思想是指定了一个实现了该接口的类必须实现的一系列函数
使用接口(interface),可以指定某个类必须实现哪些方法,但不需要定义这些方法的具体内容。接口是通过interface关键字来定义的,就像定义一个标准的类一样,但其中定义所有的方法都是空的
接口中定义的所有方法都必须是公有,这是接口的特性。要实现一个接口,使用 implements 操作符。类中必须实现接口中定义的所有方法,否则会报一个致命错误。类可以实现多个接口,用逗号来分隔多个接口的名称。接口中也可以定义常量。接口常量和类常量的使用完全相同,但是不能被子类或子接口所覆盖
<span style="color: #008000;">//</span><span style="color: #008000;">实现一个接口</span> <?<span style="color: #000000;">php </span><span style="color: #0000ff;">interface</span><span style="color: #000000;"> iTemplate { </span><span style="color: #0000ff;">public</span> <span style="color: #0000ff;">function</span> setVariable(<span style="color: #800080;">$name</span>, <span style="color: #800080;">$var</span><span style="color: #000000;">); </span><span style="color: #0000ff;">public</span> <span style="color: #0000ff;">function</span> getHtml(<span style="color: #800080;">$template</span><span style="color: #000000;">); } </span><span style="color: #0000ff;">class</span> Template <span style="color: #0000ff;">implements</span><span style="color: #000000;"> iTemplate { </span><span style="color: #0000ff;">private</span> <span style="color: #800080;">$vars</span> = <span style="color: #0000ff;">array</span><span style="color: #000000;">(); </span><span style="color: #0000ff;">public</span> <span style="color: #0000ff;">function</span> setVariable(<span style="color: #800080;">$name</span>, <span style="color: #800080;">$var</span><span style="color: #000000;">) { </span><span style="color: #800080;">$this</span>->vars[<span style="color: #800080;">$name</span>] = <span style="color: #800080;">$var</span><span style="color: #000000;">; } </span><span style="color: #0000ff;">public</span> <span style="color: #0000ff;">function</span> getHtml(<span style="color: #800080;">$template</span><span style="color: #000000;">) { </span><span style="color: #0000ff;">foreach</span>(<span style="color: #800080;">$this</span>->vars <span style="color: #0000ff;">as</span> <span style="color: #800080;">$name</span> => <span style="color: #800080;">$value</span><span style="color: #000000;">) { </span><span style="color: #800080;">$template</span> = <span style="color: #008080;">str_replace</span>('{' . <span style="color: #800080;">$name</span> . '}', <span style="color: #800080;">$value</span>, <span style="color: #800080;">$template</span><span style="color: #000000;">); } </span><span style="color: #0000ff;">return</span> <span style="color: #800080;">$template</span><span style="color: #000000;">; } } </span>?>
<span style="color: #008000;">//</span><span style="color: #008000;">常量不能被覆盖</span> <?<span style="color: #000000;">php </span><span style="color: #0000ff;">interface</span><span style="color: #000000;"> a { </span><span style="color: #0000ff;">const</span> b = 'Interface constant'<span style="color: #000000;">; } </span><span style="color: #0000ff;">echo</span> a::<span style="color: #000000;">b; </span><span style="color: #008000;">//</span><span style="color: #008000;"> 错误写法,因为常量不能被覆盖。接口常量的概念和类常量是一样的。</span> <span style="color: #0000ff;">class</span> b <span style="color: #0000ff;">implements</span><span style="color: #000000;"> a { </span><span style="color: #0000ff;">const</span> b = 'Class constant'<span style="color: #000000;">; } </span>?>
<span style="color: #008000;">//</span><span style="color: #008000;">继承多个接口</span> <?<span style="color: #000000;">php </span><span style="color: #0000ff;">interface</span><span style="color: #000000;"> a { </span><span style="color: #0000ff;">public</span> <span style="color: #0000ff;">function</span><span style="color: #000000;"> foo(); } </span><span style="color: #0000ff;">interface</span><span style="color: #000000;"> b { </span><span style="color: #0000ff;">public</span> <span style="color: #0000ff;">function</span><span style="color: #000000;"> bar(); } </span><span style="color: #0000ff;">interface</span> c <span style="color: #0000ff;">extends</span> a,<span style="color: #000000;"> b { </span><span style="color: #0000ff;">public</span> <span style="color: #0000ff;">function</span><span style="color: #000000;"> baz(); } </span>?>
对象的多态性是指在父类中定义的属性或行为被子类继承之后,可以具有不同的数据类型或表现出不同的行为。这使得同一个属性或行为在父类及其各个子类中具有不同的语义。例如:"几何图形"的"绘图"方法,"椭圆"和"多边形"都是"几何图"的子类,其"绘图"方法功能不同
单态
说到多态,首先要提到单态设计模式,单态模式的主要作用是保证在面向对象编程设计中,一个类只能有一个实例对象存在
<?<span style="color: #000000;">php </span><span style="color: #0000ff;">class</span><span style="color: #000000;"> DB { </span><span style="color: #0000ff;">private</span> <span style="color: #0000ff;">static</span> <span style="color: #800080;">$obj</span> = <span style="color: #0000ff;">null</span><span style="color: #000000;">; </span><span style="color: #0000ff;">private</span> <span style="color: #0000ff;">function</span><span style="color: #000000;"> __construct() { </span><span style="color: #0000ff;">echo</span> "连接数据库成功<br>"<span style="color: #000000;">; } </span><span style="color: #0000ff;">public</span> <span style="color: #0000ff;">static</span> <span style="color: #0000ff;">function</span><span style="color: #000000;"> getInstance() { </span><span style="color: #0000ff;">if</span>(<span style="color: #008080;">is_null</span>(self::<span style="color: #800080;">$obj</span><span style="color: #000000;">)) self</span>::<span style="color: #800080;">$obj</span> = <span style="color: #0000ff;">new</span><span style="color: #000000;"> self(); </span><span style="color: #0000ff;">return</span> self::<span style="color: #800080;">$obj</span><span style="color: #000000;">; } </span><span style="color: #0000ff;">public</span> <span style="color: #0000ff;">function</span> query(<span style="color: #800080;">$sql</span><span style="color: #000000;">) { </span><span style="color: #0000ff;">echo</span> <span style="color: #800080;">$sql</span><span style="color: #000000;">; } } </span><span style="color: #800080;">$db</span> = DB::<span style="color: #000000;">getInstance(); </span><span style="color: #800080;">$db</span> -> query("select * from user"<span style="color: #000000;">); </span>?>
多态展现了动态绑定的功能,也称为“同名异式”,多态可以让软件在开发和维护时,达到充分的延伸性
在php中,多态性就是指方法的重写,一个子类可中可以重新修改父类中的某些方法,使其具有自己的特征。重写要求子类的方法和父类的方法名称相同,这可以通过声明抽象类或是接口来规范
<?<span style="color: #000000;">php </span><span style="color: #0000ff;">interface</span><span style="color: #000000;"> USB { </span><span style="color: #0000ff;">const</span> WIDTH = 12<span style="color: #000000;">; </span><span style="color: #0000ff;">const</span> HEIGHT = 3<span style="color: #000000;">; </span><span style="color: #0000ff;">function</span><span style="color: #000000;"> load(); </span><span style="color: #0000ff;">function</span><span style="color: #000000;"> run(); </span><span style="color: #0000ff;">function</span><span style="color: #000000;"> stop(); } </span><span style="color: #0000ff;">class</span><span style="color: #000000;"> Cumputer { </span><span style="color: #0000ff;">function</span> useUSB(USB <span style="color: #800080;">$usb</span><span style="color: #000000;">) { </span><span style="color: #800080;">$usb</span> -><span style="color: #000000;"> load(); </span><span style="color: #800080;">$usb</span> -><span style="color: #000000;"> run(); </span><span style="color: #800080;">$usb</span> -><span style="color: #000000;"> stop(); } } </span><span style="color: #0000ff;">class</span> Mouse <span style="color: #0000ff;">implements</span><span style="color: #000000;"> USB{ </span><span style="color: #0000ff;">function</span><span style="color: #000000;"> load() { </span><span style="color: #0000ff;">echo</span> "加载鼠标成功!<br>"<span style="color: #000000;">; } </span><span style="color: #0000ff;">function</span><span style="color: #000000;"> run() { </span><span style="color: #0000ff;">echo</span> "运行鼠标功能!<br>"<span style="color: #000000;">; } </span><span style="color: #0000ff;">function</span><span style="color: #000000;"> stop() { </span><span style="color: #0000ff;">echo</span> "鼠标工作结束!<br>"<span style="color: #000000;">; } } </span><span style="color: #0000ff;">class</span> KeyPress <span style="color: #0000ff;">implements</span><span style="color: #000000;"> USB { </span><span style="color: #0000ff;">function</span><span style="color: #000000;"> load() { </span><span style="color: #0000ff;">echo</span> "加载键盘成功!<br>"<span style="color: #000000;">; } </span><span style="color: #0000ff;">function</span><span style="color: #000000;"> run() { </span><span style="color: #0000ff;">echo</span> "运行键盘成功!<br>"<span style="color: #000000;">; } </span><span style="color: #0000ff;">function</span><span style="color: #000000;"> stop() { </span><span style="color: #0000ff;">echo</span> "停止键盘使用!<br>"<span style="color: #000000;">; } } </span><span style="color: #0000ff;">class</span><span style="color: #000000;"> Worker { </span><span style="color: #0000ff;">function</span><span style="color: #000000;"> work() { </span><span style="color: #800080;">$c</span> = <span style="color: #0000ff;">new</span><span style="color: #000000;"> Cumputer(); </span><span style="color: #800080;">$m</span> = <span style="color: #0000ff;">new</span><span style="color: #000000;"> Mouse; </span><span style="color: #800080;">$k</span> = <span style="color: #0000ff;">new</span><span style="color: #000000;"> KeyPress; </span><span style="color: #800080;">$c</span>->useUSB(<span style="color: #800080;">$k</span><span style="color: #000000;">); </span><span style="color: #800080;">$c</span>->useUSB(<span style="color: #800080;">$m</span><span style="color: #000000;">); } } </span><span style="color: #800080;">$w</span> = <span style="color: #0000ff;">new</span><span style="color: #000000;"> Worker; </span><span style="color: #800080;">$w</span> -><span style="color: #000000;"> work(); </span>?>