第71+72+73+74讲 static静态方法+面向对象三大特征(1)

来源:互联网 发布:ff14猫女捏脸数据 御姐 编辑:程序博客网 时间:2024/06/14 07:04

==什么是静态方法,为什么有静态方法==
静态方法也叫类方法,静态方法是属于所有对象实例的,形式如下:
- 访问修饰符 static 方法名 (){}
- 注意:静态方法中不能访问非静态属性(变量)
- 在类外部 类名::方法名 或者 对象名->方法名
- 在类内部 self::方法名 或者 类名::方法名

统计总费用

<?php    class Student{        public static $fee=0;        public $name;        function __construct($name){            $this->name=$name;        }        public static function enterSchool($fe){            self::$fee+=$fe;        }        public static function getTotalMoney(){            return self::$fee;        }    }    $student1 = new Student("张三");    $student1->enterSchool(100);    //Student::enterSchool(100);    $student2 = new Student("李四");    $student2->enterSchool(100);    //Student::enterSchool(100);    echo "总学费是".Student::getTotalMoney();?>

静态变量小结:

1.什么时候需要用静态变量
案例:定义学生类,统计学生共交了多少钱 如上代码用类变量属于公共的属性
2.静态变量与普通变量的区别:
  • (1)加上static称为类变量或静态变量,否则称为实例变量
  • (2)类变量(静态变量)是与类相关的,公共属性
  • (3)实例变量属于每个对象个体的属性

- (4)类变量(静态变量)可以通过 类名::静态变量名 或 self::静态变量名 直接访问

静态方法(类方法)小结:

  • 静态方法属于与类相关的,公共的方法
  • 实例方法属于每个对象个体的方法

- 静态方法可以通过类名:静态方法名 或 self::静态方法名 直接访问

面向对象 跟 java 一致

  • ==封装==:把抽取出来的数据和对数据的操作封装在一起,数据被保护在内部,程序的其他部分只有通过被授权的操作,才能对数据进行访问。
  • ==继承==
  • ==多态==
<?php    <?php    class Person{        public $name;        private $age;        private $money;        public function __construct($name,$age,$money){            $this->name=$name;            $this->age=$age;            $this->money=$money;        }        public function getAge(){            return $this->age;        }        public function isGetName(){            //return getName();//这样写运行会发现提示Call to undefined function getName()             return $this->getName();//这样调用就没毛病        }        public function getName(){            return $this->name;        }    }    $p1 = new Person("张三",30,1000);    //print $p1->age;//私有之后没法直接调用。    print $p1->getAge();//可以通过方法调用    print $p1->isGetName();?>?>

如上自己定义set get 赋值 取值

php 自己的__set __get方法 好恶心 还不如自己写方法(所谓的魔术方法。。尴尬)

<?php    class A{        private $n1;        private $n2;        private $n3;        public function __construct(){        }        //__set赋值        public function __set($pro_name,$pro_value){            $this->pro_name=$pro_value;        }        //__get取值        public function __get($pro_name){            if(isset($pro_name)){                return $this->pro_name;            }else{                return "12";            }        }    }    $a1 = new A();    $a1->n1="测试";    print $a1->n1;?>
结果:输出了---> 测试

==继承==

结论:
- 1、父类的 public 、 protected 的属性和方法被继承,private
的属性和方法没有被继承

  • 2、总计 一个类只能继承一个类(直接继承),如果希望集成多个类,那么如下代码所示:

php跟java一样都只能单一继承父类

但是 如果要一个子类继承多个父类 可以 进行多次继承
such as

class A{}class B extends A{}class C extends B{}

如上C类相当于同时继承了A类B类

创建子类对象时候 默认情况下不会自动调用父类的构造方法(这个跟java是不一样的)

<?php    class Su{        public $name=1;        public $age=2;        public function __construct(){            print "a____construct<br/>";        }        public function ShowInfo(){            print "test<br>";        }    }    class Child extends Su{        public function __construct(){            parent::__construct();//也可以在子类构造方法中用这种方法调用父类的构造方法,这个叫显示的调用父类的构造方法---->调用就显示 不调用就没有 写法正确            Su::__construct();//也可以这么调用父类的构造方法; 写法正确            //PARENT::__construct();//parent 不能写成大写 写法错误 ---            print "b____construct<br/>";            parent::ShowInfo();//在构造方法中可以用此种方法直接调用父类的方法,,写法正确 可以调用公有的 但是 不能调用私有的        }        public function showChild(){            print parent::showInfo();        }    }    $child = new Child();//实例化子类不会调用 父类构造方法    //$child1 = new Su();//转型后可以可以看到调用了 父类构造方法    //$child->showChild();    //print $child->name." || ".$child->age;//子类继承父类属性

如果希望调用父类的构造方法,或者其他的构造方法(public/protected),可以如下处理

4.1  类名::方法名 或者 parent::方法名

当一个子类的方法和父类的方法完全一样(public protected),称为方法的覆盖/重写

==面向对象的重载==

方法的重载:重载是类的多态的一种实现

重载 方法名相同 参数不同 重写 方法名参数 完全相同

notice : 目前在php中暂时不支持重载

示例代码:

<?php    class OverLoad{        public $name;        public function __construct(){        }        public function test(){            print "1————";        }        public function test($a){            print "2____";        }    }    $test = new OverLoad();?>

如上代码运行后提示 不能够声明 test()在12行 因为上边已经声明了一个test(),12行的是test($a),如此可知目前php是不支持重载的。在php7里边不知道是否支持

Fatal error: Cannot redeclare OverLoad::test() in D:\phpStudy\WWW\OverLoad.php on line 12

解决方案:

<?php    class OverLoad{        public $name;        public function __construct(){        }        public function test1(){            print "1————<br/>";        }        public function test2($a){            print "2____<br/>";        }        public function __call($method,$p){            if($method=="test"){                if(count($p)==1){                    $this->test1($p);                }else if(count($p)==2){                    $this->test2($p);                }else if(count($p)==3){                    $this->test1($p);                    $this->test2($p);                }            }        }    }    $test = new OverLoad();    $test->test(1,2);?>

如上代码所示:
__call 用这个魔术方法可以解决,但是 感觉这么写还不如直接定义不同方法名直接调用来的干脆,何必呢。构造方法不能传参的话,就通过set get 设置啊。也没毛病。 目前官方都不推荐用__call来搞。

重载总结:

1、php5中默认情况下不支持方法的重载
2、php5可以用__call魔术方法,模拟一个重载方法的效果。

方法的重写/方法的覆盖

与java一致方法名参数要完全相同
在实现方法的重写的时候 子类的访问修饰符 访问范围 >= 父类的访问修饰符
也就是说 ==重写的访问修饰符可以不一样,但是得注意这个访问修饰符的范围==

总结:
- 1、实现重写 要子类的方法名和参数列表一模一样
- 2、子类调用父类的 public / protected 方法可以使用 parent::方法名(参数),或者 父类类名::方法名(参数)

- 3、在实现方法覆盖时候,访问修饰符可以不一致,但是必须满足 子类的访问范围>=父类的访问范围

原创粉丝点击