后端基础【PHP面向对象】
后端基础【PHP面向对象】
类与对象概念
<?php
//创建一个对象
class cat {
public $name;
public $age;
public $color;
}
//创建一个猫
$cat1= new cat;
$cat1->name="mingming";
$cat1->age=18;
$cat1->color="yellow";
//再创建一个猫
$cat2= new cat;
$cat2->name="honghong";
$cat2->age=16;
$cat2->color="pink";
//输出两个猫的信息
if ($cat1->name="mingming"){
echo $cat1->name."|".$cat1->age."|".$cat1->color.'<br/>';
}if ($cat2->name="honghong"){
echo $cat2->name."|".$cat2->age."|".$cat2->color;
}
?>
根据案例发现,类是抽象的,表示一类事物,对象是具体的,表示类的一个具体实例。类是对象的模板,对象是类的一个个具体实例。
类的创建格式:
class 类名{
成员属性(变量);
}
成员属性可以是基本数据类型也可以是复合数据类型(数组、对象)。
对象的创建格式:
$对象名 = new 类名();
或者
$对象名 = new 类名;
访问对象的属性
$对象名 -> 属性名;
构造函数
构造函数:在创建对象时直接给属性赋值。
构造函数是类的一种特殊函数,主要作用是完成对新对象的初始化。
两个特点:1.没有返回值;2.在创建一个类的对象时,系统会自动调用该类的构造函数完成对新对象的初始化。
案例
<?php
//创建一个对象
class Person {
public $name;
public $age;
public function __construct($name, $age) {
$this->name = $name;
$this->age = $age;
}
}
$cat1 = new Person("xiaohong",5);
echo $cat1->name;
echo '<hr />';
echo $cat1->age;
?>
注意:构造函数在类中只能有一个,并且不能手动调用。它只能在创建新对象时自动调用。
代码中所使用的$this,它会指向当前对象,更深一步,就是这个对象的地址。哪个对象使用$this,就指向哪个对象的地址,$this不能再类外部使用。
析构函数
析构函数是另一种特殊的函数,用于在对象销毁时执行清理操作。
当对象不再被使用时,PHP会自动调用析构函数。与构造函数一样,析构函数的名称必须与类名相同,并且不带参数。
<?php
class MyClass {
public function __construct() {
echo 'Object created.';
}
public function __destruct() {
echo 'Object destroyed.';
}
}
$test = new MyClass;
?>
在创建新的对象时,并输出一条消息“Object created.”。当脚本结束或对象不再被使用时,PHP将自动销毁该对象,并输出一条消息“Object destroyed.”。
需要注意的是,析构函数的执行时机不受程序员的控制。当对象不再被使用时,PHP会自动调用析构函数。
因此,析构函数主要用于执行清理操作,例如关闭数据库连接或释放资源等。
静态变量
<?php
class Child{
public $name;
public static $sums=0; //定义静态变量
function __construct($name)
{
$this-> name = $name;
}
function JChild(){
self::$sums += 1;
echo $this-> name.'加入游戏';
echo "<hr />";
}
}
$child1=new Child("Ming");
$child1->JChild();
$child2=new Child("Zhang");
$child2->JChild();
$child3=new Child("Lin");
$child3->JChild();
echo '<br/>'."一共".Child::$sums."个小孩";
?>
1、静态变量的修饰符为static;
2、静态变量的访问方式:
如果是在类的外部访问:类名::$类变量名
如果是在类的内部访问:类名::$类变量名 或者 self::$类变量名
注意:访问静态变量和是否创建对象无关,你不创建对象,也可以访问。访问静态变量,禁止使用$this,否则程序会报错。
静态方法
<?php
class Child{
public $name;
public static $sums=0;
function __construct($name)
{
$this-> name = $name;
}
static function JChild(){
Child::$sums += 1;
}
function Join(){
echo $this-> name.'加入游戏';
echo "<hr />";
}
}
$child1 = new Child("Ming");
$child1->Join();
$child1->JChild();
$child2=new Child("Zhang");
$child2->JChild();
$child2->join();
$child3=new Child("Lin");
$child3->JChild();
$child3->join();
echo '<br/>'."一共".Child::$sums."个小孩";
?>
静态方法和静态变量是对应的,只能调用静态变量,如果调用非静态变量它是会报错的。不过,反过来可以,即普通成员函数是可以调用静态变量的。原因是静态变量和静态方法都属于这个类,并且都是公开的。
封装
封装主要介绍三个修饰符,分别是public(公开的)、protected(受保护的)、private(私有的)
<?php
class Person{
public $name;
protected $age;
private $wage;
public function __construct($name,$age,$wage){ //构造方法
$this-> name = $name;
$this-> age = $age;
$this-> wage = $wage;
}
}
$p1=new Person("Ming",18,1000); //实例化对象
echo $p1->name;
echo $p1->age; #进行了报错
echo $p1->wage; #进行了报错
?>
protected(受保护的)与 private(私有的)这两个修饰符修饰的变量不能直接调用。要想调用,就需要写一个公开的方法,再直接调用方法就可以。
<?php
class Person{
public $name;
protected $age;
private $wage;
public function __construct($name,$age,$wage){ //构造方法
$this-> name = $name;
$this-> age = $age;
$this-> wage = $wage;
}
public function PersonAge(){
echo $this->age;
echo "<hr />";
}
public function PersonWage(){
echo $this->wage;
echo "<hr />";
}
}
$p1=new Person("Ming",18,1000); //实例化对象
echo $p1->name;
echo "<hr />";
echo $p1->PersonAge();
echo $p1->PersonWage();
?>
你可能会有疑问,我们直接调就可以了,为什么要多走这一步?这是因为在方法里我们可以对变量进一步控制,比如加个范围,权限再控制得细一些等。也可以用另外一种方法,即PHP为我们提供的魔术方法:
__set()对protected或是private属性,进行赋值操作
__get()获取protected或是private属性的值
继承
<?php
// 父类
class Student{
public $name;
public $age;
public $studentID;
public function ShowInfo($name,$age){
echo $this-> name = $name." | ".$this-> age = $age;
}
}
// 子类
class universityStudent extends Student{
public function study(){
echo " 正在学习 ";
}
}
$u1 = new universityStudent();
$u1-> ShowInfo("Ming",22);
$u1-> study();
?>
子类可以使用父类的方法,这就解决了代码重复的问题。如果想要使用继承,关键字“extends”。所谓继承就是子类通过“extends”关键字,把父类的(public、protected)属性和(public、protected)方法继承下来。
还需注意,只能继承public、protected属性和public、protected方法,private的属性和方法只能在本类中使用。
在PHP中子类最多只能继承一个父类(指直接继承),在创建某个子类对象时,默认情况不会自动调用其父类的构造函数。
如果想调用父类的构造函数,可以通过在子类的代码中加入:“父类名::构造函数名”或者“parent::构造函数名”两种方法实现
<?php
// 父类
class Student{
public $name;
public $age;
public $studentID;
public function __construct(){
echo "我是父类的构造函数";
}
public function ShowInfo($name,$age){
echo $this-> name = $name." | ".$this-> age = $age;
}
}
// 子类
class universityStudent extends Student{
public function study(){
echo " 正在学习 ";
}
public function __construct(){
Student::__construct();
echo " 我是子类的构造函数 "." <br/>";
}
}
$u1 = new universityStudent();
$u1-> ShowInfo("Ming",22);
$u1-> study();
?>
多态
函数重载
重载是类的多态的一种实现,是指一个标识符被用作多个函数名,并且能够通过参数个数或参数类型将这些同名的函数区分开,调用不发生混淆。
<?php
class A{
public $name;
public $age;
public function test1($a){
echo "hello,123";
}
public function test2($a){
echo "hello,456";
}
public function __call($name, $arguments) //定义call方法,会自动调用这个方法
// __call为PHP的魔术方法
//$name:被调用的方法的名称
//$arguments:一个包含传递给方法参数的数组
{
var_dump($arguments);
if($name=="test"){
if(count($arguments)==1){
$this->test1($arguments);
}elseif (count($arguments)==2){
$this->test2($arguments);
}
}
}
}
$a = new A();
$a-> test(1);
$a-> test(2,6);
?>
注意:
public function test(){
echo "hello,123";
}
public function test($a){
echo "hello,456";
}
如果我们这么写,PHP会报错,其他的语言可以。
方法重写(覆盖)
假设我们设计一个类,提取一些相同的特征,设计成父类,并有一些函数,而子类想要完善父类的方法,只需要在子类中将方法的命名设为和父类相同,参数也完全相同就可以了。我们把它叫作方法重写(覆盖)。如果子类想要调用父类的方法,可以使用parent::方法名()。
子类方法不能缩小父类方法的访问权限,但可以扩大。
<?php
class A{
public function Reset(){
echo "父类的reset方法";
}
}
class B extends A{
public function Reset(){
parent::Reset();
echo '<hr />';
echo "子类的reset方法";
}
}
$obj = new B;
$obj-> reset();
?>
抽象类
之所以设计抽象类,是为了快速开发,我们可能遇到这样的类,它是其他类的父类,但它本身并不需要实例化,主要是用于子类去继承。这样可以达到代码复用的目的,并且有利于项目设计者设计类。
抽象类格式:
abstract class 类名{
abstract 修饰符 function 函数名(参数列表);//这里要注意,没有方法体。
}
抽象类不能被实例化。抽象类不一定要包含abstract方法。也就是说,抽象类可以没有abstract方法。一旦类包含了abstract方法,则这个类必须声明为abstract。抽象方法不能有函数体。
如果一个类继承了某个抽象类,则它必须实现该抽象类的所有抽象方法(除非自己也声明为抽象类)。
接口
接口的存在是为了方便,也是为了规范。因为若要实现某个接口,就必须实现里面的所有方法。
<?php
interface iTest{ //定义一个接口
public function start();
public function stop();
}
class camera implements iTest{
public function start(){
echo "计算机开始工作";
}
public function stop(){
echo "计算机停止工作";
}
}
class phone implements iTest{
public function start(){
echo "手机开始工作";
}
public function stop(){
echo "手机停止工作";
}
}
$c1=new camera();
$c1->start();
$c1->stop();
echo "<br/>";
$p1=new phone();
$p1->start();
$p1->stop();
?>
接口比抽象类更抽象,所以,接口更不能被实例化了。接口中所有的方法都不能有主体。
一个类可以实现多个接口,用逗号隔开。
public class A implements 接口1,接口2{
}
接口中可以有属性,但必须是常量,默认是public。接口中的方法必须是public,默认也是public。一个接口不能继承其他的类,但是可以继承别的接口。
interface 接口名 extends 接口1,接口2{
}
如果我们希望某个类不被其他类继承,我们可以使用final关键字来修饰这个类。
final关键字通过在定义方法和常量之前加上 final 来防止被子类覆盖。 如果一个类被声明为 final,则不能被继承。
注意,如果我们用final来修饰某个类中的方法,则这个方法无法被重写。final也不能用来修饰成员属性。
本文系作者 @小白学安全 原创发布在 xbxaq.com 站点,未经许可,禁止转载!
评论