通俗易懂PHP基础【10-类和对象(2)】

你是你自己

在你成长的过程中,人们总是会告诉你:这个世界就是……尽量不要撞了墙也不回头,要努力拥有美好的家庭,要学会享乐,要存下一点钱。那是一种非常有限的生活。生活可以变得更加多彩,只要你发现这样一个简单的事实:你周围的一切,即你所谓的生活,都是由不如你聪明的人组成的,你可以去改变它,可以去影响它,也可以做出自己的东西供他人使用。一旦意识到这一点,你将从此不同。

——史蒂夫·乔布斯

这一节是介绍 类和对象的第二小节,今天还出去帮朋友整理工作室,傍晚6点半才到公司开始整理这一小节的内容。好吧,不多说了,开始这一小节的介绍。

1

类的实例化

上一小节,我们有提过只有类是无法直接对类中的属性和方法进行引用,因为类是一个抽象性的概念,我们只有通过类去创建一个对象,才有使用属性和方法的意义。

正如人类是类,人类代表不了你,你也代表不了人类,你是人类中的你,你是你自己。

在PHP 中创建对象,在上一节我们也有使用过,就是通过 new 关键字 来创建对象。

例如,在上一节我们有创建一个叫Student的类,为了使用该 Student 类 中的属性和方法,我们需要通过 new 关键词来创建出一个学生的对象,如下:

$student=new Student($grade,$name,$age);

这样我们就可以,通过 $student 这个对象来调用 Student 类中的属性和方法。想要使用类中属性和方法,调用的语法是通过"$对象->属性/方法"的方式来调用,如下所示(即通过"->"来访问属性和方法):

$student->age;//调用属性
$student->printStudentInfo();//调用方法

2

控制访问权限

上一节我们有提到过控制类的属性和方法的访问权限,所谓的权限,是指我们定义的属性和方法可以被使用的范围。在实际的编码中,总会有一些属性(如一些密码属性等)或者方法不宜对外公开,所以学会使用修饰符来控制你自定义类中的属性和方法是很有必要的。

PHP中控制访问权限的修饰符主要包括public、private和protect这3种,如果不加任何修饰符就对类体中的属性或方法进行修饰,则默认为public。下面是三个修饰符能访问的权限介绍:

public

使用public修饰的属性或方法,则属性和方法是类的公有成员,公有的成员属性或者方法在类体内和类体外都可以被调用。

private

使用 private 修饰的属性或方法,则属性和方法是类的私有成员,私有的成员属性或者方法只有在本类(当前类本身)中可以被调用。

protect

使用 protect修饰的属性或方法,则属性和方法是类的保护成员,保护的成员属性和方法只有能在本类(当前类本身)和它的子类被调用。

3

继承

上一节中我们说过类有三大特性:继承,封装,多态。这里我们在结合之前所讲说一下继承这一特性。

PHP中使用继承的挂件是 extends 。如,定义类A,让类B继承类A,则类A是父类,类A被称为子类。

//父类
class A {

}
//子类
class B extends A {
  // 类B中的成员
}

结合访问的权限,以下几点总结可要细细体会。

1、子类B可以继承父类A中的公有的和受保护的成员方法和属性,但父类中的私有成员属性和方法,子类是无权调用的。

2、类的继承是单向性的,意思就是子类能继承父类的一些属性和方法,但是父类不能继承子类的属性和方法。通俗的说,儿子可以继承老爸的,没有老爸继承儿子的。

3、PHP中是不支持多继承,也就是说一个子类只能有一个父类,一个父类可以有多个子类。通俗的说,你只能有一个父亲,而你的父亲可以有多个的儿子。

4

重载

上一节我们也说过类的三大特性之一,多态多态,简单的说就是同样的操作(方法)可以有不一样的行为。

在子父类中体现这种多态性,叫做重载。重载的意思就是,如果在父类中已经定义了某属性或方法,子类可以继承这些属性或者方法,也可以在同样的属性或者方法命名下重新自己定义。

通俗的说,你继承了你爸的艺术天分,虽然都有艺术天分,但是你们彼此还是会有不一样的艺术体现。

<?php
class Father{    //定义father 类
  public function art(){
      echo "father 会画国画";
  }
}
 
class Child extends Father{    //子类child 继承 father 类
  public function art(){  //重写 father 类中的方法,实现重载
      echo "chile 会涂涂鸦";
  }
}
 
$fater=new Father();
$fater->art(); //输出 father 会画国画
echo "<br>";
$child=new Child();
$child->art();   // 输出 chile 会涂涂鸦
?>

运行结果:

5

final关键字

上面说的是子类能重载父类的属性或方法,但是父类总会有一些属性或方法是不想被子类继承重载的,那该怎么办?

父类中的属性或方法要不想被子类继承重载的话,就要使用 final关键字。

如果父类中有 final 关键字修饰的属性或方法,则子类不能重载父类中的属性或者方法。通俗的说,虽然你很受你爸的熏陶(继承),但你爸总有一些东西是不想继承给你的(比如抽烟喝酒啥的,哈哈)。要达成这一目的,记住代码中是使用 final 关键字。

如果是一个类自己用 final 修饰,则 这个类是当不了父类的,他是不会有任何的子类的。通说的说,这个类把自己“丁克”了。

我们来 see see 实例:

<?php
class Father{
  final function drink(){
      echo "father 很爱酗酒";
  }
}
 
class Child extends Father{
  function drink(){
      echo "来,干了这一杯1982年的可口可乐";
  }
}
 
$child = new child();
$child->drink();
?>

运行上面代码将出现以下报错信息: 不能重修final 修饰的方法 drink()

Fatal error: Cannot override final method Father::drink()

6

接口

上面我们说过,PHP中的类是无法多重继承的,只能有一个父类。但在PHP中有一种算是可以多继承的解决的方案,那就是去实现接口,一个类可以实现 n 多个的接口。

声明一个类,我们使用 class 关键字来声明,而声明一个接口,我们就要使用一个叫做 interface 的关键字,来声明接口。

下面我们 see see 类和接口的对比:

<?php
//这是定义一个类
class Hello{
  function say(){
    echo "hello,请叫我靓仔";
  }
}
//这是定义一个接口
interface Hello{   //定义test接口
  function say();
}
?>

从上,通过类和接口的对比,我们来说一下接口:

1、类的声明用 class 关键字,接口的声明使用 interface 关键字;

2、接口中方法只需定义,无需实现。如上,我们Hello接口定义了一个 say(),而没有方法块(用"{}"包围的方法体)。

3、一个接口可以继承多个接口,每个接口使用逗号隔开。(了解看下面的实例代码,并自己测试一下好不好)

那么,接口定义的方法要怎么去实现呢?Em...,这个就要让实现这个接口的类去实现了,而且只实现一个接口中的方法还不行,必须实现这个接口包括这个接口的父类接口中全部定义的方法才行

如果一个类没有实现接口中定义的全部方法,程序将会发生错误。而且,一个类要继承(应该说实现比较合理)多个接口,这些接口要用逗号隔开。

结合以上,下面我们来 see see 例子:

实现一个接口:

<?php
//这是定义一个接口
interface Hello{   //定义test接口
  function say();
}

class Chinese implements Hello{   // 实现test接口
  function say(){
      echo "你好";
  }
}
?>

实现多个接口:

<?php

interface Hello{   //定义test1接口
  function say();
}
 
interface Eatting{  //定义test2接口
  function food();
}
 
interface People extends Hello,Eatting{   //接口Chinese 继承Hello,Eatting 接口
  function country();
}
 
class Chinese implements People {   //接口的实现
  function say(){
      echo "实现接口Hello中的方法";
  }
  function food(){
      echo "实现接口Eatting中的方法";
  }
  function country(){
      echo "实现接口People 中的方法";
  }
}

 $chinese = new Chinese();
 $chinese->say();
 echo "<br/>";
 $chinese->food();
  echo "<br/>";
 $chinese->country();
?>

运行效果:程序没有报错

加入我们去掉 Chinese 类中任意的一个方法,我们再来看看程序会不会报错

可以看到程序报了如下的错误,意思是:类Chinese包含1个抽象方法,要么把类声明成抽象类(什么是抽象类下一节再介绍),要么就要去实现这个抽象方法。

Fatal error: Class Chinese contains 1 abstract method and must therefore be declared abstract or implement the remaining methods (Hello::say)

关于类和对象的第二小节介绍,就先介绍到这里了。剩下的一节是类和对象的第三小节,这个PHP基础介绍的最后一节。欢迎您关注我,我们还有更多学习的知识在等着我们。

本文分享自微信公众号 - Lemon黄(lemonhunag)

原文出处及转载信息见文内详细说明,如有侵权,请联系 yunjia_community@tencent.com 删除。

原始发表时间:2019-09-21

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

扫码关注云+社区

领取腾讯云代金券