学习oop知识之OOP的封装
學習要點:
1、 OOP的封裝
2、 OOP的繼承
3、 OOP的多態
?
面向對象的三個主要特性是封裝、繼承和多態。
?
一、OOP的封裝
隱藏對象的字段和實現細節,僅對外公開接口,控制在程序中字段的讀和修改的訪問級別;將抽象得到的數據和行為(或功能)相結合,形成 一個有機的整體,也就是將數據與操作數據的源代碼進行有機的結合,形成“類”,其中數據和函數都是類的成員。
?
字段的作用域 1.public 公共的 (類外可以訪問) 2.private 私有的 (類內可以訪問) 3.protected 受保護的 (類內和子類可以訪問,類外不可訪問) 其實也是私有的,權限不一樣而已
?
創建使用了私有的字段,這樣外部就無法訪問了
?
?
1、類內和類外的概念
【參看demo1.php】
<meta charset="utf-8">
<?php
//創建一個電腦類
class Computer{
?
//什么叫做類內,就是創建類的兩個花括號內的范圍叫做類內,其他地方則叫做類外;
//public是字段的公有化,這個字段類外即可訪問,賦值和取值;
public $_name;
}
?
$computer = new Computer(); //這就是類外;
$computer->_name = 'dell';
echo $computer->_name;
?>
?
?
2、類外無法訪問類內私有字段
【參看demo2.php】
<?php
class Computer{ //大括號里面是類內;
//private是私有化,即對字段進行封裝的操作,類外無法訪問,取值和賦值都不能操作;
private $_name = '聯想';
}
?
$computer = new Computer();
echo $computer->_name;
?>
?
?
?
?
3、類外如何訪問類內私有字段——通過類內公有方法
【參看demo3.php】
<meta charset="utf-8">
<?php
class Computer{
private $_name = '聯想';
//這個時候我采用一個公共對外的方法來訪問私有字段
//因為私有字段只能在類內訪問,而對外的公共方法是類內的。
//而且公共方式又是公共的,所以類外又可以訪問。
public function _run(){
//字段在類內調用的時候必須是類->字段,而$_name只是普通變量而已
//字段在類外調用的方法是對象->字段,而類內就必須使用Computer->_name
//但是在本類中可以用一個關鍵字來代替Computer,那就是$this
echo $this->_name;
}
}
?
$computer = new Computer();
$computer->_run();
?>
?
4、類外對類內賦值和取值——通過設置公有賦值方法和公有取值方法
【參看demo4.php】
<meta charset="utf-8">
<?php
class Computer{
private $_name;
private $_model;
private $_cpu;
private $_keyboard;
private $_show;
private $_zb;
?
//必須寫一個對內的入口,對私有字段進行賦值
public function setName($_name){ //public換成private就會報錯
//通常約定俗成,字段是什么名字,你就取什么名字;
//這里的$_name只是一個變量而已,參數而已;
//$this->_name才是類的字段;
$this->_name = $_name;
}
?
//必須寫個對外的入口,才可以取到;
public function getName(){
return $this->_name;
}
?
}
?
$computer = new Computer();
$computer->setName('dell');
?
echo $computer->getName();
?>
?
?
?
?
?
?
?
5、設置攔截器__set()和__get()實現類外對類內不同字段的賦值和取值
擴展思考:如果類中有很多個字段需要賦值和取值,是不是需要有很多方法來對其進行賦
值和取值呢?答案當然不是;PHP內置兩個攔截器(兩個方法)專門用于取值和賦值;
__set()和__get();(注意:是兩個下劃線)
?
?
【參看demo5.php】
<meta charset="utf-8">
<?php
class Computer{
private $_name;
private $_model;
private $_cpu;
//采用攔截器進行賦值和取值
?
//當類外的對象直接調用私有字段時,會跟著檢查是否有攔截器;如果沒有攔截器直接報錯;如果有攔截器就直接攔截下來;
//如果直接對$_name進行賦值,那么__set()方法就會攔截住,就不會報錯了;
?
//賦值
public function __set($_key,$_value){//$_key屬性名,$_value屬性值;
//那么$_key = '_name' ,那么 $_value = '聯想'
//$this->_name = '聯想'
//那么$_key = '_cpu', 那么$_value = '四核'
//$this->_cpu = '四核'
//那么$_key = '_model', 那么$_value = 'i7'
//$this->_model = 'i7'
$this->$_key = $_value;
}
?
//取值方法1:
/*
public function getName(){
echo $this->_name;
echo $this->_model;
echo $this->_cpu;
}
*/
?
public function __get($_key){
return $this->$_key;
//如果$_key = '_name',那么$this->_name
//如果$_key = '_model',那么$this->_model
//如果$_key = '_cpu',那么$this->_cpu
}
?
//有個疑問?如果攔截器是私有private,那會出錯嗎
//不出錯!為什么都是私有的?類外還能訪問呢?下節課講解;
?
}
$computer = new Computer($_key); // new Computer($_key, $value);也可以如何分析??
$computer->_name = '聯想';
$computer->_cpu = '四核';
$computer->_model = 'i7';
?
?
echo $computer->_name;
echo $computer->_model;
echo $computer->_cpu;
?>
6、設置攔截器__set()和__get()私有的,類外可以實現對類內字段的賦值和取值嗎
【參看demo6.php】
<meta charset="utf-8">
<?php
class Computer{
private $_name;
private $_model;
private $_cpu;
?
//__set()和__get()方法私有了,還是可以執行,是因為目前程序的指針已經在類內了。而類內可以執行封裝的方法;
//類內執行私有方法,不會出現任何錯誤;
//只需要間接的攔截就可以了。攔截是在類內執行的;
?
//說白了,__set和__get是PHP內置的方法,具有一定的特殊性;
private function __set($_key, $_value){
$this->$_key = $_value;
}
?
private function __get($_key){
return $this->$_key;
}
}
?
$computer = new Computer();
?
$computer->_name = '聯想';
$computer->_model = 'i7';
$computer->_cpu = '四核';
?
echo $computer->_name;
echo $computer->_model;
echo $computer->_cpu;
?>
?
?
?
7、類中常量設置及訪問
【參看demo7.php】
常量不是在堆區或棧區,它是在一個數據區中;
<?php
class Computer{
const NAME = 'DELL';//const 定義常量;
}
?
//常量的輸出方法 類::常量 (兩個冒號)
echo Computer::NAME;
?
?
$computer = new Computer();
$computer ::NAME;
?>
?
?
?
8、普通類字段和類方法在數值累加情況
靜態類成員:有時候,可能需要創建供所有類實例共享的字段和方法,這些字段和方法與所有的類實例有關,但不能由任何特定對象調用;
靜態類字段、靜態類方法;
?
【參看demo8.php】
?
<?php
class Computer{
public $_count = 0;
?
public function _add(){
$this->_count++; //$count = $count +1 $count++
}
}
?
//做一個累計的效果
$computer1 = new Computer();
$computer1->_add();
echo $computer1->_count;
$computer1->_add();
echo $computer1->_count;
$computer1->_add();
echo $computer1->_count;
?
echo "<br/>";
?
$computer2 = new Computer();
$computer2->_add();
echo $computer2->_count;
$computer2->_add();
echo $computer2->_count;
$computer2->_add();
echo $computer2->_count;
?>
?
?
9、靜態類字段訪問方法
上面$_count代碼如果設置成靜態字段會如何?
靜態字段是在一個特定的區域——數據區;靜態區只有一個,它是共享的!!!
?
【參看demo9.php】
<?php
class Computer{
public static $_count=0;
?
public function _add(){
//如果是靜態成員字段,那么就應該用self調用,而不是$this
self::$_count++; //注意:slef調用時候需要有$符號;$this調用的時候不需要有$符號
//普通方法必須實例化才能調用;
}
}
?
//echo Computer::$_count;
$computer1 = new Computer();
$computer1->_add();
$computer1->_add();
$computer1->_add();
echo Computer::$_count;
echo "<br/>";
?
$computer2 = new Computer();
$computer2->_add();
$computer2->_add();
$computer2->_add();
echo Computer::$_count;
?
?>
?
?
?
?
10、靜態類字段和靜態類方法的訪問方法
【參看demo10.php】
?
<?php
class Computer{
public static $_count = 0;
?
public static function _run(){
self::$_count++;
}
}
//普通方法需要實例化才能使用;
//而靜態方法不需要實例化直接能使用,不需要new;參看內存說明圖;
Computer::_run();
Computer::_run();
Computer::_run();
Computer::_run();
echo Computer::$_count;
?
?>
?
?
?
11、instanceof關鍵字使用方法
instanceof關鍵字:可以確定一個對象是類的實例、類的子類還是實現了某個特定的接口,并進行相應的操作;
【參看demo11.php】
<?php
class Computer{
?
}
$computer = new Computer();
?
//左邊寫上對象的名字,右邊寫上類的名字
echo ($computer instanceof Computer);
//返回值是1表示真,1表示假;
?
?>
?
轉載于:https://www.cnblogs.com/hcrk/p/10788374.html
總結
以上是生活随笔為你收集整理的学习oop知识之OOP的封装的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Handler 源码解析(Java 层)
- 下一篇: 超媒体API