PHP面向对象(oop)的学习笔记

一.特点:
1.封装 
public 公共的(类外可以访问)
private 私有的(类内访问) 

私有字段内容的调用
 class Computer {
        private $_name = '联想';
         
          //这个时候我采用一个公共对外的方法来访问私有字段
          //因为私有字段只能在类内访问,而对外的公共方法是类内的。
          //更而公共方法又是公共的,所以类外又可访问。
          public function _run() {
               //字段在类内调用的时候必须是类->字段,而$_name只是一个普通变量而已。
               //字段在类外调用的方法是对象->字段,而类内就必须使用Computer->_name
               //但是在本类中,可以用一个关键字来代替Compouter,那就是$this
              
               echo $this->_name; 
          }  
     }
     $computer = new Computer();
     $computer->_run();

如何对私有的字段进行赋值和取值
class Computer {
     private $_name;   
     //必须写一个对内的入口,对私有字段进行赋值
     public function setName($_name) {
          //这里的$_name只是一个变量而已,参数而已
          //$this->_name才是类的字段
          $this->_name = $_name;
     }
    
    
     //必须写个对外的入口,才可以取到
     public function getName() {
          return $this->_name;
     }
    
}

如果有十个字段那么就必须要二十个方法才能够赋值和取值, 那么有没有更简便的方法呢?PHP内置两个方法(拦截器)专门用于取值与赋值:__set(),__get()
class Computer {
//类的字段(成员)
private $_name;
private $_model;
//所有字段的赋值都在这里进行
private function __set($_key ,$_value) {
$this->$_key = $_value;
}
//所有字段的取值都在这里进行
private function __get($_key) {
return $this->$_key;
}
}
$computer = new Computer();
$computer->_model = 'LX';
echo $computer->_model;
  有些使用类里面的方法并不需要对外公开, 只是里面运作的一部分, 这个时候可以将方法也封装起来。所以__set()和__get()方法私有,还是可以执行,是因为目前程序的指针已经在类内了。而类内可以执行封装的方法。 类内执行私有方法,不会出现任何错误。 它只需要间接的拦截就可以了。拦截是在内类执行的。

静态类成员
静态的方法和成员字段都保存在数据静态区,不是放在堆中
class Computer {
public static $_count = 0;
}
echo Computer::$_count;
静态的方法不用实例化,直接调用
class Computer {
    
     public static $_count = 0;
    
     public static function _run() {
          self::$_count++;
     }
    
}
Computer::_run();
Computer::_run();
Computer::_run();
Computer::_run();
echo Computer::$_count;

Instanceof关键字
PHP5有一个instanceof关键字,使用这个关键字可以确定一个对象是类的实例、类的子类,还是实现了某个特定接口,并进行相应的操作。
class Computer {
//
}
$computer = new Computer();
echo ($computer instanceof Computer);


2.继承:从父类继承到子类的字段或方法
继承自其他类的类成为子类或派生类,子类所继承的类成为父类或基类。(PHP只支持单继承,PHP不支持方法重载)
class Computer {
private $_name = '联想120';
private function __get($_key) {
return $this->$_key;
}
public function run() {
echo '我是父类';
}
}
class NoteBookComputer extends Computer {
}
$notebookcomputer = new NoteBookComputer();
$notebookcomputer->run();
echo $notebookcomputer->_name;
有些时候, 并不是特别需要父类的字段和方法,那么可以通过 子类的重写来修改父类的字段和方法。

子类调用父类的字段或方法
为了安全, 我们一般将父类的方法用受 保护的修饰符来封装了起来,这样, 外部就无法调用, 只能被继承它的子类所看到。这个时候,就需要通过子类操作来调用父类了
class Computer {     
     //私有化,但是无法被子类继承,这个时候就应该用受保护的修饰符来封装
      protected $_name = '联想';
      protected function _run() {
           return '联想在运行!';
     }
    
}
class NoteComputer extends Computer {
     public function getTop() {
          echo $this->_name;
          echo $this->_run();
     }
}

$notecomputer = new NoteComputer();
$notecomputer->getTop();

当子类已经覆盖了父类的字段和方法,但是我们又要调用父类的字段和方法 语法:父类名::方法() 或者parent::方法()即可调用
class NoteBookComputer extends Computer {
public function run() {
echo Computer::run(); //
}
}

final关键字
final如果加在类前面,表示这个类不能被继承;如果加在方法前面,表示不能重写此方法

3.多态
一个相同的方法,不同的人调用这个方法会有不同的行为
用不同的方法去执行调用同一动作

抽象类
抽象类不能被实例化只能被继承(给子类进行继承)
抽象类里的抽象方法,子类必须重写

//创建一个抽象类,只要在class前面加上abstract就是抽象类了
//抽象类不能够被实例化,就是创建对象
//只要类里面有一个抽象方法,那么这个类就必须是抽象类,类前面必须加上abstract
abstract class Computer {
     public $_name  = '联想';
     //在抽象类里创建一个抽象方法
     //抽象方法不能够实现方法体的内容
     abstract public function _run();
     //我在抽象类里能否创建一个普通方法
     public function _run2() {
          echo '我是父类的普通方法';
     }
}
//类不能够实现多继承,只支持单继承。
//抽象类是给子类用来继承的,实现一种规范和资源的共享
class NoteComputer extends Computer {
     //抽象类里的抽象方法,子类必须重写,不然会报错。
     //抽象类里的普通方法不需要重写,子类会直接继承下来
     public function _run() {
          echo '我是子类的方法!';
     }
}
$notecomputer = new NoteComputer();
$notecomputer->_run2();
echo $notecomputer->_name;

接口
<?php
//到底应该用抽象类还是接口呢
//如果你要继承多个类的方法规范,那么就用接口好了。
//如果你要共享一个方法体内容,那么就用抽象类。

//创建一个接口
//接口也不能被实例化
//接口是为了规范实现它的子类,以达到统一的目的。也可以共享数据
interface Computer {
     //成员字段必须是常量
     const NAME = '联想';
     //接口里的所有方法都是抽象方法,不能够写方法体
     //并且接口的抽象方法不需要写abstract
     public function _run();
     public function _run2();
}

interface Computer2 {
     public function _run3();
}

//子类继承接口的说话,叫做实现,接口可以多实现
class NoteComputer implements Computer,computer2 {
     public function _run() {
          echo '我重写了run';
     }
     public function _run2() {
          echo '我重写了run2';
     }
     public function _run3() {
         
     }
}
$notecomputer = new NoteComputer();
$notecomputer->_run();

//接口::常量
//echo Computer::NAME;
?>

多态
<?php
//什么叫做多态,字面意思,多种形态    
//一个动作由不同的人去执行,而产生不同的效果或者结果,即为多态。    
//一个人通过不同的状态去执行同一种动作,形成不同的结果,也可以称作为多态。

//园丁           剪              修理花草
//理发师         剪               理发
//总裁           剪               裁员

//人            笔记本             运行            win7开机了
//人            台式机              运行            xp开机了

//创建一个接口,来规范运行的方法
interface Computer {
     public function version(); //这个方法表示采用什么电脑
     public function work();  //这台电脑是怎么运行的
}    
//创建一个笔记本类来实现接口
class NoteComputer implements Computer {
     public function version() {
          echo '笔记本';
     }
     public function work() {
          echo '可以便携式运行win7';
     }
}    
//创建一个台式机的类来实现接口
class DesktopComputer implements Computer {
     public function version() {
          echo '台式机';
     }
     public function work() {
          echo '在工作站运行XP';
     }
}    
//创建一个用户
class Person {
     //创建一个方法来接受电脑(笔记本电脑,也可是台式电脑)
     //怎么接受,将他们的对象传进来就OK啦。
     public function _run($type) {
          echo '这个人的';
          $type->version();
          $type->work();
     }
}    
//多态的原理,就是类都写好了,不要去修改他,只要在类外的调用参数的更改
//而最后的结果也会得到更改,那么这个就是多态。

//有一个接口,两个类,一个是笔记本的类,一个是台式机的类

//创建了笔记本
$notecomputer = new NoteComputer();
//创建台式机
$desktopcomputer = new DesktopComputer();
//创建一个人
$person = new Person();
//使用电脑
$person->_run($notecomputer);  //这种传递,叫做对象引用的传递
?>

二.关键的oop概念
1.类
2.对象
3.字段
4.属性:一种特殊的方法
5.方法

echo var_dump() 打印对象的地址
构造方法(命名必须和类名相同,当实例化的时就可以直接运行构造方法)
php5中可以运用 __construct()创建构造函数

析构方法
public function __destruct() {}
一般情况都是先执行构造方法,在执行其他的方法
用这张图片来解释下上面5个概念

面向对象的工具
PHP引入了__autoload()内置方法来自动包含类文件。 __autoload()应该被写成单个参数的方法。当PHP引擎遇到试图实例化未知类的操作时,会调用__autoload()方法,并将类名当作字符串参数传递给它。
function __autoload($_className) {
require $_className.'.class.php';
}
$demo = new Computer();

PHP采用了__call()内置方法来屏蔽对象调用方法时产生的错误。当对象调用一个不存在的方法时,会自动调用__call()方法。
private function __call($_methodName,$args) {
echo $_methodName.'方法不存在';
print_r($args);
}
$computer->go('我',1,'知道');

PHP使用__toString()内置方法来打印对象的引用。没有使用__toString()的对象是产生一个错误,当打印对象的时候会自动调用__toString()方法。
class Computer {
private function __toString() {
return '打印对象';
}
}
echo new Computer();

PHP可以在类中定义一个__clone()内置方法来调整对象的克隆行为。当一个对象被克隆的时候自动执行__clone()方法,而复制的对象可以在其方法体内进行调整。
class Computer {
public $_name ;
public function __clone() {
$this->_name = 'ibm';
}
}
$computer1 = new Computer();
$computer1->_name = 'dell';
$computer2 = clone $computer1;
echo $computer2->_name;

二,类函数和对象函数
<?php
class Computer {
     public function _run() {}
     private function _go() {}
     public $_name = 'dell';
     private $_model = 'i7';
}

class NoteComputer extends Computer {
    
}

interface Person {
    
}

$computer = new Computer();
$notecomputer = new NoteComputer();

//1.检查类是否存在
echo class_exists('Computer');
//2.获取对象的类名
echo get_class($computer);
//3.获取类中公共的方法
print_r(get_class_methods($computer));
//4.获取类中的字段(公有的)
print_r(get_class_vars('Computer'));
//5.获取子类的父类
echo get_parent_class($notecomputer);
//6.判断接口是否存在
echo interface_exists('Person');
//7.判断对象是否是这个类,$notecomputer的类的父类是Computer
echo is_a($notecomputer,'Computer');
//8.判断对象是否是类的子类。
echo is_subclass_of($notecomputer,'Computer');
//9.判断对象是否有这个方法
echo method_exists($computer,'_run');
?>

以上就是我学习php面向对象所做的一下笔记,有不对的地方希望与我交流,谢谢

猜你喜欢

转载自blog.csdn.net/amanat/article/details/48092343