php oop,PHP OOP

PHP 使用了一段时间, 从对OOP的不了解, 再到使用, 觉得挺好, 特写下

OOP并不是为了面向对象而面向对象, 而是为了达到代码的重用性、灵活性、扩展性

对象和类

从先有对象才有人类, 这个来说, 有点不合理的合理

类:具有相同属性的一组对象的集合

对象:类实例化之后就是对象

看下一般的类的定义

class Person{

// 成员变量

private $name;

private $sex;

private $age;

// 构造函数

function __construct($name="",$sex="",$age=""){

if($name===""||$sex===""||$age===""){

throw new Exception("must set name , sex, age");

}

$this->name = $name;

$this->age = $age;

$this->sex = $sex;

}

// 析构函数

function __destruct(){

echo "byebye\n";

}

// 成员方法

function eat(){

echo "my name is ". $this->name;

}

function sleep(){

echo "i am sleeping";

}

}

// 类的实例化

$jaime = new Person("jaime", "man", 24);

$jaime->eat();

?>

保存为index.php, 在命令窗口输入

$ php index.php

my name is jaime

byebye

如果

$jaime = new Person("jaime", "man", 24);

改为

$jaime = new Person("jaime", "man");

则会触发异常, 会有以下的消息出来, 包括错误信息, 错误行数, 和堆栈信息

$ php index.php

Fatal error: Uncaught exception 'Exception' with message 'must set name , sex, age' in E:\net\index.php on line 15

Exception: must set name , sex, age in E:\net\index.php on line 15

Call Stack:

0.0025 242440 1. {main}() E:\net\index.php:0

0.0025 243016 2. Person->__construct() E:\net\index.php:30

对象和内存

说点理论上的东西吧,

内存的分类:

堆(heap): 不可直接存取, 存储占有空间很大的数据类型的数据

栈(stack): 可以直接存取, 存储占用相同空间长度并且占用空间小的数据, 如存放局部变量,函数参数,当前状态,函数调用信息等

$jaime = new Person("jaime", "man", 24);

$jaime是存放在栈内存里面的引用变量, 即存储在堆中对象的首地址, 一个指针

new Person 实例化出来的对象是存放在堆内存里面的, 是真正的对象实例

对象和成员

变量,方法(内部成员函数)的前缀:

private: 私有成员

public:  公有成员(外部接口),没有加修饰, 默认就是public

protected: 保护型成员, 继承的类可以调用

访问private修饰的变量

Fatal error: Cannot access private property Person::$name in E:\net\index.php on line 36

如果想访问private, protected修饰的成员:

把private改为public

使用__get(), ___set()魔术方法, 但是还是写出代码来看看根据实际情况使用

class Person{

private $name;

private $sex;

private $age;

function __construct($name="",$sex="",$age=""){

if($name===""||$sex===""||$age===""){

throw new Exception("must set name , sex, age");

}

$this->name = $name;

$this->age = $age;

$this->sex = $sex;

}

function __destruct(){

echo "byebye\n";

}

function eat(){

echo "my name is ". $this->name."\n";

}

function sleep(){

echo "i am sleeping\n";

}

function __get($property_name){

$access_array = ['age','name'];// 只允许访问age,name两个私有成员

if(in_array($property_name, $access_array)){

return ($this->$property_name);

}

else{

return NULL;

}

}

function __set($property_name, $value){

$access_array = ['age'];// 只允许访问age这个私有成员

if(in_array($property_name, $access_array)){

$this->$property_name = $value;

}

}

}

$jaime = new Person("jaime", "man", 24);

$jaime->eat();

echo ($jaime->age === NULL)? "NULL":$jaime->age;

echo "\n";

echo ($jaime->sex === NULL)? "NULL":$jaime->sex;

$jaime->age = 80;

echo "\n";

echo ($jaime->age === NULL)? "NULL":$jaime->age;

echo "\n";

$jaime->name = "lll";

echo ($jaime->name === NULL)? "NULL":$jaime->name;

echo "\n";

?>

执行结果如下

$ php index.php

my name is jaime

24

NULL

80

jaime

byebye

类的继承

class Person{

private $name;

private $sex;

private $age;

function __construct($name="",$sex="",$age=""){

if($name===""||$sex===""||$age===""){

throw new Exception("must set name , sex, age");

}

$this->name = $name;

$this->age = $age;

$this->sex = $sex;

}

function __destruct(){

echo "byebye\n";

}

function hello(){

echo "my name is ". $this->name."\n";

}

function sleep(){

echo "i am sleeping\n";

}

}

class Student extends Person

{

private $school;

function __construct($name, $sex, $age, $school)

{

// 调用父类方法, 构造函数

parent::__construct($name, $sex, $age);

$this->school = $school;

}

// 重载了父类方法

function sleep(){

echo "afternoon sleep\n";

// 调用父类方法

parent::sleep();

}

}

$jaime = new Student("jaime", "man", 24,"zh");

$jaime->hello();

$jaime->sleep();

?>

执行后输出

$ php index.php

my name is jaime

afternoon sleep

i am sleeping

byebye

调用父类的方法需要用parent

静态成员和常量

no bb, show code

class Person

{

// 静态成员属性

public static $contry = "China";

public static function say(){

// 静态成员方法, 通过self访问其它静态成员

// 类里面的静态方法只能访问类的静态的属性

echo "I live in ".self::$contry."\n";

}

public function show(){

echo "xxx".self::$contry."\n";

}

}

// 输出静态属性

echo Person::$contry."\n";

// 调用静态方法, 外部调用用类名::静态方法

Person::say();

// 给静态属性重新赋值

Person::$contry = "American";

Person::say();

(new Person())->show();

?>

结果

$ php is.php

China

en

I live in China

I live in American

xxxAmerican en

类的静态变量,类似于全局变量,能够被所有类的实例共享,类的静态方法也是一样的,类似于全局函数, 静态成员被这个类的每个实例对象所共享

访问静态方法访问静态成员不能用$this, 需要用self

$this表示了此方法的对象

'self'表示此静态方法所在的类, self::成员

抽象方法和抽象类

什么叫抽象?不具体的就叫抽象! so

抽象方法 : 类里面没有具体方法体的方法(其实就是不具体的方法)

抽象类: 含有抽象方法的类,

抽象类不能实例化会报错"Cannot instantiate abstract class ", 有点像C里面的函数声明, 仅仅只是一个声明

abstract class AbstractClass{

// 抽象类里面可以有不是抽象的成员

public $variable;

// 抽象方法

abstract function fun1();

abstract function fun2();

function fun3{

echo "我是抽象类中的非抽象方法";

}

}

class demo0 extends AbstractClass{

// 子类必须把父类中的抽象方法全部都实现, 否则子类中还存在抽象方法,仍是抽象类

function fun1(){

echo "call ".__FUNCTION__."\n";

}

function fun2(){

echo "call ".__FUNCTION__."\n";

}

}

// 我这里是想不出名字, 不建议这样做, 因为demo0实例化了3次

(new demo0())->fun1();

(new demo0())->fun2();

(new demo0())->fun3();

?>

接口interface

什么是接口?

如果一个内里面所有的方法都是抽象方法, 我们可以把声明方式换为接口

接口是一种特殊的抽象类, 接口不能包含成员的任何代码,只定义成员身。接口成员的具体代码由实现接口的类提供

interface One{

// 定义常量

const con = "xonst";

// 定义抽象方法, 不用加abstract, 因为都是abstract

function fun1();

function fun2();

}

?>

接口的继承

interface Two extends One{

function fun3();

function fun4();

}

?>

接口的实现

interface One{

// 定义常量

const con = "xonst";

// 定义抽象方法, 不用加abstract, 因为都是abstract

function fun1();

function fun2();

}

interface Two extends One{

function fun3();

function fun4();

}

// 使用“implements”这个关键字去实现接口中的抽象方法

class demo implements Two

{

function fun1() {

echo "call ".__FUNCTION__."\n";

}

function fun2() {

echo "call ".__FUNCTION__."\n";

}

function fun3() {

echo "call ".__FUNCTION__."\n";

}

function fun4() {

echo "call ".__FUNCTION__."\n";

}

}

(new demo())->fun1();

(new demo())->fun2();

(new demo())->fun3();

(new demo())->fun4();

?>

一个类实现多个接口

一个人要遵守的法律不止一步吧, 所以see code

interface One{

// 定义常量

const con = "xonst";

// 定义抽象方法, 不用加abstract, 因为都是abstract

function fun1();

function fun2();

}

interface Two{

function fun3();

function fun4();

}

// 注意这里

class demo implements One, Two

{

function fun1() {

echo "call ".__FUNCTION__."\n";

}

function fun2() {

echo "call ".__FUNCTION__."\n";

}

function fun3() {

echo "call ".__FUNCTION__."\n";

}

function fun4() {

echo "call ".__FUNCTION__."\n";

}

}

(new demo())->fun1();

(new demo())->fun2();

(new demo())->fun3();

(new demo())->fun4();

?>

你娶了你老婆你得对她的家人负责吧, 就像下面

// 使用extends继承一个类,使用implements实现多个接口

class demo extend AbstractClass implements One, Two{

......

// 所有接口中的方法都要实现才可以实例化对象

}

反射Reflection

需求: 导出或提取出关于类、方法、属性、参数等的详细信息, 甚至是判断某个方法是否存在

这里我不做多说, 看我在实际的项目中的实际应用,

这是一个API的入口处理函数, 如果存在这个方法就执行并返回结果, 不存在就抛出异常,

因为接口函数是不断增加甚至是变化的, 使用反射作为api的入口可以让你的具体的api函数变化了入口也不用改

try {

// 使用工厂方法实例化具体的接口

$instance = new \Api\Library\ApiFactory($module, $server, $this->params);

// 反射方法

$action = new \ReflectionMethod($instance->instance, $method);

// 判断方法的类型

if (!$action->isPublic() || $action->isStatic()) throw new \ReflectionException();

// 验证api参数

$validator = new \Api\Library\ApiValidator();

$result = $validator->check($this->params);

if (false === $result) {

$this->result['code'] = $validator->code ? : $this->result['code'];

$this->result['msg'] = $validator->msg ? : $this->result['msg'];

throw new \Exception();

}

} catch(\Exception $e){

$this->_format();

}

参考:

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
本火锅店点餐系统采用Java语言和Vue技术,框架采用SSM,搭配Mysql数据库,运行在Idea里,采用小程序模式。本火锅店点餐系统提供管理员、用户两种角色的服务。总的功能包括菜品的查询、菜品的购买、餐桌预定和订单管理。本系统可以帮助管理员更新菜品信息和管理订单信息,帮助用户实现在线的点餐方式,并可以实现餐桌预定。本系统采用成熟技术开发可以完成点餐管理的相关工作。 本系统的功能围绕用户、管理员两种权限设计。根据不同权限的不同需求设计出更符合用户要求的功能。本系统中管理员主要负责审核管理用户,发布分享新的菜品,审核用户的订餐信息和餐桌预定信息等,用户可以对需要的菜品进行购买、预定餐桌等。用户可以管理个人资料、查询菜品、在线点餐和预定餐桌、管理订单等,用户的个人资料是由管理员添加用户资料时产生,用户的订单内容由用户在购买菜品时产生,用户预定信息由用户在预定餐桌操作时产生。 本系统的功能设计为管理员、用户两部分。管理员为菜品管理、菜品分类管理、用户管理、订单管理等,用户的功能为查询菜品,在线点餐、预定餐桌、管理个人信息等。 管理员负责用户信息的删除和管理,用户的姓名和手机号都可以由管理员在此功能里看到。管理员可以对菜品的信息进行管理、审核。本功能可以实现菜品的定时更新和审核管理。本功能包括查询餐桌,也可以发布新的餐桌信息。管理员可以查询已预定的餐桌,并进行审核。管理员可以管理公告和系统的轮播图,可以安排活动。管理员可以对个人的资料进行修改和管理,管理员还可以在本功能里修改密码。管理员可以查询用户的订单,并完成菜品的安排。 当用户登录进系统后可以修改自己的资料,可以使自己信息的保持正确性。还可以修改密码。用户可以浏览所有的菜品,可以查看详细的菜品内容,也可以进行菜品的点餐。在本功能里用户可以进行点餐。用户可以浏览没有预定出去的餐桌,选择合适的餐桌可以进行预定。用户可以管理购物车里的菜品。用户可以管理自己的订单,在订单管理界面里也可以进行查询操作。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值