### 面向对象的三大特征:
**² 封装
抽象:简单理解,我们在定义一个类的时候,实际上就是把一类事物的共有属性和行为提取出来,形成一个物理模型,这种研究问题的方法叫做抽象。
封装:就是把抽象的数据和对数据的操作封装在一起,数据被保护在内部,程序的其他部分只有通过被授权的操作(成员方法),才能对数据进行操作。
那么在PHP中如何实现这种类型的控制呢!请看下面的小程序,不能随便查看人的年龄,工资等隐私。
访问控制修饰符
PHP提供三种访问控制修饰符皓来控制方法和变量(属性)的访问权限。
<table border="1" cellspacing="0" cellpadding="0"><tbody><tr><td valign="top"><p align="left">Public</p></td><td valign="top"><p align="left">表示全局,类内部,外部和子类都可以访问</p></td></tr><tr><td valign="top"><p align="left">protected</p></td><td valign="top"><p align="left">表示受保护的,只有本类和子类可以访问</p></td></tr><tr><td valign="top"><p align="left">Private</p></td><td valign="top"><p align="left">表示私有的,只有本类的内部可以使用</p></td></tr></tbody></table>
下面是总结的使用范围
<table border="1" cellspacing="0" cellpadding="0"><tbody><tr><td valign="top"><p align="left"> </p></td><td valign="top"><p align="left">Public</p></td><td valign="top"><p align="left">Protected</p></td><td valign="top"><p align="left">private</p></td></tr><tr><td valign="top"><p align="left">全局</p></td><td valign="top"><p align="left"><span style="background:red">※</span></p></td><td valign="top"><p align="left"> </p></td><td valign="top"><p align="left"> </p></td></tr><tr><td valign="top"><p align="left">继承</p></td><td valign="top"><p align="left"><span style="background:red">※</span></p></td><td valign="top"><p align="left"><span style="background:red">※</span></p></td><td valign="top"><p align="left"><span style="background:red"> </span></p></td></tr><tr><td valign="top"><p align="left">本类</p></td><td valign="top"><p align="left"><span style="background:red">※</span></p></td><td valign="top"><p align="left"><span style="background:red">※</span></p></td><td valign="top"><p align="left"><span style="background:red">※</span></p></td></tr></tbody></table>
Ø 如果一个方法没有设置访问修饰符,默认是public
Ø 属性必须制定访问修饰符
Ø 成员内方法之间也可以相互调用,但是使用this
~~~
function test1(){
$this->test2();
}
private function test2(){
echo "我是一名程序猿,转行学习,求大家多多指教";
}
~~~
###如何访问protectedprivae修饰变量?
~~~
//通过下面的方法来访问protected private变量
//查看薪水:
public function getSalary($name,$passwd){
if($name=="jsh" && $passwd=="1234567a"){
echo $this->salary;
}else{
echo "输入用户名或密码错误,无法访问";
}
}
//修改年龄
public function setAge($age){
if($age>0&&$age<120){
$this->age=$age;
}else{
echo "设置年龄不符合要求";
}
}
//查看年龄
public function getAge($name,$passwd){
if($name=="jsh" && $passwd=="1234567a"){
echo $this->age;
}else{
echo "输入用户名或密码错误,无法访问";
}
}
~~~
Ø 从上面可以很容易看出,对访问protected private修饰的变量提供了上述的访问方法,并且增加了验证!
PHP设计者提供下面的方法:
~~~
<?php
class A{
private $n1;
private $n2;
private $n3;
private $n4;
//使用__set方法来设置所有的属性
function __set($pro_name,$pro_val){
$this->pro_name=$pro_val;
}
//使用__get方法来获得所有的属性
function __get($pro_name){
if(isset($pro_name)){
return $this->pro_name;
}else{
return null;
}
}
}
$a1=new A();
$a1->n1="hello || ";
echo $a1->n1;
$a1->n2=222;
echo $a1->n2;
//结果:hello || 222
?>
~~~
上面的方法和public 使用时一样的,所以基本来对我们编程来说这种写法没有什么用途的。
代码一:
~~~
<?php
//封装实例:
class Person{
public $name;
protected $age;
private $salary;
public function __construct($name,$age,$salary){
$this->name=$name;
$this->age=$age;
$this->salary=$salary;
}
//成员方法
public function showInfo(){
//三种访问控制修饰符号在本类中都可以访问
echo $this->name."||".$this->age."||".$this->salary;
}
//通过下面的方法来访问protected private变量
//查看薪水:
public function getSalary($name,$passwd){
if($name=="jsh" && $passwd=="1234567a"){
echo $this->salary;
}else{
echo "输入用户名或密码错误,无法访问";
}
}
//修改年龄
public function setAge($age){
if($age>0&&$age<120){
$this->age=$age;
}else{
echo "设置年龄不符合要求";
}
}
//查看年龄
public function getAge($name,$passwd){
if($name=="jsh" && $passwd=="1234567a"){
echo $this->age;
}else{
echo "输入用户名或密码错误,无法访问";
}
}
function test1(){
$this->test2();
}
private function test2(){
echo "我是一名程序猿,转行学习,求大家多多指教";
}
}
$p1=new Person("阿辉",29,1000);
//访问阿辉的年龄及薪水,有如下错误!private 是不能被外部访问的
// echo $p1->age.$p1->salary;
//Fatal error: Cannot access private property Person::$age in /var/myphp/class/fengzhuang.php on line 18
//查看薪水
echo $p1->name."薪水是:";
$p1->getSalary("jsh","1234567a");
echo "<br/>";
//设置年龄,查看年龄
$p1->setAge(28);
echo $p1->name."年龄是:";
$p1->getAge("jsh","1234567a");
echo "<br/>";
$p1->test1();
/***********输出结果***********
*阿辉薪水是:1000
*阿辉年龄是:28
*我是一名程序猿,转行学习,求大家多多指教
**************************/
?>
~~~
### 继承:
~~~
<?php
//应用场景,开发一套学生管理系统(Pupil Graduate,...)
/***************************
class Pupil{
public $name;
private $age;
private $grade;
//构造方法
public function __construct($name,$age,$grade){
$this->name=$name;
$this->age=$age;
$this->grade=$grade;
}
//输入学生信息的方法
public function showInfo(){
echo $this->name."||".$this->age."||".$this->grade."<br/>";
}
//考试方法
public function testing(){
echo "小学生考试<br/>";
}
}
class Graduate{
public $name;
private $age;
private $grade;
//构造方法
public function __construct($name,$age,$grade){
$this->name=$name;
$this->age=$age;
$this->grade=$grade;
}
//输入学生信息的方法
public function showInfo(){
echo $this->name."||".$this->age."||".$this->grade."<br/>";
}
//考试方法
public function testing(){
echo "研究生考试<br/>";
}
}
//考虑上述有很多共同点,不如年龄,名字,分数等等,这样就造成
//代码的复用性不高,代码的可维护性比较低,
****************************/
//解决方案,引入继承方法。
//父类
class Stu{
public $name;
private $age;
private $grade;
//构造方法
public function __construct($name,$age,$grade){
$this->name=$name;
$this->age=$age;
$this->grade=$grade;
}
//输入学生信息的方法
public function showInfo(){
echo $this->name."||".$this->age."||".$this->grade."<br/>";
}
}
//子类 小学生
class Pupil extends Stu{
//考试方法
public function testing(){
echo "小学生考试<br/>";
}
}
//子类,研究生
class Graduate extends Stu{
//考试方法
public function testing(){
echo "研究生考试<br/>";
}
}
$pupil1=new Pupil("阿辉",28,99);
$pupil1->showInfo();
$pupil1->testing();
$gra1=new Graduate("佩佩",29,89);
$gra1->showInfo();
$gra1->testing();
/******输出结果****
*阿辉||28||99
*小学生考试
*佩佩||29||89
*研究生考试
**************/
?>
~~~
上面的代码,我们简单了解到继承方法的使用,引入继承方法的好处,可以解决代码复用,让我们的变成更加靠近人类的思维,当多个了存在相同的属性和方法是,可以从这些类中抽象出父类,在父类中定义这些相同的类或者方法,所有的子类不需要重新定义这些属性和方法,只需要通过
class 子类名 extends 父类名{
} 这样,子类就会自动永远父类定义的属性和方法。
细节讨论:
1)父类的那些属性(变量)、方法被子类继承了?
父类的public修饰符的属性和方法,protected修饰符的属性和方法被子类继承了。父类的private修饰符的属性和方法不能被子类继承。
2) 子类最多只能继承一个父类(直接继承)
3) 子类可以继承去父类的public protected修饰的属性和函数方法
4)在创建某个子类对象时,默认情况下不会自动调用其父类的构造方法,这点和JAVA不同。
~~~
<?php
//继承方法测试
class A{
public $name=90;
public function __construct(){
echo "A __construct<br/>";
}
}
class B extends A{
public function ___construct(){
echo "B __construct<br/>";
}
}
$b=new B();
?>
~~~
上面的PHP会输出什么? 居然输出的是B __construct
5) 如果子类需要访问父类的方法(构造、成员方法,方法修饰符是public,protected)可以使用父类::方法名 或者parent::方法名)来完成。
~~~
<?php
//继承方法测试
class A{
public $name=90;
public function __construct(){
echo "A __construct<br/>";
}
}
class B extends A{
public function __construct(){
//A::__construct();
parent::__construct();
}
}
$b=new B();
?>
~~~
### 重载
基本概念: 函数名一样,可以通过函数的参数个数或者参数类型的不同,达到嗲用同意函数名,但可以区分不同的函数。
1)PHP中 默认是不知道方法重载的
2)PHP可以 通过__call魔术方法,模拟一个方向的效果。
~~~
<?php
class A{
public function test1($p){
echo "输入一个参数<br/>";
var_dump($p);
echo "<br/>";
}
public function test2($p){
echo "输入二个参数<br/>";
var_dump($p);
}
function __call($method,$p){
if($method == "test"){
if(count($p)==1){
$this->test1($p);
}else if (count($p)==2){
$this->test2($p);
}
}
}
}
$a=new A();
$a->test(1);
$a->test(1,2);
/*
输入一个参数
array(1) { [0]=> int(1) }
输入二个参数
array(2) { [0]=> int(1) [1]=> int(2)
*/
?>
~~~
### 方法覆盖:
~~~
<?php
//抽象一个动物类
class Animal{
public $name;
protected $price;
function cry(){
echo "不知道怎么叫";
}
}
class Dog extends Animal{
//覆盖(逻辑上的覆盖)
function cry(){
echo "小狗叫。。。。";
}
}
class Pig extends Animal{
function cry(){
echo "小猪叫。。。。";
}
}
//创建一只狗
$dog1=new Dog();
$dog1->cry();
$pig1=new Pig();
$pig1->cry();
?>
~~~
### 方法重写细节讨论
1、 要实现重写,要求子类的那个方法的名字和参数列表一模一样
2、如果子类要去调用父类的某个方法,前提是父类方法必须要public或者protected。在子类中可以使用
父类::方法名 或者parent::方法名)来完成。
3、在是先方法覆盖的时候,访问修饰符可以不一样。但是必须满足,子类的范围一定要大于等于父类的范围
² 抽象类
为什么设计抽象类这个技术
1、在实际开饭中,我们可能有这样一种类,是其他类的父类,但是它本身并不需要实例化。主要用于子类来继承。这样可以达到代码复用作用,同时利于项目设计者设计类
2、如果一个类使用abstract修饰了,这个类就是抽象类
如果一个方法被abstract修饰了,这个抽象方法就不能有方法体;
1、 抽象类可以没有抽象方法,同时还有有实现了的方法,可以被子类继承。
2、 一个类中,只有有抽象方法,则该类必须声明为抽象类,否则会报错!
3、 如果一个类继承了某个抽象类,则要求子类必须实现从父类继承的所有抽象类,或者子类也是抽象类。
~~~
<?php
//抽象一个动物类
abstract class Animal{
public $name;
protected $price;
//这个方法没有方法体,主要为了给子类来覆盖
abstract public function cry();
}
class Dog extends Animal{
//覆盖(逻辑上的覆盖)
function cry(){
echo "小狗叫12。。。。";
}
}
class Pig extends Animal{
function cry(){
echo "小猪叫1234。。。。";
}
}
//创建一只狗
$dog1=new Dog();
$dog1->cry();
$pig1=new Pig();
$pig1->cry();
?>
~~~
- 前言
- HTML(第一天)
- HTML(第二天)
- DIV+CSS(第一天)
- DIV+CSS(第二天)
- DIV+CSS(第三天)
- DIV+CSS(第四天)
- PHP开发环境配置说明
- PHP基础数据类型及运算符介绍
- 走进PHP函数
- 走进位运算
- 走进数组及相关数组函数
- 面向对象的编程(类与对象)
- 面向对象的编程(类成员方法用法)
- 构造方法,析构方法
- static,global用法
- 静态方法
- 面向对象的编程方法
- 接口方法
- 接口VS继承、final、const
- 错误及异常处理机制、错误日志
- HTTP协议深度剖析
- 文件下载
- PHP数据库编程
- 数据库编程(2)
- 超全局变量
- Zend studio 开发环境入门
- 雇员管理系统(1)
- 雇员管理系统(2)
- 会话技术(cookie session)
- 会话技术 session场景使用介绍!
- PHP.in中session和cookie的配置说明
- PHP文件编程
- 报表及绘图技术
- 报表及绘图技术(jpgraph库使用,Linux安装及配置说明)
- XML基本语法及DTD介绍
- XML编程(Dom技术)
- XML编程(Xpath技术,simpleXml技术)基础入门
- 网上支付平台PHP版本
- javascript基础入门