作者:黎躍春,區塊鏈、高可用架構工程師
微信:liyc1215 QQ羣:348924182 博客:http://liyuechun.org
在上一小節中我們在函數參數中使用storage
這個關鍵字時,當前的函數必須是internal
或者private
類型。
在本小節中,我(微信:liyc1215)將重點爲大家介紹屬性和函數的使用權限。
狀態變量、函數的權限
一、public
備註:爲了演示方便,我直接通過https://remix.ethereum.org/
來進行演示。
public
類型的狀態變量和函數的權限最大,可供外部、子合約、合約內部訪問。
pragma solidity ^0.4.4;
contract Animal {
string _birthDay; // 生日
int public _age; // 年齡
int internal _weight; // 身高
string private _name; // 姓名
function Animal() {
_age = 29;
_weight = 170;
_name = "Lucky dog";
_birthDay = "2011-01-01";
}
function birthDay() constant returns (string) {
return _birthDay;
}
function age() constant public returns (int) {
return _age;
}
function height() constant internal returns (int) {
return _weight;
}
function name() constant private returns (string) {
return _name;
}
}
在這個合約中,我們通過運行結果不難看出,可供外部調用的一個有三個函數,分別爲birthDay
,_age
,age
,也許有人會問,爲什麼外部可以調用_age
函數呢,爲什麼外部可以調用_age
函數呢,爲什麼外部可以調用_age
函數呢,原因是因爲我們的狀態變量_age
的權限是public
,當一個狀態變量的權限爲public
類型時,它就會自動生成一個可供外部調用的get
函數。在我們這個合約中,因爲_age
是public
類型,所以在合約中其實會有一個默認的和狀態變量同名的get函數
,如下所示:
function _age() constant public returns (int) {
return _age;
}
在我們顯示聲明的四個函數中:
function birthDay() constant returns (string) {
return _birthDay;
}
function age() constant public returns (int) {
return _age;
}
function height() constant internal returns (int) {
return _weight;
}
function name() constant private returns (string) {
return _name;
}
由上面的運行結果,我們知道,這四個函數中,只有birthDay
、age
函數可供外部訪問,【PS:age
函數是我顯示聲明的,_age
函數是因爲狀態變量_age
爲public
自動生成的,因爲狀態變量默認爲internal
類型,所以不會自動生成可供外部訪問的和狀態變量同名的函數】,換句話說,只有public
類型的函數纔可以供外部訪問,由此可知,函數聲明時,它默認爲是public
類型,而狀態變量聲明時,默認爲internal
類型。
小結:
- 狀態變量聲明時,默認爲
internal
類型,只有顯示聲明爲public
類型的狀態變量纔會自動生成一個和狀態變量同名的get
函數以供外部獲取當前狀態變量的值。 - 函數聲明時默認爲
public
類型,和顯示聲明爲public
類型的函數一樣,都可供外部訪問。
二、internal
internal
類型的狀態變量可供外部和子合約調用。internal
類型的函數和private
類型的函數一樣,智能合約自己內部調用,它和其他語言中的protected
不完全一樣。
pragma solidity ^0.4.4;
contract Animal {
string _birthDay; // 生日
int public _age; // 年齡
int internal _weight; // 身高
string private _name; // 姓名
function Animal() {
_age = 29;
_weight = 170;
_name = "Lucky dog";
_birthDay = "2011-01-01";
}
function birthDay() constant returns (string) {
return _birthDay;
}
function age() constant public returns (int) {
return _age;
}
function height() constant internal returns (int) {
return _weight;
}
function name() constant private returns (string) {
return _name;
}
}
contract Person is Animal {
function Person() {
_age = 50;
_weight = 270;
_birthDay = "2017-01-01";
}
}
在這個案例中,contract Person is Animal
,Person
合約繼承了Animal
合約的public/internal
的所有狀態變量,但是隻能繼承父合約中的所有的public
類型的函數,不能繼承internal/private
的函數,不能繼承internal/private
的函數,不能繼承internal/private
的函數。
三、private
我們在person
合約中嘗試調用_name
狀態變量,你會發現,編譯沒法通過。
因爲_name
狀態變量在Animal
合約中屬於private
私有類型,只能在Animal
內部使用,所以到我們在子合約Person
中嘗試使用時,就會報錯。
四、重寫
子合約可以將父合約的public
類型的函數,只能繼承public類型的函數,只能繼承public類型的函數,只能繼承public類型的函數,我們可以直接調用繼承過來的函數,當然,我們還可以對繼承過來的函數進行重寫。
- 重寫前
pragma solidity ^0.4.4;
contract Animal {
string _birthDay; // 生日
int public _age; // 年齡
int internal _weight; // 身高
string private _name; // 姓名
function Animal() {
_age = 29;
_weight = 170;
_name = "Lucky dog";
_birthDay = "2011-01-01";
}
function birthDay() constant returns (string) {
return _birthDay;
}
function age() constant public returns (int) {
return _age;
}
function height() constant internal returns (int) {
return _weight;
}
function name() constant private returns (string) {
return _name;
}
}
contract Person is Animal {
}
- 重寫後
pragma solidity ^0.4.4;
contract Animal {
string _birthDay; // 生日
int public _age; // 年齡
int internal _weight; // 身高
string private _name; // 姓名
function Animal() {
_age = 29;
_weight = 170;
_name = "Lucky dog";
_birthDay = "2011-01-01";
}
function birthDay() constant returns (string) {
return _birthDay;
}
function age() constant public returns (int) {
return _age;
}
function height() constant internal returns (int) {
return _weight;
}
function name() constant private returns (string) {
return _name;
}
}
contract Person is Animal {
function birthDay() constant returns (string) {
return "2020-12-15";
}
}
小結
本篇文章主要全面介紹了合約中狀態變量和函數中public、internal、private
三種權限在合約內部、外部以及子合約中的應用。通過本篇教程的學習,我相信你一定會進一步瞭解狀態變量的繼承以及函數繼承和重寫。接下來的系列文章中,我們將進一步講師Solidity中相關的語法以及開發中的注意事項。
技術交流
區塊鏈技術交流QQ羣:348924182
「區塊鏈部落」官方公衆號