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

==什么是静态方法,为什么有静态方法==
静态方法也叫类方法,静态方法是属于所有对象实例的,形式如下:
- 访问修饰符 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、在实现方法覆盖时候,访问修饰符可以不一致,但是必须满足 子类的访问范围>=父类的访问范围

猜你喜欢

转载自blog.csdn.net/u014449096/article/details/78272931