(40)面向对象的三大特性继承性(41)面向对象中常用的关键字和魔术方法

来源:互联网 发布:站长交易第一平台源码 编辑:程序博客网 时间:2024/03/29 09:13
(40)面向对象的三大特性继承性
继承性: 
 1. 他也是面向对象的三大特性之一
 2. 开放性、可扩充性
 3. 增加代码的重用性
 4. 提高了软件的可维护性
 5. 继承就是用子类去”扩展“父类
 6. 鸟--- 砖头


 如果没有继承性会有哪些影响:
1、重复定义了n个属性和方法
2、如果需要添加一个功能,几个类都分别添加
3、如果需要修改的内容几个类都要修改


有继承性的相对不同之处:
1、如果两个或以上的类中,有公共的部分就可以共享,共享的就可以作为父类
2、如果所有的类都需要添加同一个功能,只要在父类中添加所有子类都多一个功能
3、如果在父类中修改一个成员,则所有子类中的成员也被修改。




 C++ 属于多继承, 同一个类可以有多个父类
 
 PHP和Java属于单继承, 同一个类只能有一个父类
 
 不管多继承的还是单继承的都可以有多个子类


 
 只要你在设计两个类时,有可以共享的成员,就将可以共享的内容拿出来,单独作为一个基类使用
 
       父类----也称为-----基类
       子类-----也称为--------派生类
 
 将类拆成多个子类的形式,这样代码不浪费      
 
 
  作用:
 
  一、类继承的应用
 
  1.声明一个子类,使用 extends 关键字 去继承(扩展)一个父类
 
  2.子类可以从父类,继承所有的内容,包括成员属性,成员方法, 构造方法 ..., 在子类中都可以直接使用
 
  3. 类之间的层次关系设计好
 
  二、访问类型控制
  虽然子类可以从父类中继承所有内容,但private的成员, 只能在本类中使用, 子类中也不能使用
 
封装时,即可以让自己类的内部可以访问,也让子类可以用,但类的外部不能使用,private ----换成----> protected


private只能在自己类中用
protected除了自己类中还可以在子类中使用
public在自己类和子类还有外面都可以使用,所以它的优先级也是最高的。(默认的)


  三、子类中重载父类的方法(在PHP中没有重载这个概念的,但是在java和C++都有)
 重载:也就是函数名相同(方法名相同),参数类型或参数个数不同
   function  add(int a,int b){
        return  a+b;
    }
   
   function  add(float a,float b){
        return  a+b;
    }
不同的类型执行不同的方法。为什么瑞类型语言PHP不行呢?因为
function  add($a,$b);$a和$b可以赋予任何类型的数值,而且php还不限制参数个数


    1. 子类可以声明和父类相同的方法名,即子类覆盖了父类中同名的方法。那么为什么这样做?
 
    鸟类---鸵鸟(飞方法), 在鸵鸟类中将 “飞的方法改写”
 
    子类的方法对父方法的扩展
 
    在子类中 调用 父类中 被覆盖的方法  
 
  对象->成员  类::成员
 
    父类名::方法名()   //把父类的方法拿过来
    parent::方法名()   //代表父类的类名,来表示父类的方法。用parent来代表父类的类名,不管父类的类名改不改都不影响子类的程序和父类名。


 私有的成员属性在子类是访问不了的!
 
   在子类中编写构造方法,如果父中也有构造方法一定要去调用一次父类中被覆盖的那个构造方法
 可能有的有用的功能被覆盖掉了。所以如果不调用一次父类方法,可能会导致有的功能不能用。


 注意: 子类中重载的方法,不能低于父类中访问权限,(子类可以访大权限,但不能缩小权限)
 例如:父类是public那么子类一定是public,假如父类是protected那么子类可以放大到public,或者不放大还是protected。当然私有的是不可以的。
 


  class Person1 {
protected $name;    //声明
protected $age;    //私有的成员属性用不了,但是用protected,那么在子类中就可以用私有的成员属性,但是在外面仍然不可以用。
protected $sex;


function __construct($name, $age, $sex){
$this->name=$name;   //先声明在使用,按照以上方法声明,否则不要直接这样用。
$this->sex=$sex;
$this->age=$age;


echo "###################<br>";
}




protected function say(){
echo "我的名-{$this->name}:,我的年龄:{$this->age},我的性别:{$this->sex}.<br>";
}


function eat(){
echo "wwwwwwwwwwwwwwww";
}


function run(){

}
  }


  class Student extends Person1 {    //学生类用extends继承了人类
 var $school;
function __construct($name, $age, $sex, $school){
parent::__construct($name, $age, $sex);   //调用一下父类的方法,因为有的有用的功能可能完全被子类覆盖了。
$this->school=$school;
}
function study(){
echo "{$this->name}在学习.<br>";

$this->eat();
}


public function say(){
parent::say();   //把父类的方法拿过来,再扩展一些自己的功能
echo "我所在的学校{$this->school}<br>";
}
  
  }


  $s=new Student("lisi", 20, "男", "QingHua");


//  $s->say()





(41)面向对象中常用的关键字和魔术方法
PHP中常用的关键字
 final
  1. final不能修饰成员属性(类中常量不是用这个关键字)
  2. final只能修饰类和方法


  作用:
  使用final修饰的类 不 能被子类继承
  使用final修饰的方法不能被子类去覆盖,也就是不能再去扩展
 
  用来限制类不被继承,方法不被覆盖就使用fianl
 
static(静态)
  1. 使用static可以修饰成员属性和成员方法,不能修饰类
 
  2. 用static修饰的成员属性,可以被同一个类的所有对象共享

3. 静态的数据是存在内存中的数据段中(初使化静态段)而不是堆内存
 
  4. 静态的数据是在类每一次加载时 分配到内存中的, 以后再用到类时就直接从数据段中获取(第一次是声明,第二次就是使用了)
 
  5. 什么是类被加载? 只要在程序中使用到这个类(有这个类名出现)
 
注意: 静态的成员都要使用类名去访问,不用创建对象, 不用对象去访问
 
类名::静态成员  例如:echo person(类名)::$country(成员);
 
  如果在类中使用静态成员, 可以使用 self代表本类的类名($this是类内对象的名字)
 
  6. 静态方法(static修饰的方法), 不能访问非静态的成员(在非静态的方法中,可以访问静态成员用self就可以了)
 
  因为非静态的成员, 就必须用对象来访问,访问内部的成员使用的就是$this
 
  静态方法 不用使用对象来调用, 也就没有对象, $this也就不能代表什么对象, 非静态的成员还必须使用对象
 
  如果你确定一个方法不使用非静态的成员, 则可以将这个方法声明为 静态方法(好处是不能创建对象,直接使用类名就可以访问)
 
 单态的设计模式:让一个类只能生成一个对象;
 静态成员: 类名::成员 , 在类内部访问其它成员 self::成员
 
const
  1. 他只能修饰成员属性
  define('HOST', 'www.xsphp.com');
 
  final int A=10;
 
  2. 类中声明常量属性使用const
 
  3. 命名的方式和我们以前学习 define是一样的效果
 
  4. 访问方式和static静态成员属性是一样(在类外部使用  类名::常量, 在类内部使用  self::常量)
 
  5. 常量一定要在声明时就给初值(常量不允许改值)
 
  $this   self   parent  .... 
 
 
 PHP中常用的魔术方法
 
 __call() 
 
作用: 在调用对象中不存在的方法时就会出现系统报错,然后程序退出。
 
  什么时候自动调用: 就会在调用一个对象中不存的的方法时自动调用
 
  处理一些不存在方法的错误调用
 
  这个方法需要两个参数
 
 __toString()直接输出对象引用时自动调用, 用来快速获取对象的字符串表示的最便捷的方式
例如:function  toString(){
                return“<$this->name>=123456678”;



echo   name
 __clone()
  克隆对象使用clone去处理
 
  原本 (原来的对象)
 
  复本 (复制出来的对象)
 
__clone()就是在克隆对象时自动调用的方法
 
 
 只要一个对象一诞生,就要有初使化的动作, 和构造方法__construct作用相似
 
 在__clone()方法中的 $this关键字,代表的是复本, $that代表原本对象


__autoload()自动包含类的方法
注意: 其它的魔术方法都是在类中添加起作用, 这是一个唯一一个不在类中添加的方法
 
 只要在页面中使用到一个类,只要用到类名就会自动将类名传给这个参数
 
  对象串行化(序列化): 将一个对象转为二进制串 (对象是存储在内存)(将一个大的类型拆分)
 
     1. 将对象长时间存储在数据库或文件中时
     2. 将对象在多个PHP文件中传输时


serialize() : 参数是一个对象, 返回来的就是串行化后的二进制串

 unserialize() : 参数就是对象的二进制串, 返回来的就是新生成的对象
 
__sleep()
 
 是在序列化时自动调用的方法
 
作用:就是可以将一个对象部分串行化


只要这个方法中返回一个数组,数组中有几个成员属性就序列化几个成员属性,如果不加这个方法,则所有成员都被序列化


 __wakeup()
 
 是在反序列化时自动调用的方法
 
也是对象重新诞生的一个过程(__construct(), __clone(),__wakeup())
 
 class Person {
var $name;
protected $age;
protected $sex;
static $country="中国";
const HOST="localhost";


function __construct($name, $age, $sex){
$this->name=$name;
$this->sex=$sex;
$this->age=$age;


echo "###################<br>";
}


function getCountry(){
return self::$country;
}


function setCountry($country){
self::$country=$country;
}


function say(){
echo "我的名-{$this->name}:,我的年龄:{$this->age},我的性别:{$this->sex}.<br>";
}


function eat(){
echo "wwwwwwwwwwwwwwww";
}


function __call($methodName, $args){
echo "你调用的方法{$methodName}(参数:";
print_r($args);
echo ")不存在<br>";
}


static function hello(){
echo "{$this->name} @@@@@@@@@@@@@@<br>";
}


function run(){
echo self::HOST;
}


function __toString(){
return "{$this->name}1234567898765432123567898765432";
}


function __clone(){
$this->name="复本 张三";
$this->age=0;
}


function __sleep(){
return array("name", "age");
}


function __wakeup(){
$this->name="sanzhang";
$this->age=$this->age+1;
}


function __destruct(){
echo $this->name."<br>";
}
  }