php中的类与对象(入门)

本文详细介绍了PHP中类和对象的基本使用方法,包括类属性、构造函数、对象间赋值的特点,以及如何在类内创建对象等内容。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

简介

下面用一个实例说明类和对象的简单使用方式

class MyClass 
{
  public    $a = 1;  // 对象属性
  protected $b = 2;  // 对象属性
  private   $c = 3;  // 对象属性

  // 构造函数
  public function __construct() {
    
  }

  // 对象方法
  public function getA() {
    return $this->a;
  }
}

$str = "MyClass";     // 当用到类名时,可使用类名字符串
$a = new MyClass;     // 如果构造函数无参数,可省略括号
$b = new MyClass();
$c = new $str;        // 使用类名字符串构造实例
$d = new $str();


类属性

使用类属性时,需要遵循以下规定:

1.类属性可以进行初始化,但必须使用编译阶段即可确定的常量。或一些常量表达式,例如:"1+2"、"'Hello'.'world'"等。

2.在类内部,非静态成员使用 "$this->成员名"的方式访问,静态成员使用 "self::成员名" 的方式进行访问。

3.字符串属性不能应用变量解析特性(使用heredoc或双引号方式时)。

4.类常量使用const进行声明,注意,常量名称前不能添加$符号,而且public/private/protected等访问修改符必须在const之前。

5.类静态成员使用static进行声明。

6.类的静态成员、常量属性、方法都可以不指定可访问修饰符,这时默认为public,类的非静态属性,则必须指定可访问修饰符。

class MyClass 
{
  public const PI = 3.14;
  public static $name = "MyClass"; 


  public $a = 1+2;
  public $b = <<<"HERE"
hello world
HERE;
  
  public function getInfo() {
    echo MyClass::PI . "\n";
    echo self::PI . "\n";
    echo MyClass::$name . "\n";
    echo self::$name . "\n";
    echo $this->a . "\n";
    echo $this->b . "\n";
  }
}

$str = "MyClass";   // 当用到类名时,可使用类名字符串
$a = new MyClass;
$a->getInfo();

echo MyClass::PI . "\n";
echo MyClass::$name . "\n";
echo $a::PI . "\n";
echo $a::$name . "\n";
echo $str::PI . "\n";
echo $str::$name . "\n";

echo $a->a . "\n";
echo $a->b . "\n";


构造函数

类的构造函数使用固定的名称: __construct()
如果子类中定义了构造函数则不会隐式调用其父类的构造函数。要执行父类的构造函数,需要在子类的构造函数中调用 parent::__construct()。如果子类没有定义构造函数则会如同一个普通的类方法一样从父类继承(假如没有被定义为 private 的话)。 

class MyClass
{
  private $name = 1;

  public function __construct(string $name = "none")
  {
    // 如果没有定义构造函数,类将自动继承次类的构造函数
    // 如果类中定义了自己的构造函数,则父类构造函数不会自动调用
    // 如果要调用父类构造函数,需自行调用
    // parent::__construct();
    $this->name = $name;
  }

  public function getName()
  {
    return $this->name;
  }
}

$a = new MyClass();
$b = new MyClass("Ann");

echo $a->getName() . "\n";    // none
echo $b->getName() . "\n";    // Ann

对象可以动态添加和删除属性

class MyClass
{}

$a = new MyClass();
$a->a = "a";
$a->b = "b";

unset($a->a);
var_dump($a);
/*
object(MyClass)#1 (1) {
  ["b"]=>
  string(1) "b"
}
*/

对象之间的赋值默认为引用赋值

当把一个对象已经创建的实例赋给一个新变量时,新变量会访问同一个实例,就和用该对象赋值一样。此行为和给函数传递入实例时一样。给一个已创建的对象建立一个新实例需要使用“克隆”的方式。

class MyClass { }

$a = new MyClass();
$b = new MyClass();

$c = $a;    // a和c是不同的变量,但指向同一个内存实体
$d = &$b;   // b和d是同一个变量,自然也是指向同一个内存实体

$a->x = "1";
$b->x = "2";
$c->x = "3";
$d->x = "4";

var_dump($a->x);  // 3
var_dump($b->x);  // 4
var_dump($c->x);  // 3
var_dump($d->x);  // 4

$b = $a;          // a和b是不同变量,只是指向同一个内存实体
$c = &$a;         // a和c是同一个变量

$a->x = "5";
$a = null;

var_dump($a);     // NULL
var_dump($b);     // ["x"]=>string(1) "5"
var_dump($c);     // NULL

使用对象而非类创建对象

可以通过new一个对象来实例化一个对象,效果与直接使用类是一样的,可以将对象名当构造函数使用:

class Info
{
  public $age = 10;
}
class MyClass 
{
  public $dat = 0;
  public function __construct($dat)
  {
    $this->dat = $dat;
    echo "new MyClass\n";
  }
}

$i = new Info();
$a = new MyClass(2);
$a->x = "x";
$a->i = $i;

$b = new $a(3);  // 如果没有参数,可省略括号
$b->y = "y";
$i->age = 20;

var_dump($a);
var_dump($b);
/*
new MyClass
new MyClass
object(MyClass)#2 (3) {
  ["dat"]=>
  int(2)
  ["x"]=>
  string(1) "x"
  ["i"]=>
  object(Info)#1 (1) {
    ["age"]=>
    int(20)
  }
}
object(MyClass)#3 (2) {
  ["dat"]=>
  int(3)
  ["y"]=>
  string(1) "y"
}
*/

类内创建对象

在类的内部,可以有多种特殊方式可以创建对象,而且可以用于静态方法或对象方法

class MyClass 
{
  public static function getNew($x)
  {
    return new static($x);  // 如果没有参数,可省略括号
  }

  public $dat = 0;
  public function __construct($dat)
  {
    $this->dat = $dat;
  }
}
$a = MyClass::getNew(3);
var_dump($a);

/*
object(MyClass)#1 (1) {
  ["dat"]=>
  int(3)
}*/

class MyClass 
{
  public $dat = 0;
  public function __construct($dat)
  {
    $this->dat = $dat;
  }

  public function getNew()
  {
    // 在类内部有以下方式可以创建当前类的对象
    return new static($this->dat);
    return new self($this->dat);
    return new MyClass($this->dat);
  }
}
$a = new MyClass(3);
$b = $a->getNew();
var_dump($b);

/*
object(MyClass)#2 (1) {
  ["dat"]=>
  int(3)
}
*/

静态属性和方法

类的静态属性和方法使用static关键字进行声明,如果不添加可访问修饰符,则默认为public。注意,不能通过对象访问类的静态属性,但可以通过对象访问静态方法。

class MyClass 
{
  static public $id = 0;            // 类变量

  static public function put() {    // 类方法
    echo "MyClass put()\n";
  }
}

$str = "MyClass";
$ca = new MyClass;

echo MyClass::$id . "\n";
echo $str::$id . "\n";
echo $ca::$id . "\n";
//echo $ca->id."\n";   // 非法

MyClass::put();
$str::put();
$ca::put();
$ca->put();


私有成员可以被同类对象访问

一个对象中的私有成员并非只在对象自身可以读写,同类对象只要有相应的方法,就可以读写同类的其他对象的私有成员

class MyClass
{
  private $dat;

  public function __construct($dat) {
    $this->dat = $dat;
  }
  public function getDat() {
    return $this->dat;
  }
  public function cloneDat(MyClass $x) {
    $x->dat = $this->dat;
  } 
}

$a = new MyClass(2);
$b = new MyClass(3);
$a->cloneDat($b);

echo $b->getDat();    // 2

类定义的一般格式

[abstract/final] class classname [extends baseclass] [implements interfacename,[interfacename, ...]]
{
  [use traitname, [traitname, ...];]
  [[public/protected/private/static/const] $property[=value]; ...]
  [[public/protected/private/static/final/abstract]function functionname(args) {}]
  ...
}


类定义示例

// 定义一个矩形类
class MyRectangle
{
  private $width;
  private $height;

  public function __construct(float $width, float $height){
    $this->width = $width;
    $this->height = $height;
  }

  public function setLenght($width, $height) {
    $ok = false;

    if(is_numeric($width) && (float)$width>0) {
      $ok = true;
      $this->width = (float)$width;
    }

    if(is_numeric($height) && (float)$height>0) {
      $ok = true;
      $this->height = (float)$height;
    }

    if(!$ok)
      throw new Exception("Error: [$width, $height]\n");
  }

  public function getArea(float $ratio=1) : float {
    $area = $this->width * $this->height * $ratio;
    if($area > 0)
      return $area;
    else
      throw new Exception("Error: area == 0\n");
  }
}

try {
  $a = new MyRectangle(2, 3);
  echo "面积为: " . $a->getArea() . "\n";
  $a->setLenght(null, "4");
  echo "面积为: " . $a->getArea(2) . "\n";
  $a->setLenght(null, -3);
  echo "面积为: " . $a->getArea(0) . "\n";
}
catch(Exception $e) {
  echo $e->getMessage();
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值