php面向对象程序设计
面向对象的优势:可读性、可重用性、稳定性、维护性、可测试性
简单格式:
[修饰符]class 类名{
[成员属性]
[成员方法]
}
完整格式:
[修饰符]class类名 [extends 父类] [implements 接口 ] {
[成员属性]
[成员方法]
}
成员方法格式:
[修饰符] function 方法名(参数){
[方法体]
[return返回值]
}
修饰符:public protected privatestatic abstract final
$对象名称=new 类名称();
$引用名=new 类名(构造函数)
$引用名->成员属性=赋值
$引用名->成员方法(参数)
class student{
public$name = "ssw";
public$age = "20";
publicfunction study($num,$yum){
return"学习成功";
}
}
$s = new student();
echo $s->name;
echo $s->age;
$s->study();
1、特殊的对象引用 $this(代表对象的一个引用)
class Person{
public $name;
public $sex;
public function say(){
echo "我的名子:".$this->name."性别:".$this->sex;
}
}
$p = new Person();
$p -> name = ssw;
$p -> sex =male;
$p -> say();
显示为:我的名子:ssw性别:male
2、构造方法
(1)是对象创建完成以后、第一个自动调用的方法
(2)方法名比较特殊、可以和类名相同名的方法名、
(3)作用:给对象中的成员属性赋初值
class Person{
public$name;
public$sex;
public$age;
publicfunction Person($n,$s,$a="25"){
$this->name=$n;
$this->sex=$s;
$this->age=$a;
}
publicfunction say(){
echo"我的名子:".$this->name."性别:".$this->sex."年龄:".$this->age;
}
}
$p = new Person(ssw,male,22);
$p1 = new Person(ssw,male);
$p -> say();
显示为:我的名子:ssw性别:male年龄:22
classPerson{
public $name;
public $sex;
public $age;
/*
public functionPerson($n,$s,$a="25"){
$this->name=$n;
$this->sex=$s;
$this->age=$a;
}
*/
public function__construct($n,$s,$a="25"){
$this->name=$n;
$this->sex=$s;
$this->age=$a;
}
public function say(){
echo "我的名子:".$this->name."性别:".$this->sex."年龄:".$this->age;
}
}
$p= new Person(ssw,male,22);
$p1= new Person(ssw,male);
$p-> say();
显示为:我的名子:ssw性别:male年龄:22
3、析构函数
对象释放前调用、没有参数、__destruct
classPerson{
public $name;
public $sex;
public $age;
public function__construct($n,$s,$a="25"){
$this->name=$n;
$this->sex=$s;
$this->age=$a;
}
public function say(){
echo "我的名子:".$this->name."性别:".$this->sex."年龄:".$this->age;
}
function __destruct(){
echo "{$this->name}再见!<br>";
}
}
$p= new Person(ssw,male,22);
$p1= new Person(qzx,male);
显示为:($p在内存中存储为栈。New Person()在内中存储为堆)
qzx再见!
ssw再见!
封装继承多态
4、类的封装性
方法的封装:
(1)、Public()公共的:能在程序的任意地方引用!类内类外都可以引用!
(2)、Protected()保护的:声明的类内能用,继承类能引用!
(3)、Private() 私有的:只能在本类内调用
classPerson{
private $name;
private $age;
private $sex;
function__construct($name="", $age=0, $sex="男"){
$this->name=$name;
$this->age=$age;
$this->sex=$sex;
}
function getAge(){
if($this->age < 20){
return$this->age;
}else if($this->age <30){
return $this->age- 5;
}else{
return 29;
}
}
function __destruct(){
echo "再见:".$this->name;
}
}
$p1= new Person("ssw", 80, "女");
echo$p1->getAge();
显示为:29再见:ssw
5、魔术方法
__get 获取类中私有属性值的时候、自动调用的方法
自动调用、是在直接访问私有成员时、自动调用
classPerson{
private $name;
private $age;
private $sex;
function__get($a){
echo $a."get";
}
}
$p1= new Person("ssw", 80, "女");
$p1->name."<br>";
$p1->age;
显示为:name####age####
classPerson{
private $name;
private $age;
private $sex;
function__construct($name="", $age=0, $sex="男"){
$this->name =$name;
$this->age =$age;
$this->sex =$sex;
}
function__get($a){
echo $this->$a."##";
}
}
$p1= new Person("ssw", 80, "女");
$p1->name;
$p1->age;
$p1->sex;
显示为:ssw##80##女##
__set 为类中私有属性赋值的时候、自动调用的方法
自动调用、是在直接设置私有属性值时、二个参数
class Person{
private $name;
private $age;
private $sex;
function__construct($name="", $age=0, $sex="男"){
$this->name = $name;
$this->age = $age;
$this->sex = $sex;
}
function __set($n,$v){
echo $n."=".$v;
echo "<br>";
echo $this->$n=$v;
}
}
$p1 = newPerson("ssw", 80, "女");
$p1->name="王子";
显示为:name=王子王子
class Person{
private $name;
private $age;
private $sex;
function__construct($name="", $age=0, $sex="男"){
$this->name = $name;
$this->age = $age;
$this->sex = $sex;
}
function __set($n,$v){
if($n=="age"){
if($v < 0 or $v > 100)
return;
}
$this->$n = $v;
}
function __get($pre){
return $this->$pre;
}
}
$p1 = newPerson("ssw", 80, "女");
$p1->name="王子";
$p1->age=109;
$p1->sex="女";
echo $p1->name;
echo $p1->sex;
echo $p1->age;//echo $p1->__get("age");__get不是私有的、外部可以通过对象来调用
显示为:王子女80
__isset()判断类中私有属性是否存在时、自动调用的方法
isset()在使用isset判断一个私有属性是否存在时、自动调用__isset()魔术方法、参数则是属性名称
class Person{
private$name;
private$age;
private$sex;
function__construct($name="",$age=0,$sex="男"){
$this->name=$name;
$this->age=$age;
$this->sex=$sex;
}
function__isset($Pro){
if($Pro=="age")
returnfalse;
returnisset($this->$Pro);
}
}
$p = new Person("ssw",29,"男");
if(isset($p->name)){
echo"这个对象中的name是存在的属性";
}else{
echo"对象p中不存在name值";
}
显示为:这个对象中的name是存在的属性
__unset 销毁类中私有成员时、自动调用的方法
class Person{
private$name;
private$age;
private$sex;
function__construct($name="",$age=0,$sex="男"){
$this->name=$name;
$this->age=$age;
$this->sex=$sex;
}
function__isset($Pro){
if($Pro=="age")
returnfalse;
returnisset($this->$Pro);
}
function__unset($Pro){
if($Pro!="age"){
unset($this->$Pro);
}
}
}
$p = new Person("ssw",29,"男");
unset($p->name);
if(isset($p->name)){
echo"这个对象中的name是存在的属性";
}else{
echo"对象p中不存在name值";
}
显示为:对象p中不存在name值
6、类的继承性
类的继承访问控制:
(1)、子类使用extends继承父类、子类可以将父类中所有的内容都继承过来
(2)、private 私有的权限、只能自已类里用、不能在别的类中用、包括自已的子类
(3)、protected 保护的权限、只能是自已类和自已子类中使用、不能在类外面使用
(4)、public 公有的权限、所有都可以、自已、子类、类外部都可以使用
class Person{
public$name;
protected$age;
private$sex;
function__construct($name, $age, $sex){
$this->name= $name;
$this->age= $age;
$this->sex= $sex;
}
publicfunction say(){
echo"我的性别:{$this->sex}";
}
publicfunction eat(){
}
}
class Student extends Person{
var$school;
functionstudy(){
}
}
class Teacher extends Student{
var$gz;
functionjiao(){
echo"我的年龄是:".$this->age;
}
}
$t = new Teacher("ssw",30,"男");
echo $t -> name;
$t -> jiao();
$t -> say();
显示为:ssw我的年龄是:30我的性别:男
继承中的重载(覆盖)--在子类中可以重写父类同名的方法(方法也可以拓展)
对象->成员
类::成员
Parent::成员 使用用parent::访问父类中被覆盖的方法
重要:只要是子类的构造方法、去覆盖父类中的构造方法、一定要在子类的最上面调用一下父类被覆盖的方法
权限问题:子类只能大于或等于父类的权限、不能小于
class Person{ //使用用parent::访问父类中被覆盖的方法
public$name;
protected$age;
protected$sex;
function__construct($name, $age, $sex){
$this->name= $name;
$this->age= $age;
$this->sex= $sex;
}
publicfunction say(){
echo"我的名子:{$this->name},我的年龄是:{$this->age},我的性别:{$this->sex} <br>";
}
}
class Student extends Person{
var$school="jtuniverty!";
functionsay(){
// echo"我的名子:{$this->name},我的年龄是:{$this->age},我的性别:{$this->sex} <br>";
// Person::say();
parent::say();//这三个是一样的!
echo"我的学校是:{$this->school}";
}
}
$p = new Student("ssw", 28,"男");
$p -> say();
显示为:我的名子:ssw,我的年龄是:28,我的性别:男我的学校是:jtuniverty!
class Person{ //子类的构造方法、去覆盖父类中的构造方法
public$name;
protected$age;
protected$sex;
function__construct($name, $age, $sex){
$this->name= $name;
$this->age= $age;
$this->sex= $sex;
}
publicfunction say(){
echo"我的名子:{$this->name},我的年龄是:{$this->age},我的性别:{$this->sex} ";
}
}
class Student extends Person{
var$school;
function__construct($name, $age, $sex, $school){
parent::__construct($name,$age, $sex);
$this->school= $school;
}
functionsay(){
parent::say();//这三个是一样的!
echo"我的学校是:{$this->school}";
}
}
$p = new Student("ssw", 28,"男", "上海交通大学");
$p -> say();
显示为:我的名子:ssw,我的年龄是:28,我的性别:男我的学校是:上海交通大学
7、Php常见的关键字
Instanceof 操作符用于检测当前对象实例是否属于某一个类的类型
If($p instanceof Person){
Echo“这个$p是Person类的对象”;
}else{
Echo“对象不属于这个类”;
}
Final 用于类方法名前、不能修饰成员属性
(1)final可以修饰类、这个类不能扩展、不能有子类、这个类是最终类
(2)final可以修饰方法、这个方法、就不能在子类中覆盖、不能让子类来改这个方法、或扩展这个方法、这个方法也是最终方法。
Static 可以修饰属性和方法、不能修饰类
(1)使用static修饰成员属性、存在内存的初始化表态段
(2)可以被所有同一个类的对象共用
(3)第一个用到类、类在加载到内存时、就已经将静态的成员加到了内存
对象->成员
类::成员
(4)静态的成员一定要使用类来访问(静态成员不可以由对象通过->操作符来访问)
(5)self可以在类中的方法中、代表自已类的($this)。子类用parent::静态名
(6)静态成员一但被加载、只有脚本结束才释放
(7)在静态的方法中、是不能访问非静态的成员的
(8)只要是能使用静态的环境下声明方法、就最好使用静态方法(效率)
class Foo
{
public static $my_static = ‘foo‘;
public function staticValue() {
return self::$my_static;
}
}
class Bar extends Foo
{
public function fooStatic() {
return parent::$my_static;
}
}
print Foo::$my_static . "\n";
$foo = new Foo();
print $foo->staticValue() ."\n";
//print $foo->my_static ."\n"; // Undefined"Property" my_static
//print $foo::$my_static . "\n";
//$classname = ‘Foo‘;
//print $classname::$my_static ."\n"; // PHP 5.3.0之后可以动态调用
print Bar::$my_static . "\n";
$bar = new Bar();
print $bar->fooStatic() ."\n";
显示为:foofoo foo foo
单态设计模式
单态(单例、单件)
(1)如果想让一个类、只能有一个对象、就要先让这个类、不能创建对象、将构造方法private
(2)可以在类的内存使用一个方法、来创建对象
class Person{
static $obj = null;
static function getObj(){
//如果第一次调用时、没有对象则创建、以后调用时、直接使用第一次创建的对象
if(is_null(self::$obj)){
self::$obj = newself;
}
return self::$obj;
}
function __destruct(){
echo "####";
}
function say(){
echo "say";
}
}
$p =Person::getObj();
$p ->say();
显示为:say####
Const(类常量)修饰的成员属性为常量、只能修饰成员属性
类中:
(1)常量建议用大写、不能使用$
(2)常量一定要在声明时就给好初值
(3)常量的访问方式和static的访问方式相同、但只能读
在类外部使用类名::常量名
在类内部使用 self::常量名
class MyClass
{
const constant = ‘cv‘;
function showConstant() {
echoself::constant . "\n";
}
}
echoMyClass::constant . "\n";
//$classname ="MyClass";
//echo$classname::constant . "\n"; // PHP 5.3.0之后
$class = newMyClass();
$class->showConstant();
//echo$class::constant."\n"; // PHP 5.3.0之后
显示为:cv cv
8、php魔术方法
__construct() __destruct()__set() __get() __isset()__unset()
__tostring()
(1)直接使用 echo print printf输出一个对象引用时、自动调用这个方法
(2)将对象的基本信息放在__toString()方法内部、形成字符串返回
(3)__toString()方法中、不能有参数、而且必须返回一个字符串
class test{
private $foo;
public function __construct($foo){
$this->foo = $foo;
}
public function __toString(){
return $this->foo;
}
}
$p = newtest("ssw");
echo $p;
显示为:ssw
克隆对象__clone()方法
克隆对象:
(1)使用clone这个关键字复制一个对象
__clone()魔术方法:
(1)是在克隆对象时、自动调用的方法
(2)作用:和构造方法一样、是对新克隆的对象进行初使化
(3)在这个__clone()方法中$this代表的是副本、所以就可以给所有副本的成员初始化
class Person{
public $name;
public $age;
public $sex;
function __construct($name,$age,$sex){
$this->name = $name;
$this->age = $age;
$this->sex = $sex;
}
function say(){
echo "名