【Solidity智能合约开发第10篇】3分钟了解Solidity中external、public、internal、private在状态变量和函数中的使用

上一小节中,我们就有使用到publicinternal,但是我们并没有给大家讲解更多细节,接下来我们将针对publicexternalinternalprivate在状态变量和函数中的使用进行讲解和案例分析。

一、案例一

// SPDX-License-Identifier: MIT
pragma solidity >=0.5.0 <0.7.0;

contract Animal {

    string _birthDay; // 生日,默认权限为 internal
    int public _age; // 年龄
    int internal _weight; // 身高
    string private _name; // 姓名

    constructor() public {
      _age = 29;
      _weight = 170;
      _name = "Lucky dog";
      _birthDay = "2011-01-01";
    }

    function birthDay() view external returns (string memory) {
      return _birthDay;
    }

    function age() view  public returns (int) {
      return _age;
    }

    function weight() view internal returns (int) {
      return _weight;
    }

    function name() view  private returns (string memory) {
      return _name;
    }

    function test() view internal {
        // string memory newBirthDay = birthDay(); // external -》报错,birthDay() 函数只支持外部访问
        int newAge = age(); // public 类型的函数
        int newHeight = weight(); // internal 类型的函数
        string memory newName = name(); // private 类型的函数

    }

}

【Solidity智能合约开发第10篇】3分钟了解Solidity中external、public、internal、private在状态变量和函数中的使用

从上面的运行结果我们不难得出如下结论:

  • 状态变量

    1. 状态变量不支持external类型
    2. public类型的_age会自动生成一个_age()函数供外部调用以便访问状态变量的值。
    3. public类型的_ageinternal类型的状态变量_weightprivate类型的状态变量_name均支持合约内部函数访问。
  • 函数

    1. external类型的函数只支持外部访问,内部访问将报错。
    2. public类型的函数birthDay()age()均支持外部访问。
    3. publicinternalprivate的类型均支持内部访问。

二、案例二,状态变量继承

// SPDX-License-Identifier: MIT
pragma solidity >=0.5.0 <0.7.0;

contract Animal {

    string  _birthDay; // 生日
    int public _age; // 年龄
    int internal _weight; // 身高
    string private _name; // 姓名

    constructor() public {
      _age = 29;
      _weight = 170;
      _name = "Lucky dog";
      _birthDay = "2011-01-01";
    }

    function birthDay() view external returns (string memory) {
      return _birthDay;
    }

    function age() view  public returns (int) {
      return _age;
    }

    function weight() view internal returns (int) {
      return _weight;
    }

    function name() view  private returns (string memory) {
      return _name;
    }

}

contract Person is Animal {

        constructor() public {

            _age = 50;
            _weight = 270;
            _birthDay = "2017-01-01";
            _name = "Lucky"; // private 类型的变量

        }
        function test() view internal {
            // string memory newBirthDay = birthDay(); // external -》报错,birthDay() 函数只支持外部访问
            int newAge = age(); // public 类型的函数
            int newHeight = weight(); // internal 类型的函数
            string memory newName = name(); // private 类型的函数

        }
}

【Solidity智能合约开发第10篇】3分钟了解Solidity中external、public、internal、private在状态变量和函数中的使用

接下来注释掉报错的代码,运行结果如下:

【Solidity智能合约开发第10篇】3分钟了解Solidity中external、public、internal、private在状态变量和函数中的使用

结论:

  1. publicinternal类型的状态变量均支持继承,private类型的状态变量不支持继承。
  2. externalpublicinternal类型的函数均支持继承,private类型的函数不支持继承。

三、案例三,函数重写

// SPDX-License-Identifier: MIT
pragma solidity >=0.5.0 <0.7.0;

contract Animal {

    string  _birthDay; // 生日
    int public _age; // 年龄
    int internal _weight; // 身高
    string private _name; // 姓名

    constructor() public {
      _age = 29;
      _weight = 170;
      _name = "Lucky dog";
      _birthDay = "2011-01-01";
    }
    // 如果父合约希望支持子合约继承自己的行为(函数),那么函数声明时需要添加`virtual`关键字
    function birthDay() view external virtual returns (string memory) {
      return _birthDay;
    }
    // 如果父合约希望支持子合约继承自己的行为(函数),那么函数声明时需要添加`virtual`关键字
    function age() view  public virtual  returns (int) {
      return _age;
    }

    function weight() view internal returns (int) {
      return _weight;
    }

    function name() view  private returns (string memory) {
      return _name;
    }

}

contract Person is Animal {

    // 如果子合约欲继承父合约的行为(函数),那么子合约的方法(函数)声明时需添加`override`关键字
    function birthDay() view external override returns (string memory) {
       return "2020-06-18";
    }

    // 如果子合约欲继承父合约的行为(函数),那么子合约的方法(函数)声明时需添加`override`关键字
    function age() view  public override returns (int) {
       return 88;
    } 

}

【Solidity智能合约开发第10篇】3分钟了解Solidity中external、public、internal、private在状态变量和函数中的使用

小结:

  1. 如果父合约希望支持子合约继承自己的行为(函数),那么函数声明时需要添加virtual关键字
  2. 如果子合约欲继承父合约的行为(函数),那么子合约的方法(函数)声明时需添加override关键字
  3. 如果子合约重写从父合约继承来的函数,那么函数的行为将以子合约重写的函数的行为为主。

该内容来自于互联网公开内容,非区块链原创内容,如若转载,请注明出处:https://htzkw.com/archives/25009

联系我们

aliyinhang@gmail.com