وراثت در سالیدیتی قابلیتی است که به شما اجازه میدهد توابع و ویژگیهای یک قرارداد دیگر را به ارث ببرید و بدون تکرار کد، قراردادهای پیچیده تری ایجاد کنید.
وراثت در سالیدیتی چیست؟
وراثت در سالیدیتی به معنی قابلیت استفاده مجدد از کدهای یک قرارداد دیگر در یک قرارداد جدید است. با استفاده از وراثت، میتوان یک قرارداد جدید ایجاد کرد که تمام توابع و متغیرهای قرارداد پایه (پدر) را به ارث ببرد و در صورت نیاز آنها را بازنویسی (override) کند.
این ویژگی باعث افزایش بهرهوری، کاهش تکرار کد و ساختارمند شدن توسعه قراردادهای هوشمند میشود. مثلاً در پیاده سازی توکن های ERC20 معمولاً بهجای نوشتن همه توابع از صفر، از یک قرارداد استاندارد استفاده میشود و قرارداد جدید از آن ارث بری میکند.
آموزش وراثت در سالیدیتی
در ادامه مثالی ساده از استفاده از وراثت را میبینیم که در آن یک قرارداد پایه تعریف شده و قرارداد دیگر از آن ارث بری میکند.
1 2 3 4 5 6 7 8 9 10 11 12 |
contract Parent { function theMeaningOfLife() public pure returns (uint256) { return 42; } } contract Child is Parent { } |
حتی با اینکه قرارداد Child خالی است، ما تابع را در داخل Child مشاهده میکنیم.
وقتی یک «قرارداد» «قرارداد دیگری» است، تمام عملکردهای آن را به ارث میبرد.
مانند دیگر زبان های برنامه نویسی شیگرا، توابع میتوانند بازنویسی (override) شوند. در اینجا ساختاری برای تغییر مقدار آورده شده است.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
contract Parent { function theMeaningOfLife() public pure virtual returns (uint256) { return 42; } } contract Child is Parent { function theMeaningOfLife() public pure override returns (uint256) { return 43; } } |
توجه داشته باشید که فقط توابعی که virtual هستند میتوانند بازنویسی شوند. اگر سعی کنید تابعی که virtual نیست را override کنید، کد کامپایل نخواهد شد.
همچنین، زمانی که یک تابع override میشود، باید دقیقاً مطابق باشد؛ هم از نظر نام، هم آرگومان ها، و هم نوع بازگشتی.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 |
contract Parent { function theMeaningOfLife() public pure virtual returns (uint256) { return 42; } } contract Child is Parent { // INVALID: has different arguments function theMeaningOfLife(uint256 x) public pure override returns (uint256) { return 42 + x; } // INVALID: has different return type function theMeaningOfLife(uint256 x) public pure override returns (bool) { return true; } // INVALID: has different name function theMeaningOfLif3(uint256 x) public pure override returns (uint256) { return 42; } } |
سالیدیتی از وراثت چندگانه پشتیبانی میکند.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
contract Parent1 { function theMeaningOfLife() public pure virtual returns (uint256) { return 42; } } contract Parent2 { function hackerFavoriteNumber() public pure virtual returns (uint256) { return 1337; } } contract Child is Parent1, Parent2 { } |
اگر برایتان سوال است، در صورتی که دو والد تابعی با نام یکسان داشته باشند، فرزند باید آن را override کند، در غیر این صورت رفتار نامشخص خواهد بود. اگر در چنین شرایطی قرار گرفتید، احتمالاً در طراحی نرمافزار اشتباهی انجام دادهاید. پس بهتر است وارد آن مسیر نشویم.
Private در مقابل Internal
دو روش برای غیرقابل دسترسی کردن یک تابع از بیرون وجود دارد: استفاده از مادیفایر private یا internal. تفاوت آنها ساده است.
توابع (و متغیرهای) private نمیتوانند توسط قراردادهای فرزند «دیده شوند».
توابع و متغیرهای internal میتوانند.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
contract Parent { function foo() internal pure virtual returns (string memory) { return "foo"; } // error! private functions cannot be overriden, // so no point in making them virtual! function bar() private pure virtual returns (string memory) { return "bar"; } } |
کلمه کلیدی super
کلمه کلیدی super به معنی «فراخوانی تابع والد» است. در اینجا چگونگی مفید بودن آن آورده شده است.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
contract Parent { function foo() internal pure virtual returns (string memory) { return "foo"; } } contract Child is Parent { // we have overriden foo and made it public function foo() public pure override returns (string memory) { return super.foo(); } } |
اگر در اینجا از کلمه کلیدی super
استفاده نمیکردیم، تابع foo()
خودش را صدا میزد و وارد بازگشت بینهایت میشد. سعی کنید super
را حذف کرده و کد را در Remix اجرا کنید. تراکنش بازمیگردد (revert میشود) چون بازگشت بینهایت رخ میدهد (اتریوم اجازه نمیدهد کد برای همیشه اجرا شود، آن را بهاجبار متوقف میکند. مکانیزم دقیق آن یک موضوع سطح متوسط برای بحث در آینده است).
super
به این معناست که “تابع foo
والد را صدا بزن، نه تابع من”. این به ما اجازه میدهد که تمام قابلیتهای foo
را داشته باشیم، بدون اینکه مجبور باشیم کد آن را کپی و جای گذاری کنیم.
فراخوانی سازنده والد
سالیدیتی اجازه نمیدهد بدون مقداردهی اولیه به سازندهی والد، از آن ارثبری کنید. به این وضعیت توجه کنید:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
contract Parent { string private name; constructor(string memory _name) { name = _name; } function getName() public view virtual returns (string memory) { return name; } } contract Child is Parent { // error, name hasn't been set! function getName() public view override returns (string memory) { return super.getName(); } } |
راهحل این است که سازنده والد را در نقطه ارث بری صدا بزنید.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 |
contract Parent { string private name; constructor(string memory _name) { name = _name; } function getName() public view virtual returns (string memory) { return name; } } //fixed contract Child is Parent("The Beatles") { function getName() public view override returns (string memory) { return super.getName(); } } |
بیایید آنچه را که یاد گرفتیم خلاصه کنیم:
-
فقط توابعی که
virtual
هستند میتوانند override شوند -
توابعی که یک تابع والد را override میکنند، باید از مادیفایر
override
استفاده کنند -
تابع override شده باید دقیقاً مطابقت داشته باشد؛ از نظر نام، آرگومان ها، و نوع مقدار بازگشتی
-
به جای کپی و جای گذاری کد تابع والد، میتوانید از کلیدواژه
super
استفاده کنید -
میتوانید از چند قرارداد بهصورت همزمان ارث بری کنید
-
هنگام ارثبری، باید سازنده والد را بهصورت صریح فراخوانی کنید
ایجاد یک توکن ERC20 با کمی تلاش
ارث بری، همراه با دستور import
، باعث میشود بتوانیم بهراحتی از کتابخانه هایی که دیگران ساختهاند استفاده کنیم. این قرارداد را در Remix دیپلوی کنید و خواهید دید تمام توابع ERC20 برایتان پیاده سازی شدهاند.
1 2 3 4 5 |
import "@openzeppelin/contracts/token/ERC20/ERC20.sol"; contract Token is ERC20("SomeToken", "symbol") { } |
نکته ای برای روشن شدن موضوع:
تفاوت زیادی بین یک قرارداد هوشمند بهعنوان یک شیء در سالیدیتی و یک قرارداد هوشمند دیپلوی شده روی بلاکچین وجود دارد.
شما نمیتوانید از قراردادی که روی بلاکچین دیپلوی شده، ارث بری کنید.
آنها باینری هایی هستند که مستقل از شما در خارج از قرارداد شما زندگی میکنند. به دلیل اصطلاحات مبهم، برخی از توسعه دهندگان سالیدیتی نگران این بودهاند که توابع و متغیرها ممکن است توسط یک قرارداد مخرب به ارث برده یا override شوند. این امکانپذیر نیست. حتی اگر کد دیپلوی شده را «قرارداد» بنامیم و کد سالیدیتی را هم «قرارداد» صدا کنیم، این دو با هم یکسان نیستند.
راستی! برای دریافت مطالب جدید در کانال تلگرام یا پیج اینستاگرام سورس باران عضو شوید.
- انتشار: ۱۶ اردیبهشت ۱۴۰۴
دسته بندی موضوعات
- آموزش ارز دیجیتال
- آموزش برنامه نویسی
- آموزش متنی برنامه نویسی
- اطلاعیه و سایر مطالب
- پروژه برنامه نویسی
- دوره های تخصصی برنامه نویسی
- رپورتاژ
- فیلم های آموزشی
- ++C
- ADO.NET
- Adobe Flash
- Ajax
- AngularJS
- apache
- ARM
- Asp.Net
- ASP.NET MVC
- AVR
- Bootstrap
- CCNA
- CCNP
- CMD
- CSS
- Dreameaver
- EntityFramework
- HTML
- IOS
- jquery
- Linq
- Mysql
- Oracle
- PHP
- PHPMyAdmin
- Rational Rose
- silver light
- SQL Server
- Stimulsoft Reports
- Telerik
- UML
- VB.NET&VB6
- WPF
- Xml
- آموزش های پروژه محور
- اتوکد
- الگوریتم تقریبی
- امنیت
- اندروید
- اندروید استودیو
- بک ترک
- بیسیک فور اندروید
- پایتون
- جاوا
- جاوا اسکریپت
- جوملا
- دلفی
- دوره آموزش Go
- دوره های رایگان پیشنهادی
- زامارین
- سئو
- ساخت CMS
- سی شارپ
- شبکه و مجازی سازی
- طراحی الگوریتم
- طراحی بازی
- طراحی وب
- فتوشاپ
- فریم ورک codeigniter
- فلاتر
- کانستراکت
- کریستال ریپورت
- لاراول
- معماری کامپیوتر
- مهندسی اینترنت
- هوش مصنوعی
- یونیتی
- کتاب های آموزشی
- Android
- ASP.NET
- AVR
- LINQ
- php
- Workflow
- اچ تی ام ال
- بانک اطلاعاتی
- برنامه نویسی سوکت
- برنامه نویسی موبایل
- پاسکال
- پایان نامه
- پایتون
- جاوا
- جاوا اسکریپت
- جی کوئری
- داده کاوی
- دلفی
- رباتیک
- سئو
- سایر کتاب ها
- سخت افزار
- سی اس اس
- سی پلاس پلاس
- سی شارپ
- طراحی الگوریتم
- فتوشاپ
- مقاله
- مهندسی نرم افزار
- هک و امنیت
- هوش مصنوعی
- ویژوال بیسیک
- نرم افزار و ابزار برنامه نویسی
- وردپرس