<?php
/*
*PHP双冒号::(作用域限定操作符)的用法
*可以访问静态、const和类中重写的属性与方法。
*在类本体内,可以使用“self::常量名”或者“”
*体外可以使用“类名::常量名”
*在PHP 5.3.0,可以使用变量代替类名。但该变量的值不能为关键字self, parent 或static。
*一般是define在类外定义常量,const在类内定义常量但是php5.3以上支持类外通过const定义常量
*define与const的区别:
* 1.const不能再条件语句中定义常量,但是define是可以的
* 2.const采用一个普通的常量名称,define可以采用表达式作为名称
* 3.const只能接受静态的标量,而define可以采用任何表达式。
*/
静态属性、方法:
1、不需要实例化就可以直接用self::静态方法名”或者“”类外可以使用“类名::静态方法名”调用;
2、静态属性、方法一个公用不管实例化多少次,静态方法都直接加载到内存的一个固定空间里,在内存中只有一份,为所有的实例共用;普通方法 你的方法调用需要先实例化类 然后 这部操作会在 内存中 另开辟空间 来存放这部分空间也省掉了~就是楼上说的 省资源
3、static 的属性和方法,只能访问static的属性和方法,不能类访问非静态的属性和方法。因为静态属性和方法被创建时,可能还没有任何这个类的实例可以被调用。
4、静态方法不能调用非静态属性。因为非静态属性需要实例化后,存放在对象里;
5、静态方法可以调用非静态方法,使用 self 关键词。php里,一个方法被self:: 后,它就自动转变为静态方法;
//1常量在类里定义外部访问(调用)
class person
{
const CONST_VALUE = 'person类的常量值;';
}
//将类名赋给变量
$classname='person';
//在PHP 5.3.0,可以使用变量代替类名。
echo "外部用变量名代替类名后调用".$classname::CONST_VALUE;
//外部调用常量
echo "外部调用".person::CONST_VALUE;
echo "<br />";
//外部用变量名代替类名后调用person类的常量值
//外部调用person类的常量值
echo "==============================================================================<br />";
class person2
{
const CONST_VALUE = 'person2类的常量值;';
//1常量在类里定义内部访问(调用)
public function demofunction()
{
self::CONST_VALUE;
}
}
$a=new person2();
$a->demofunction();
echo $a::CONST_VALUE."
"; // PHP 5.3.0之后
//person2类的常量值;
echo "<pre>===================在类定义外部使用==========================================<pre>";
class person3
{
const CONST_VALUE = 'person3类的常量值';
}
class boy3 extends person3
{
public static $name3 = 'lichihua';//静态属性
public static function first()//静态方法
{
echo parent::CONST_VALUE.";";//调用父类的常量
echo self::$name3.";";//调用类本身的属性
}
}
boy3::first();
//person3类的常量值;
//lichihua;
echo "<pre>===================调用parent的方法==========================================<pre>";
class person4
{
protected function eat4()
{
echo "person::eat()
;";
}
}
class boy4 extends person4
{
public function eat4()
{
parent::eat4();
echo "boy::eat;";
}
}
$b = new boy4();
$b->eat4();
//person::eat();
//boy::eat()
echo "<br />===================使用作用域限定符????==========================================<pre>";
//一般用于在B类对象中使用A类对象的属性/方法!
class Apple
{
public function showColor()
{
return $this->color;
}
}
class Banana
{
public $color;
public function __construct()
{
$this->color = "Banana is yellow";
}
public function GetColor()
{
return Apple::showColor();
}
}
$banana = new Banana;
echo $banana->GetColor();
//Banana is yellow
echo "<br />===================调用基类的方法????==========================================<pre>";
class Fruit2{
static function color(){
return"color";
}
static function showColor(){
echo "输出颜色(show)".self::color();
}
}
class Apple2 extends Fruit2
{
static function color(){
return "red";
}
}
Apple2::showColor();
//输出颜色(show)color
?>
==========================================================================================================================
<?php
class MyClass
{
const CONST_VALUE = 'MyClass 的 常量值'."<br />";
protected function myFunc() {
echo "MyClass中的方法<br />";
}
}
//下面两种方法都可以调用类常量、
//法1/////////////////////////////////////////////////////////////
//// $classname = 'MyClass'; ////
//// echo $classname::CONST_VALUE; // 自 PHP 5.3.0 起 ////
//// ////
//////////////////////////////////////////////////////////////
///法2
echo MyClass::CONST_VALUE;
class OtherClass extends MyClass
{
public static $my_static = 'OtherClass类的静态属性值';
public static function doubleColon() {
echo "OtherClass类里调用父类(MyClass)的常量:".parent::CONST_VALUE . "
";
echo self::$my_static . "<br />";
}
}
//$classname = 'OtherClass';
//echo $classname::doubleColon(); // 自 PHP 5.3.0 起
OtherClass::doubleColon();
//当一个子类覆盖其父类中的方法时,PHP 不会调用父类中已被覆盖的方法。是否调用父类的方法取决于子类。这种机制也作用于构造函数和析构函数,重载以及魔术方法。
class OtherClass2 extends MyClass
{
// 覆盖了父类的定义
public function myFunc()
{
// 但还是可以调用父类中被覆盖的方法
echo"被子类覆盖的父类方法如果在子类单读用parent::方法名还是可以调用的例这里输出了:";
parent::myFunc();
echo "OtherClass2中的方法;这里的子类覆盖了父类的方法,这一行如果没出现(MyClass中的方法)这句就是代表没有调用被覆盖的方法<br />";
}
}
$class = new OtherClass2();
$class->myFunc();//这里的子类是外部调用方法的所以这里必须实例化和调用方法才能输出
//类常量,类属性(静态)和类函数(静态)都可以共享相同的名称,并使用双冒号访问例如下
class A
{
public static $B="1";//类的静态属性
const B = "2";//类常量
public static function B(){
return"3";
} //类的静态函数
//静态函数为什么会用return呢??
}
echo A::$B.A::B.A::B()."<br />";
class cA
{
//直接设置属性默认值
protected static $item = 'Foo';
//间接设置默认属性值
protected static $other = 'cA';
public static function method()
{
print self::$item."
"; //各种方式打印foo
print self::$other."
"; // 我们认为这个打印cA但是。。
}
public static function setOther($val)
{
self::$other = $val; // 在这个范围设置一个值.
}
}
class cB extends cA
{
/**
* 尝试给重新属性定义默认值
*/
protected static $item = 'Bar';
public static function setOther($val)
{
self::$other = $val;
}
}
cB::setOther('cB'); // setOther子类父类都有,调用子类cB的方法但是这里没有输出因为子类将父类的方法覆盖了这是子类的setOther方法而子类方法里的内容没有echo等输出所以无输出
//如果是cA::method();则输出Foo和cA;
cB::method(); // 输出Foo和cB子类调用父类的method!子类本身没有method方法(子类继承是可以调用父类里的方法属性的)嘎嘎才试了一下只要父类和子类两个雷利只要一个有setother方法就能输出cB不知什么原理
class cC extends cA
{
/**
* 给属性重新定义默认值
*/
protected static $item = 'Tango';
public static function method()
{
print self::$item."
"; // 各种方式打印foo
print self::$other."
"; // 我们认为这个打印cA但是
}
/**
*现在我们将重新定义setOther()方法,使用cA“self::”只是为了好玩。
*/
}
cC::setOther('cC'); // 应为cC里没有setOther方法所以调用这里调用的的是父类的方法
cC::method(); // 这里子类覆盖了父类,父类方法相当于没有被调用!
/*
注意
如果只调用cC::setOther('cC')那么不会输出因为父类的setOther方法里没有echo等输出;加上就能输出cC
如果只调用cC::method()那么会输出Tango和cB
如果这里的cC::setOther('cC')和cC::method()一起的话会出现Tango和cC并且cC::setOther('cC')必须在cC::method()之前调用否则也会输出Tango和cB
*/
class cD extends cA
{
/**
* 重新定义属性默认值
*/
protected static $item = 'Foxtrot';
/**
* 现在我们将重新定义说有方法来完成这个问题.
*/
}
cD::setOther('cD'); // 这里调用的是cA父类的setOther方法!还是和上面一样无输出!
cD::method(); // 这里调用的是cA父类的method()!输出Foo和cD可以看出cD里的重新定义的$item值没生效还是输出Foo想要输出Foxtrot那么必须在cD子类里定义method方法覆盖掉父类的method方法才行
/*
//获取随机字符串
function generateRandomString($length = 4) {
$characters = '0123456789abcdefghijklmnopqrstuvwxyz';
$randomString = '';
for ($i = 0; $i < $length; $i++) {
$randomString .= $characters[rand(0, strlen($characters) - 1)];
}
return $randomString;
}
echo generateRandomString();
echo"<pre>";
*/
==============================================================================================================================
class A {
const C = 'constA';
public function m() {
echo static::C; //使用'static'的范围值
}
public function n() {
echo self::C;
}
}
class B extends A {
const C = 'constB';
}
$b = new B();
$b->m(); //输出constB可知输出的是子类的常量
$b->n();//输出constA可知输出的是父类的常量