PHP面向对象的一些重小知识点
访问修饰符的权限
1. public(公有的):在类的内部和外部都能访问
2. private(私有的):只能在类的内部访问
3. protected(受保护的):在整个继承链上访问
4. 一般来说,属性都是私有的,通过公有的方法对私有的属性进行赋值和取值
作用:
保证数据的合法性
class Person{
public function __construct ( )
{
echo '这是父类<br>' ;
}
}
class Student extends Person {
public function __construct ( )
{
Person :: __construct ( ) ;
parent :: __construct ( ) ;
echo '这是子类<br>' ;
}
}
new Student ( ) ;
知识点:
1. 如果子类有构造函数就调用子类的,如果子类没有就调用父类的构造函数
2. 子类的构造函数调用以后,默认不再调用父类的构造函数
3. 通过类名调用父类的构造函数,类名::__construct()
4. 注意:parent关键字表示父类的名字,可以降低程序的耦合性
多重继承
多重继承:PHP不允许多重继承,因为多重继承会产生二义性
重写
知识点:
1. 子类的方法必须和父类的方法同名
2. 参数个数要一致
3. 子类修饰的不能比父类更加严格
class A {
public function show ( ) {
}
}
class B extends A {
public function show ( )
{
}
}
class C {
protected function show ( ) {
}
}
class D extends C {
public function show ( )
{
}
}
方法重载
知识点:
1. 方法重载:在同一个类中,有多个同名的函数,通过参数的不同来区分不同的方法,称为方法重载
2. 但是注意:PHP不支持方法重载,但是PHP可以通过其他方法来模拟方法重载
方法修饰符
知识点:
1. 方法修饰符有:static、final、abstract
static[静态的]:
知识点:
1. static修饰的属性叫静态属性,static修饰的方法叫做静态方法
2. 静态成员加载类的时候分配空间,程序执行后销毁
3. 静态成员在内存中就一份
4. 调用语法:类名::属性 类名::方法名()
5. static有两个作用,第一表示静态的,第二表示类名
class Student {
private static $num = 0 ;
public function __construct ( )
{
self :: $num ++ ;
}
public function __destruct ( )
{
self :: $num -- ;
}
public function show ( ) {
echo '总人数是:' . self :: $num , '<br>' ;
}
}
$stu1 = new Student ( ) ;
$stu2 = new Student ( ) ;
$stu3 = new Student ( ) ;
$stu3 -> show ( ) ;
unset ( $stu2 ) ;
$stu3 -> show ( ) ;
静态成员也可以被继承
class A {
public static $add = '中国' ;
public static function show ( ) {
echo '这是人类<br>' ;
}
}
class B extends A {
}
echo B :: $add , '<br>' ;
B :: show ( ) ;
延时绑定
class C {
public static $type = '人类' ;
public function show1 ( ) {
var_dump ( $this ) ;
echo '<br>' , self :: $type , '<br>' ;
echo static :: $type , '<br>' ;
}
}
class D extends C {
public static $type = '学生' ;
public function show2 ( ) {
var_dump ( $this ) ;
echo '<br>' , self :: $type , '<br>' ;
echo static :: $type , '<br>' ;
}
}
$obj = new D ( ) ;
$obj -> show1 ( ) ;
$obj -> show1 ( ) ;
fianl[最终的]
知识点:
1. final修饰的方法不能被重写
2. fianl修饰的类不能被继承
class Person{
final public function show ( ) {
}
}
class Student extends Person {
}
final class A {
}
class B extends A { }
作用:
1. 如果一个类确实不能被继承,一个方法确定不能被重写,用final修饰可以可以提高执行效率
2. 如果一个方法不允许被其它类重写,可以用final修饰
abstract[抽象的]:
知识点:
1. abstract修饰的方法是抽象方法,修饰的类是抽象类
2. 只有方法的声明没有方法的实现称为抽象方法
3. 一个类中只要有一个抽象方法,这个类必须是抽象类
4. 抽象类的特点是不能被实例化
5. 子类继承了抽象类,就必须重新实现父类的所有的抽象方法,否则不允许实例化
6. 类中没有抽象方法也可以声明成抽象类,用来阻止类的实例化
abstract class C {
public abstract function setinfo ( ) ;
public function getinfo ( ) {
echo '获取信息<br>' ;
}
}
class D extends C {
public function setinfo ( ) {
echo '设置信息<br>' ;
}
}
( new D ( ) ) -> setinfo ( ) ;
类常量是const常量
class E {
const ADD = '地址不详' ;
}
echo E :: ADD , '<br>' ;
define和const的区别
1. const常量可以做类成员,define常量不可以做类成员
常量和静态的属性的区别
1. 相同点:都在加载类的时候分配空间
2. 不同点:常量的值不可以更改,静态的属性的值可以更改
接口
知识点:
1. 如果一个类中的所有的方法都是抽象方法,那么这个抽象类可以声明成接口
2. 接口是一个特殊的抽象类,接口中只能有抽象方法和常量
3. 接口的抽象方法只能是public,可以省,默认以也是public的
4. 通过implents关键字类实现接口
5. 不能使用abstract和fianl来修饰接口中的抽象方法
6. 类不允许多重实现,但是接口允许多重实现
7. 在接口多重实现中,如果有同名的方法,只要实现一次即可
声明接口
interface Persons{
const ADD = '中国' ;
function fun1 ( ) ;
function fun2 ( ) ;
}
接口实现
class Students implements Persons {
public function fun1 ( )
{
}
public function fun2 ( )
{
}
}
echo Persons :: ADD , '<br>' ;
接口的多重实现
interface IP1 {
function fun1 ( ) ;
}
interface IP2 {
function fun2 ( ) ;
}
class F implements IP1 , IP2 {
public function fun2 ( )
{
}
public function fun1 ( )
{
}
}
匿名类
$stu = new class {
public $name = 'tom' ;
public function __construct ( ) {
echo '构造函数<br>' ;
}
} ;
echo $stu -> name , '<br>' ;
知识点:
1. 匿名类7.0往以后支持
2. 如果类只被实例化一次就可以使用匿名类
3. 好处:实例化完毕以后就回收了类的空间
闭包
知识点:
1. 作用:将方法绑定到对象上,并调用
2. 语法:闭包->call(对象):将闭包绑定到对象上,并调用
3. 在PHP中匿名函数被称为闭包
$lang = 'en' ;
class S { }
if ( $lang == 'ch' ) {
$fun = function ( ) {
echo '我是一名学生' ;
} ;
} else {
$fun = function ( ) {
echo 'my name is a student' ;
} ;
}
$stu = new S ;
$fun -> call ( $stu ) ;
异常处理
使用的关键字
1. try:监测代码块
2. catch:捕获异常
3. throw:抛出异常
4. finally:无论有无都会执行,可以省略
5. Exception:异常类
语法结构
作用
1. 集中处理在代码中发生的异常
2. 在代码块中发生了异常直接抛出,代码块中不处理异常,将异常集中起来一起处理
if ( isset ( $_POST [ 'button' ] ) ) {
try {
$age = $_POST [ 'age' ] ;
if ( $age == '' )
throw new Exception ( '年龄不能为空' , 1001 ) ;
if ( ! ( $age >= 10 && $age <= 30 ) )
throw new Exception ( '年龄不在10到30岁之间' , 1002 ) ;
} catch ( Exception $ex ) {
echo '错误消息:' . $ex -> getMessage ( ) . '<br>' ;
echo '错误码:' . $ex -> getCode ( ) . '<br>' ;
echo '文件地址:' . $ex -> getFile ( ) . '<br>' ;
echo '错误行号:' . $ex -> getLine ( ) . '<br>' ;
}
}
echo '<form action="" method="post">
年龄:<input type="text" name="age"><br>
<input type="submit" name="button" value="提交">
</form>' ;
自定义异常类
class MyNullExcetion extends Exception { }
class MyRangeExcetion extends Exception { }
if ( isset ( $_POST [ 'button' ] ) ) {
try {
$age = $_POST [ 'age' ] ;
if ( $age == '' )
throw new MyNullExcetion ( '年龄不能为空' , 1001 ) ;
if ( ! ( $age >= 10 && $age <= 30 ) )
throw new MyRangeExcetion ( '年龄不在10到30岁之间' , 1002 ) ;
} catch ( MyNullExcetion $ex ) {
echo '错误消息:' . $ex -> getMessage ( ) . '<br>' ;
echo '记录在日志中<br>' ;
} catch ( MyRangeExcetion $ex ) {
echo '错误消息:' . $ex -> getMessage ( ) . '<br>' ;
echo '记录在邮箱中<br>' ;
}
}
echo '<form action="" method="post">
年龄:<input type="text" name="age"><br>
<input type="submit" name="button" value="提交">
</form>' ;
__autoload()和sp_autoload_register()
__autoload():
知识点:
1. 自动加载类:方法一:__autoload()函数,在PHP7.2以后就不支持了
2. 当缺少类的时候自动调用__autoload()函数,并且将缺少的类名作为参数传递给__autoload()
function __autoload ( $class_name ) {
require "./{ $class_name } .php" ;
}
$book = new Book ( ) ;
$book -> setName ( '面向对象编程' ) ;
$phone = new Phone ( ) ;
$phone -> setName ( '苹果13' ) ;
$book -> getName ( ) ;
$phone -> getName ( ) ;
sp_autoload_register()
function loadclass ( $classname ) {
require "./{ $classname } .php" ;
}
spl_autoload_register ( 'loadclass' ) ;
spl_autoload_register ( function ( $classnamr ) {
require "./{ $classnamr } .php" ;
} ) ;
spl_autoload_register ( function ( $classname ) {
$map = array (
'Goods' => './aa/Goods.php' ,
'Book' => './cc/Book.php' ,
'Phone' => './bb/Phone.php' ,
) ;
if ( isset ( $map [ $classname ] ) ) {
require $map [ $classname ] ;
}
} ) ;