面向对象

面向对象编程

现实意义:为学习 Laravel 框架以及NodeJS 做准备

现代高级编程语言全部都是面向对象编程

面向对象仅仅是一种编程思想

以前的语言都是面向过程编程,比如 C语言

面向对象编程思想就是在模仿现实

1 相关概念

对象:具有一定功能(动态的特点)和特征(静态的特点)的单个事务,就是对象

类:具有相同功能和特征的对象抽象,就是类,类一定不是用来描述某一个具体的事物

类与对象的关系:对象是类的实例化(具体的一个实例),类是对象的抽象化

2 定义类和对象实例化

对象实例化就是创建类的一个具体对象

/**
 * 以class开头
 * 类名首字母大写
 */
class Person{

}
/*对象实例化
使用运算符 new 创建类的对象
*/
$p1=new Person();
$p2=new Person();
$p3=new Person();

3 类的成员

功能和特征需要使用类的成员进行定义

类的成员主要包含:属性(变量)、方法(函数)

3.1 属性

下面的类定义了属性

class Person
{
    // 变量在类的内部叫做属性,在类的外部叫做变量
    public $name = "yhb";
    public $age;
    public $weight;
    public $height;
    public $gender;
}

类中的属性为什么可以不设置初始值,而是等到创建对象之后再为属性赋值

/**
 * 以class开头
 * 类名首字母大写
 */

class Person
{
    // 变量在类的内部叫做属性,在类的外部叫做变量
    public $name = "yhb";
    public $age;
    public $weight;
    public $height;
    public $gender;
}
/*对象实例化
使用运算符 new 创建类的对象
 */
$p1 = new Person();
// 为对象中的属性赋值
$p1->name='赵双世';
$p1->age=100;
$p1->weight=170;
$p1->height=120;
$p1->gender='男';
echo '
';
print_r($p1);
echo '
'; $p2 = new Person(); $p2->name='李建'; $p2->age=18; $p2->weight=250; $p2->height=120; $p2->gender='男'; echo '
';
print_r($p2);
echo '
';

3.2 方法

类中的方法可以使用类中的属性,但是要使用 $this 引用

name.",是一个新人类,我的身高是".$this->height.",
        体重是".$this->weight.",我是".$this->gender;
    }
}
/*对象实例化
使用运算符 new 创建类的对象
 */
$p1 = new Person();
// 为对象中的属性赋值
$p1->name = '刘建金';
$p1->age = 100;
$p1->weight = 170;
$p1->height = 120;
$p1->gender = '男';
// 调用对象中的方法
$p1->speak();
echo '
';
print_r($p1);
echo '
';

4 $this

指向实例化的对象,只能应用于成员方法,可以调用奔类或者从父类中继承的属性和方法。比面用 $this引用静态成员属性和类常量(使用 self)

$this 不是引用类,也没有指向某个具体的对象,当前哪个对象使用到 $this了, 那么 $this就指向这个对象

name;
  }
}

$p1=new Person();
$p1->name='李白';
// 调用此方法时,$this 指向了 $p1 对象
$p1->getName();

$p2=new Person();
$p2->name='杜甫';
// 调用此方法时,$this 指向了 $p2 对象
$p2->getName();

5 魔术方法(Magic methods)

方法名称以 _ _ 下划线开头

5.1 _ _constuct

构造方法:实例化类的对象时调用

类中默认存在一个无参的构造方法,下面代码中 Person() 就是 Person 类中默认存在的无参的构造方法

$p1=new Person();
构造方法也是方法,特殊之处在于

无参的构造方法,不需要我们自己定义
不需要开发者自己调用,实例化对象时自动执行
也可以在类中定义无参的构造方法,但是并没有什么大的意义

/**
   * 定义无参的构造方法
   */
  public function __construct(){
    
  }

实际上,在开发中,我们更多的是在类中定义有参数的构造方法,一旦定义有参的构造方法,则默认无参的构造方法就会被覆盖

name.',今年'.$this->age.'岁了';
  }
  /**
   * 定义无参的构造方法
   */
  public function __construct($name,$age){
    
  }
}
// 因为类中定义了有参数的构造方法,所以无参的构造方法就被覆盖了,所以下面的调用就会出错
$p1=new Person();

作用

构造方法的主要作用:初始化对象属性


name . ',今年' . $this->age . '岁了';
    }
    /**
     * 定义有参数的构造方法
     */
    public function __construct($name, $age)
    {
      /**
       * $this->name 指代的是对象的属性 name
       * $name 指代的是形参 $name
       */
        $this->name = $name;
        $this->age = $age;
    }
}
// 因为类中定义了有参数的构造方法,所以无参的构造方法就被覆盖了,所以下面的调用就会出错
$p1 = new Person('杜甫', 18);
$p1->speak();
echo '
'; $p2=new Person('白居易',16); $p2->speak();

5.2 修饰符

5.2.1 访问修饰符

public:可以用来修饰属性和方法,表示此属性或者方法可以在类的内部、类的派生类和类的外部使用
protected:可以用来修饰属性和方法,表示此属性或者方法可以在类的内部和类的派生类中使用
private:可以用来修饰属性和方法,表示只能在类的内部使用

class Person
{
    private $name;
    public $age;
    public function __construct($name)
    {
      $this->name=$name;
    }
    /**
     * 通过公共方法向类的外部暴漏私有属性name的值
     */
    public function getName(){
      echo $this->name;
    }
}
// 因为类中定义了有参数的构造方法,所以无参的构造方法就被覆盖了,所以下面的调用就会出错
$p1 = new Person('李白');
$p1->getName();

6 三大特征

封装
继承
多态

6.1 封装

封装可以最大限度的保护类的内部细节

也就是说尽量不让类的调用者知道类的内部都有哪些属性,哪些方法

class Book{
  public $name;
  public $author;
  public $price;
}
$p1=new Book();
$p1->name='sss';

上面的代码中,可以在类的外部获取或者设置属性,封装的意义就在于在类的外部不知道类又哪些属性

将类中的属性使用 Private 修饰符修饰之后,就无法在类的外部获取或者设置私有属性了

class Book{
  private $name;
  private $author;
  private $price;
}
$p1=new Book();
$p1->name='sss';

可以通过构造方法为私有属性赋值

class Book{
  private $name;
  private $author;
  private $price;

  /**
   * 通过构造方法为私有属性赋值
   */
  public function __construct($name,$author,$price)
  {
    $this->name=$name;
    $this->author=$author;
    $this->price=$price;
  }
}
$p1=new Book("庆余年",'猫腻','20');

总结:

将属性设置为private
通过构造方法为private属性赋值
通过公共方法获取私有属性的值

6.2 继承

自己没有,别人,可以拿来,就是继承

class A{
  public $name;
  public $age;
  public function f1(){
    echo 'f1';
  }
}
class B extends A{

}
$b1=new B();
var_dump($b1);
$b1->f1();

如果父类中的成员声明为 private,则字类无法继承

class A{
  /**
   * 父类中属性声明为私有,则字类就无法继承
   */
  private $name='onlifes';
}
class B extends A{

}
$b1=new B();
echo $b1->name;

概念解释

父类:被继承的类叫做父类,也叫基类
字类,继承别的类的类叫做字类,也叫派生类
访问修饰符和继承的关系

age;
    }
}
class B extends A
{
    public function f2()
    {
        echo $this->age;
    }
    public function f3()
    {
        echo $this->name;
    }
}
$b1 = new B();
$b1->f2();
$b1->f3();
echo $b1->gender;
echo $b1->name;
echo $b1->age;

6.3 多态

在面向对象语言中,多态就是把字类的对象赋值给父类的引用,然后调用父类的方法,去执行字类覆盖父类的那个方法

覆盖

字类重写父类中重名的方法


class A
{
    public function f1()
    {
        echo 'f1';
    }
}
class B extends A
{
    public function f1()
    {
        echo '字类中的f1';
    }
}
$b1 = new B();
/**
 * 字类中如果又与父类同名的方法,则会覆盖父类中的方法
 */
$b1->f1();

多态案例1

f1();
    }
}
class B extends A
{
    public function f1()
    {
        echo 'B类中的f1';
    }
}
class C extends A
{
    public function f1()
    {
        echo 'C类中的f1';
    }
}
class D extends A
{
    public function f1()
    {
        echo 'D类中的f1';
    }
}
$a1 = new A();
$b1 = new B();
$c1 = new C();
$d1 = new D();

$a1->f1();
echo '
'; $b1->f1(); echo '
'; $c1->f1(); echo '
'; $d1->f1(); echo '
'; $a1->doWork($b1); echo '
'; $a1->doWork($c1); echo '
'; $a1->doWork($d1); echo '
';

多态案例2

6.7 __autoload

在实际的开发当中,一个类会放到一个专门的php文件中,而且这个文件的名称一般会加 class 后缀

Women.class.php

work();
    }
}
Nurse.class.php

doWork($n);
$w->doWork($t);


自动加载:帮着我们自动的将类所在的php文件引入,修改上面的代码


doWork($n);
$w->doWork($t);

function __autoload($class){
  // echo 'autoload';
  include $class.'.class.php';
}

说明:如果使用 __autoload方法,必须去掉手动的 include 代码,否则方法不会执行

你可能感兴趣的:(面向对象)