面向对象三大特性:封装-- 继承-- 多态
一、封装性:
目的:为了使类更加安全。
做法:1设置私有成员
2在类中建方法,访问私有成员
3在方法里边加控制(if)
私有成员访问的两种方法:
方法一:set(可写) get(可读)做方法(可读可写)
class Person { private $name; private $sex; private $age;//全部使用private进行封装 function __construct($n,$s,$a)
{ $this->name=$n; $this->sex=$s; $this->age=$a; }
//获取成员name的值 function Getname() { return $this->name; }
//设置性别,并加控制 function Setsex($s) { if($s=="男"||$s=="女")//对输入加控制,只有输入合法字符,才能对私有成员赋值; { $this->sex=$s; } }
//设置年龄,并加控制,防止输入非法字符 function Setage($a) { if($a>18&&$a<80) { $this->age=$a; } } function say() { echo "我的名字是".$this->name.",性别:".$this->sex.",年龄:".$this->age; } } //通过构造函数给这个对象赋值 $ren=new Person("张三","男","30"); var_dump($ren);
//获取对象的名字 echo $ren->Getname();
//改变对象的性别 $ren->Setsex("女"); var_dump($ren);
//改变对象的年龄 //1.给个非法,是改变不了的 $ren->Setage(100); var_dump($ren);
//2.输入合法 $ren->Setage(50); var_dump($ren);
//调用say() echo $ren->say();
方法二:用__SET(变量名,变量值) 、__GET(变量名) 魔术方法
class Person { private $name; private $sex; private $age;//全部使用private进行封装 function __construct($n,$s,$a) { $this->name=$n; $this->sex=$s; $this->age=$a; }
function __get($aa) { if($aa=="sex")//如果获取的是性别,则返回“保密”、、注意这里是不带$符号的 { return "保密"; } else if($aa=="age")//如果获取的是年龄,年龄大于100时,减去10后再返回 { if($this->age>100) { return $this->age-10; } else //年龄不大于100时,直接返回 { return $this->age; } } else //如果获取的是姓名,则直接返回 { return $this->name; } }
function __set($n,$v) { if($n=="sex") { if(!$v=="男"||$v=="女") { return; } } else if("age") { if($v>150||$v<0) { return; } } else { $this->$n=$v; } } } $ren=new Person("张三","男",30); //__get()自动调用,可以直接获取。 echo $ren->name."<br>"; echo $ren->sex."<br>"; echo $ren->age."<br>";
//__set()自动调用 //设置合法字符可以更改 $ren->name="张四"; $ren->age=50; $ren->sex="男"; var_dump($ren);
//设置非法字符不可以更改 $ren->age=500; $ren->sex="123"; var_dump($ren);
连续调用的一个例子,赋值之后,返回一个对象
class Person { private $name; function say() { echo $this->name."说话"; } function SetName($n) { $this->name = $n; return $this;//返回的是$ren->SetName("张三"),并把它看成一个对象。 } } $ren = new Person(); $ren->SetName("张三")->say();//$ren->SetName("张三")因为上面的return $this;返回了,并成为了一个对象
二、继承性:关键字(extends) 子类可以继承父类的一切,特点:单继承,一个子类只能有一个父类,一个父类可以有多个子类
//子类可以继承父类的一切
//重写:override
//特点:单继承,一个子类只能有一个父类,一个父类可以派生多个子类
继承例子:
class person { var $name; var $sex; var $age; function __construct($a,$b,$c) { $this->name=$a; $this->sex=$b; $this->age=$c; } function say() { echo "我的名字是".$this->name,"性别".$this->sex,"年龄".$this->age; } function run() { echo $this->name."正在走路"; } } class student extends person //student继承于person的成员变量和成员方法 { var $school; function study() { echo $this->name."正在".$this->school."学习"; } } class teacher extends student //teacher继承于student,由于student继承person,所以teacher也继承person的成员变量和成员方法 { var $gongzi; function teaching() { echo $this->name."正在".$this->school."教学"; } } $teacher1=new teacher("李四","女",30); $teacher1->school="sdu+"; $teacher1->gongzi=3000; $teacher1->say(); $teacher1->study(); $teacher1->teaching();
对父类方法的重写例子(即改变原来在父类中定义的量):强类型语言中用override
class person { protected $name; protected $sex; protected $age;
function __construct($a,$b,$c) { $this->name=$a; $this->sex=$b; $this->age=$c; }
function say() { echo "我的名字是:".$this->name."性别".$this->sex."年龄".$this->age; } } class student extends person { private $school; //覆盖父类的构造方法,对成员变量进行重写 function __construct($d,$e,$f,$g) { $this->name=$d; $this->sex=$e; $this->age=$f; $this->school=$g; }
function study() { echo $this->name."正在".$this->school."学习"; }
function say() { echo "我的名字是".$this->name."性别:".$this->sex."年龄".$this->age."正在".$this->school."学习"; } } $ren=new person("张三","男",30); var_dump($ren); $student=new student("李四","女",20,"胜利中学"); var_dump($student); $student->say();
子类对父类进行重载的例子(即对父类中定义的量拿过来):php中用parent::方法名(). 强类型语言中用关键字 overload 重载
class person { protected $name; protected $sex; protected $age; function __construct($a,$b,$c) { $this->name=$a; $this->sex=$b; $this->age=$c; } function say() { echo "我的名字是".$this->name."性别".$this->sex."年龄".$this->age; } }
class student extends person { private $school; function __construct($d,$e,$f,$g) //引用过来父类的构造函数,并修改 { parent::__construct($d,$e,$f,$g); $this->school=$g; } function study() { echo $this->name."正在".$this->school."学习"; } function say() { parent::say(); //引用过来父类的say()方法,并在下面添加一段 echo "在".$this->school."学校上学"; } } $ren=new person("张三","男",40); var_dump($ren); $student1=new student("李四","女",20,"胜利中学"); var_dump($student1); $student1->say();
重载可以使类里面的某个方法产生多种效果,根据传入的参数不同,可以执行不同的逻辑
重载也是多态的一种,编译多态
三、多态性:
当父类引用指向子类实例的时候,由于子类对父类的方法进行了重写,父类引用在调用该方法的时候表现出的不同,称为多态
运行多态
条件
1.要有继承
2.父类引用指向子类实例
3.要有重写
4.调重写的方法
父类 /* class Ren { public virtual string Say() { return "说话"; } } //子类 class China : Ren { public override string Say() { return "你好"; } } //子类 class America : Ren { public override string Say() { return "hello"; } } //父类引用r指向子类实例 Ren r = new America(); MessageBox.Show(r.Say()); r = new China(); MessageBox.Show(r.Say()); //子类的对象可以代替父类的对象 America a = new America(); MessageBox.Show(Eat(a)); //怪兽吃人,需要一个人的参数 public string Eat(Ren r) { return "这个人味道不错!"; } */