现实意义:为学习 Laravel 框架以及NodeJS 做准备
现代高级编程语言全部都是面向对象编程
面向对象仅仅是一种编程思想
以前的语言都是面向过程编程,比如 C语言
面向对象编程思想就是在模仿现实
对象:具有一定功能(动态的特点)和特征(静态的特点)的单个事务,就是对象
类:具有相同功能和特征的对象抽象,就是类,类一定不是用来描述某一个具体的事物
类与对象的关系:对象是类的实例化(具体的一个实例),类是对象的抽象化
对象实例化就是创建类的一个具体对象
/**
* 以class开头
* 类名首字母大写
*/
class Person{
}
/*对象实例化
使用运算符 new 创建类的对象
*/
$p1=new Person();
$p2=new Person();
$p3=new Person();
功能和特征需要使用类的成员进行定义
类的成员主要包含:属性(变量)、方法(函数)
下面的类定义了属性
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 '
';
类中的方法可以使用类中的属性,但是要使用 $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 '
';
指向实例化的对象,只能应用于成员方法,可以调用奔类或者从父类中继承的属性和方法。比面用 $this引用静态成员属性和类常量(使用 self)
$this 不是引用类,也没有指向某个具体的对象,当前哪个对象使用到 $this了, 那么 $this就指向这个对象
name;
}
}
$p1=new Person();
$p1->name='李白';
// 调用此方法时,$this 指向了 $p1 对象
$p1->getName();
$p2=new Person();
$p2->name='杜甫';
// 调用此方法时,$this 指向了 $p2 对象
$p2->getName();
方法名称以 _ _ 下划线开头
构造方法:实例化类的对象时调用
类中默认存在一个无参的构造方法,下面代码中 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();
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();
封装
继承
多态
封装可以最大限度的保护类的内部细节
也就是说尽量不让类的调用者知道类的内部都有哪些属性,哪些方法
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属性赋值
通过公共方法获取私有属性的值
自己没有,别人,可以拿来,就是继承
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;
在面向对象语言中,多态就是把字类的对象赋值给父类的引用,然后调用父类的方法,去执行字类覆盖父类的那个方法
覆盖
字类重写父类中重名的方法
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
在实际的开发当中,一个类会放到一个专门的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 代码,否则方法不会执行