其实这世上本没有类和对象,代码码多了,也就有了类和对象.
为什么要用到类和对象?
自从2002年的第一场雪...IT在各个领域的应用越来越多, 程序越来越复杂, 其中存在大量的重复或类似的功能, 造成大量的函数复用, 代码复用.
为了降低代码的复杂度, 让结构更清晰, 更高效, 越来越多的程序员开始将重复的部分提取出来作为公共模块, 并进行抽象, 抽象出一些公共属性, 公共方法, 公共规则, 将这些抽象的内容进行整合, 就有了类的雏形.
在类的基础上, 针对不同的应用场景, 再去做一些适应性调整, 就产生了继承. 再将不同应用场景的的数据导入, 也就产生了不同的实例(instance).
而且面对越来越复杂的业务, 程序的耦合性越来越高, 维护起来越来越难. 类的应用就很好的满足了将程序解耦, 打散再组装的需求. 让程序员们保住了饭碗, 也保住了头发.
并且, 随着面对对象编程思想的越来越流行, 类这种将事物抽象化的方法获得了巨大的青睐和广泛的应用.
什么是类和对象?
类很简单. 它将一类事物的属性和功能提炼了出来, 并进行定义. 创建类的过程也就是将事物抽象化的过程.
事物的属性通过参数(常量,变量)表达, 事物的功能通过方法(函数)表达. 而将这种抽象化的定义再此实例化, 具现化, 就产生了"对象"(object).
比如,"汽车"这个类, 品牌, 尺寸, 重量, 材料, 颜色, 马力, 油耗, 这些是车的属性, 而前进,后退, 导航, 转向, 这些是他的功能. 而比亚迪-唐, 沃尔沃-S80是它的实例.
类分为:普通类class, 抽象类abstract class, 接口类interface, 内置类stdClass, 子类class extends, 匿名类等.
先说平平无奇-普通类:
- 可以实例化, 创建对象.
- 可以定义各种类型的变量,常量和方法.
- 可以继承一个父类, 也可以被多个子类继承.
我们来看看如何创建一个普通类.
HOW
创建一个普通类很简单:
`class Classname {
}`
上面就完成了一个类的创建, 它可以是空的, 不表示任何意义.
类创建后,我们可以使用 new 运算符来实例化该类的对象.
$C= new Classname;
类和对象都创建完毕, 但如果想让它发挥意义, 就需要包含类构成的3个基本的元素: 成员变量(属性), 成员方法(函数), 类常量. 我们详细看一下.
属性
类的变量成员叫做“属性”. 它用来保存信息数据, 并且与成员方法(函数)进行交互来实现具体功能. 我们通常称呼属性为成员变量.
创建类的属性是我们第一个要做的事情, 属性值可以为空, 也可以有初始值,但是初始化的值必须是常数.
继续在上面的例子扩充属性:
class Classname //定义一个类, 类名不区分大小写
{
public $name; //定义成员变量, 公开可见public;
public $height=180; //初始化赋值
public $weight, $nationality; //可以一个语句定义多个变量
protected $age; //受保护的变量protected
}
调用成员变量主要通过两种方式, 一个是在成员方法中调用, 另一个是通过对象加->进行调用, 比如:
echo $C->height; // 180, 输出属性值;
echo $C->name='John'; // 'John', 通过对象调用, 为属性赋值;
我们已经能通过定义属性来做一些基本的事情了, 注意在定义属性的时候, 我们会加上一些关键词, 如public, protected, private, 这是标明这个属性的可见度.
成员变量的可见度:
-
public: 完全公开, 在类定义内部, 外部, 都可以被访问
-
private: 私有, 只有在本类的内部才能访问, 不可以在类外被访问,在子类中也不可以被调用或修改
-
protected: 受保护的, 可以被其自身以及其子类和父类访问
-
如果什么都不写, 则系统默认为public
我们在声明属性的时候, 还可以限制属性的数据类型, 比如:
class Classname
{
public string $name; //限制为字符串格式
public ?int $height //int型或null
}
在数据类型前面加问号, 表示该变量可以为int型, 也可以为null, 当变量为null时系统不会报错. 这里要注意, null不是不需要赋值, 而是可以赋空值null, 这里null不是undefine的意思.
方法
它是定义在类的内部的函数, 负责具体功能的实现. 通常称它为成员方法. 可用于访问和操作对象数据。
创建成员方法和函数很类似, 成员方法也有可见度, 和成员变量一样, 在上面例子的基础上扩展成员方法:
class Classname //定义一个类, 类名不区分大小写
{
public $name; //定义成员变量, 公开可见;
public $height=180; //初始化赋值
public $weight, $nationality; //可以一个语句定义多个变量
protected $age;
public function player($name,$height, $weight, $age, $sex)
{ //定义成员方法, 以及方法形参
$this->name=$name; //为成员变量赋值, 使用了伪变量$this
$this->weight=$weight;
$this->height=$height;
if ($this->height<185 && $this->weight<=85){
return $this->name.',符合要求';
}else{
return $this->name.',不太行';
}
}
}
调用成员方法与调用属性类似, 这里的变量名换成了方法名, 并携带指定参数:
$C=new Classname(); //定义一个对象, 关键词new
echo $C->player('小明','185','80','20','male'); //对象调用成员方法
从上面这个例子, 我们可以看出:
- 成员变量定义, 可以有初始值, 可以通过一个语句定义多个变量. 还可以定义不同可见度的变量;
- 方法定义与普通函数基本类似, 方法内部, 可以通过->符号来引用成员变量;
- 在成员方法中调用变量, 用到了$this. 它是一个到当前对象的引用。在上例中, 它引用的就是$C这个对象, 因为方法会被多个对象调用, 所以$this是个调用对象的代词.
- 可以通过new关键词来创建对象;
- 可以通过对象->来调用方法,并携带实参;
- 可以通过对象->来访问public变量;
在定义成员方法参数的时候, 我们还会看到一种特殊的类型:
class Classname
{
function obj(Classname $a): static {}
}
这种将类名放到参数中的类型声明, 其实是要求带入成员方法的变量, 必须是该指定类的对象. 类似的还有self, 表明参数必须是方法所在类的一个对象。
而小括号后面的是成员方法的返回类型, static表示返回值必须是成员方法所在类的对象, 这种语法在PHP 8.0开始生效.
今天我们讲了先创建了对象, 然后再通过方法player()来为成员变量赋值. 那么有没有方法能在创建对象的同时, 就完成对成员变量的赋值呢? 当然可以, 这就是"构造函数"的意义. 我们下一节来具体讲.
我最后再针对成员方法补充一点, 成员方法和普通函数有什么不一样么?
-
意义上讲: 外部函数实现的是某个独立的功能, 而成员方法是实现类中的一个行为.
-
调用: 函数可以在全局直接调用, 而成员方法需要被对象调用, 或通过类进行调用.
-
操作对象: 外部函数可以操作全局和其内部变量, 常量等. 而成员方法只能操作所属类的成员变量或调用其他成员方法.
但在一些特殊场景下, 他们也可以实现互相调用, 我这里举个例子, 但我个人不太建议这么做:
function rrc($rrc) //定义一个外部函数
{
echo $rrc;
}
class Rrc
{
function bbc() //定义一个成员方法, 并直接引用外部函数;
{
rrc('test');
}
function vcc() //定义一个成员方法;
{
echo 'done';
}
}
$ccc=new Rrc;
$ccc->bbc(); //输出test, 实现了成员方法对外部函数的引用;
function dcc() //定义一个外部函数, 用来引用类成员方法;
{
$GLOBALS['ccc']->vcc(); //通过$GLOBAL可以引用到对象$ccc, 并通过对象调用方法;
}
dcc(); //输出done, 调用成员方法成功;
好了, 第一节基础课就讲到这里, 下课~!
总结不易, 请勿私自转载, 否则别怪老大爷不客气!
参考资料:
www.php.net PHP官方文档
零基础PHP学习笔记 明日科技