Correcting teacher:天蓬老师
Correction status:qualified
Teacher's comments:
类是对某个对象的定义。它包含有关对象动作方式的信息,包括它的名称、方法、属性和事件。
基本语法:
class 类名{
//属性:变量
//构造函数:实例化类的时候就会调用它,如果有参数,在实例化类的时候必须填入参数
//方法:函数
}
类的属性和方法有三种,分别是:
1.public:公开的
2.privote:私有成员,只有本类中使用
3.protedcted:被保护的,仅限本类和子类访问
例如我们可以写一个类并实例化:
class Calculation{
//类的属性:
protected $price;
public $name;
//构造函数:
public function __construct($name,$price)
{
$this->name=$name;
$this->price=$price;
}
//类的方法
public function count():string
{
return "商品名称:$this->name,单价:$this->price";
}
};
类的实例化:
$bill = new Calculation("iphone 12",8888);
echo $bill->count();//商品名称:iphone 12,单价:8888
访问类中的属性:
echo $bill->name;//iphone 12
echo "<hr>";
声明类属性或方法为静态,就可以不实例化类而直接访问。静态属性不能通过一个类已实例化的对象来访问(但静态方法可以)。
例如:
class Demo{
public static $price;
public static $name;
public function __construct(int $price,string $name)
{
// 静态成员与实例无关,所以不能用$this访问
self::$price=$price;
self::$name=$name;
}
// 静态方法
public static function amountto():string
{
return sprintf('品名:%s,单价:%d',self::$name,self::$price);
}
}
$test1 = new Demo(8888,"苹果");
//在外部调用静态方法:
echo Demo::amountto();//品名:苹果,单价:8888
普通的方法也是可行:
echo $test1->amountto();
访问静态属性:
echo Demo::$name;//苹果
echo Demo::$price;//8888
但是静态属性不能用普通的访问方法
类的扩展,也叫类的继承,达到类的复用的目的,扩展有二个方法:一是对父类方法的重写,二是对父类功能的扩充
例如:
class Son extends Calculation{
//扩展一个属性:
private $quantity;
//重写一下父类的构造器:
public function __construct(string $name, float $price,int $quantity)
{
//调用一下父类的成员:
parent::__construct($name, $price);
$this->quantity=$quantity;
}
//再给子类添加一个自己的方法:
function calculator(){
return sprintf("品名:%s,单价:%.2f,购买数量:%d,总价:%d",$this->name,$this->price,$this->quantity,($this->quantity * $this->price));
}
}
实例化类并调用:
$test2 = new Son("足球",88.8,10);
echo $test2->calculator();//品名:足球,单价:88.80,购买数量:10,总价:888
Trait 是为类似 PHP 的单继承语言而准备的一种代码复用机制,可以理解为一个公共方法集,借用class语法实现了一个轻量级的类,但不是类,所以不能实例化,在要使用trait的类中,使用use关键字引用它就可以了
1.当子类与父类存在同名成员时子类优先
2.当trait中存在与父类同名成员时,trait优先
例如:
trait HelloWorld{
public function sayHello(){
echo "Hello World!";
}
}
class TheWorldIsNotEnough{
use HelloWorld;//引入trait
//创建一个和trait中方法同名的方法:
public function sayHello()
{
echo "Hello Galaxy!";
}
}
$test3 = new TheWorldIsNotEnough();
$test3->sayHello();//Hello Galaxy!
如果两个 trait 都插入了一个同名的方法,如果没有明确解决冲突将会产生一个致命错误。
为了解决多个 trait 在同一个类中的命名冲突,需要使用 insteadof 操作符来明确指定使用冲突方法中的哪一个。
以上方式仅允许排除掉其它方法,as 操作符可以 为某个方法引入别名。 注意,as 操作符不会对方法进行重命名,也不会影响其方法。
例如,创建AB两个trait,并在里面创建两个同名方法:
trait A{
public function smallTalk(){
echo 'a';
}
public function bigTalk(){
echo "A";
}
}
trait B{
public function smallTalk(){
echo 'b';
}
public function bigTalk(){
echo "B";
}
}
在一个类中使用AB两个trait并解决冲突:
class Aliased_Talker{
use A,B{
//用insteadof明确使用哪个:
B::smallTalk insteadof A;
A::bigTalk insteadof B;
//用as给方法起个别名:
B::bigTalk as talk;
}
}
实验解决冲突的成果:
$test5 = new Aliased_Talker();
$test5->bigTalk();//A
$test5->talk();//B