php有哪些访问控制符

发布时间:2021-07-16 11:49:16 作者:chen
来源:亿速云 阅读:189
# PHP有哪些访问控制符

## 目录
1. [访问控制符概述](#访问控制符概述)
2. [public访问控制符](#public访问控制符)
3. [protected访问控制符](#protected访问控制符)
4. [private访问控制符](#private访问控制符)
5. [访问控制符的继承特性](#访问控制符的继承特性)
6. [静态成员的访问控制](#静态成员的访问控制)
7. [构造方法的访问控制](#构造方法的访问控制)
8. [魔术方法的访问控制](#魔术方法的访问控制)
9. [接口中的访问控制](#接口中的访问控制)
10. [Trait中的访问控制](#trait中的访问控制)
11. [访问控制最佳实践](#访问控制最佳实践)
12. [总结](#总结)

## 访问控制符概述

在面向对象编程(OOP)中,访问控制符(也称为可见性修饰符)是用于限制类成员(属性和方法)可访问范围的关键字。PHP提供了三种主要的访问控制符:

- `public`:公共可见性
- `protected`:受保护的可见性
- `private`:私有可见性

这些修饰符决定了类的属性和方法可以在哪些上下文中被访问,是实现封装这一OOP重要特性的关键手段。

```php
class Example {
    public $publicProperty;
    protected $protectedProperty;
    private $privateProperty;
    
    public function publicMethod() {}
    protected function protectedMethod() {}
    private function privateMethod() {}
}

public访问控制符

public是最宽松的访问级别,具有以下特点:

  1. 全局可访问性:可以在任何地方访问

    • 类内部
    • 子类中
    • 类实例对象
    • 其他类或全局作用域
  2. 使用场景

    • 需要对外公开的API方法
    • 需要被子类重写的方法
    • 需要被外部直接访问的属性
class User {
    public $username;  // 公共属性
    
    public function login() {  // 公共方法
        return "User {$this->username} logged in";
    }
}

$user = new User();
$user->username = 'admin';  // 直接访问公共属性
echo $user->login();       // 调用公共方法

protected访问控制符

protected提供了中等限制的访问级别:

  1. 访问范围

    • 定义该成员的类内部
    • 该类的子类中
    • 不能通过类实例直接访问
  2. 使用场景

    • 需要被子类继承但不希望外部直接访问的成员
    • 实现模板方法模式时的中间方法
class Animal {
    protected $name;
    
    protected function eat() {
        return "{$this->name} is eating";
    }
}

class Dog extends Animal {
    public function setName($name) {
        $this->name = $name;  // 可以访问父类的protected属性
    }
    
    public function bark() {
        echo $this->eat();  // 可以调用父类的protected方法
        echo "Woof!";
    }
}

$dog = new Dog();
$dog->setName('Buddy');
$dog->bark();
// $dog->eat();  // 错误:无法从外部访问protected方法

private访问控制符

private提供了最严格的访问限制:

  1. 访问范围

    • 仅限定义该成员的类内部
    • 子类和其他任何地方都无法访问
  2. 使用场景

    • 实现类内部逻辑的辅助方法
    • 不希望被子类修改或访问的关键属性
    • 封装实现细节
class BankAccount {
    private $balance = 0;
    
    public function deposit($amount) {
        $this->balance += $amount;
        $this->logTransaction('Deposit', $amount);
    }
    
    public function getBalance() {
        return $this->balance;
    }
    
    private function logTransaction($type, $amount) {
        // 记录交易的私有方法
        echo "Logged: $type of $amount\n";
    }
}

$account = new BankAccount();
$account->deposit(100);
echo $account->getBalance();
// $account->balance = 1000;  // 错误:无法访问private属性
// $account->logTransaction(); // 错误:无法访问private方法

访问控制符的继承特性

了解访问控制符在继承中的行为非常重要:

  1. public成员

    • 保持public可见性
    • 子类可以重写(除非使用final)
  2. protected成员

    • 保持protected或改为public
    • 不能改为private
  3. private成员

    • 对子类不可见
    • 子类可以定义同名成员(实际上是新成员)
class ParentClass {
    public function publicMethod() {}
    protected function protectedMethod() {}
    private function privateMethod() {}
}

class ChildClass extends ParentClass {
    // 可以保持或放宽可见性
    public function publicMethod() {}      // 允许
    public function protectedMethod() {}   // 允许(protected->public)
    // private function protectedMethod() {} // 不允许(protected->private)
    
    private function privateMethod() {}    // 这是新方法,不是重写
}

静态成员的访问控制

静态属性和方法也可以使用访问控制符:

class Logger {
    public static $publicLog = [];
    protected static $protectedLog = [];
    private static $privateLog = [];
    
    public static function logPublic($message) {
        self::$publicLog[] = $message;
    }
    
    protected static function logProtected($message) {
        self::$protectedLog[] = $message;
    }
    
    private static function logPrivate($message) {
        self::$privateLog[] = $message;
    }
}

Logger::logPublic('Public message');  // 允许
// Logger::logProtected('Protected'); // 不允许
// Logger::logPrivate('Private');     // 不允许

构造方法的访问控制

构造方法(__construct)也可以有访问控制:

  1. public构造方法:标准情况,可以自由实例化
  2. protected/private构造方法:用于特殊模式
    • 单例模式(private)
    • 工厂方法模式(protected)
class Singleton {
    private static $instance;
    
    private function __construct() {
        // 防止直接实例化
    }
    
    public static function getInstance() {
        if (!self::$instance) {
            self::$instance = new self();
        }
        return self::$instance;
    }
}

// $singleton = new Singleton(); // 错误
$singleton = Singleton::getInstance(); // 正确方式

魔术方法的访问控制

PHP的魔术方法通常应该保持public:

class Magic {
    public function __get($name) {
        // 必须为public
    }
    
    public function __set($name, $value) {
        // 必须为public
    }
    
    // 其他魔术方法...
}

接口中的访问控制

接口中的所有方法都隐式为public:

interface LoggerInterface {
    public function log($message);  // 只能是public
    // protected function protectedLog(); // 不允许
}

Trait中的访问控制

Trait中的成员可以有任何访问级别,但使用时需注意:

trait LoggingTrait {
    public $publicInTrait;
    protected $protectedInTrait;
    private $privateInTrait;
    
    public function publicMethod() {}
    protected function protectedMethod() {}
    private function privateMethod() {}
}

class UsingTrait {
    use LoggingTrait;
    
    public function test() {
        $this->publicMethod();     // 允许
        $this->protectedMethod();  // 允许
        $this->privateMethod();    // 允许(在类内部)
    }
}

$obj = new UsingTrait();
$obj->publicMethod();
// $obj->protectedMethod(); // 不允许

访问控制最佳实践

  1. 最小权限原则:默认使用最严格的访问级别(private),只在必要时放宽
  2. 属性封装:大多数情况下属性应为private/protected,通过方法访问
  3. 方法设计
    • 公共方法应保持稳定(避免频繁修改)
    • 非公共方法可以更自由地重构
  4. 文档注释:使用PHPDoc标注访问控制意图
/**
 * 用户账户类
 */
class UserAccount {
    /** @var string 用户名(protected以允许子类访问) */
    protected $username;
    
    /** @var string 密码(private确保安全) */
    private $password;
    
    /**
     * 设置密码(公共接口)
     * @param string $password
     */
    public function setPassword($password) {
        $this->password = password_hash($password, PASSWORD_DEFAULT);
    }
}

总结

PHP的三种访问控制符提供了不同级别的封装能力:

修饰符 类内部 子类 类实例 主要用途
public 公共API
protected 继承实现
private 内部实现

正确使用访问控制符可以: - 提高代码安全性 - 减少意外修改的风险 - 明确类成员的预期用途 - 便于后续维护和重构

记住:良好的访问控制设计是构建健壮、可维护面向对象系统的关键要素之一。 “`

这篇文章详细介绍了PHP中的三种访问控制符,包括它们的语法、使用场景、继承特性以及在各种上下文中的应用,最后总结了访问控制的最佳实践。全文约2200字,采用Markdown格式编写,包含代码示例和比较表格,便于读者理解。

推荐阅读:
  1. 写给初学者之 访问控制符static
  2. php访问url的方式有哪些

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

php

上一篇:php如何删除数组所有元素

下一篇:Web开发中客户端跳转与服务器端跳转有什么区别

相关阅读

您好,登录后才能下订单哦!

密码登录
登录注册
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》