وراثت (inheritance) در سالیدیتی
سلام دوستان و همراهان عزیز سالیدیتی کد! امیدواریم حالتون خوب باشه!! در این مقاله قصد داریم تا با وراثت در برنامه نویسی و به صورت اختصاصی وراثت در سالیدیتی آشنا بشیم. البته در دوره آموزش سالیدیتی به صورت کامل و با ذکر مثال این مورد بررسی شده و اگر از دانشجویان دوره هستید پیشنهاد می کنم قسمت مربوط به وراثت در solidity را مشاهده کنید.
قبل از هر چیز اول یک تعریف از وراثت در برنامه نویسی داشته باشیم :
وراثت یعنی چه؟
به طور کلی زمانی که یک کلاس در برنامه نویسی از کلاس دیگری ویژگی یا رفتار هایی ارث بری کنه مفهوم وراثت معنی پیدا می کنه. برای درک بهتر این موضوع مثال زیر را ببینید:
در مثال بالا ما یک کلاس به اسم Human داریم که دو کلاس Father و Mother از کلاس Human ویژگی هایی را ارث بری کرده اند در نهایت کلاس Child از دو کلاس Father و Mother ویژگی هایی را ارث بری کرده است. خیلی ساده بود نه؟!
شما با استفاده از وراثت در سالیدیتی نیازی نیست کد ها را مجدد بنویسید و برای هر کلاس مجدد ویژگی ها را تعریف کنید در واقع با استفاده از این روش هم کدهای خوانا تر و تمیز تری دارید و هم از اضافه کاری و پیچیدگی های بی مورد جلوگیری می کنید.
وراثت چند گانه چیست ؟
احتمالا می تونید مفهوم وراثت چندگانه رو حدس بزنید! زمانی که یک کلاس از چند کلاس ارث بری کند وراثت چندگانه اتفاق میافتد مجددا ویدیو بالا را مشاهده کنید، کلاس Child از دو کلاس Mother و Father ارث بری کرده ولی کلاس Mother یا Father صرفا از یک کلاس ارث بری کرده اند
و اما . . .
وراثت در سالیدیتی
سالیدیتی هم از وراثت پیشتیبانی می کند و شما می توانید متغیر ها، توابع، Modifier و رویداد ها را بین قرارداد ها استفاده کنید. وراثت چندگانه در سالیدیتی هم وجود دارد و یک قرارداد می تواند از چند قرارداد دیگر ارث بری کند. در سالیدیتی به قراردادی که دیگر قرارداد ها از آن ارث بری می کنند قرارداد پایه می گویند و به قرارداد هایی که از قرارداد پایه ارث بری م کنند قرارداد مشتق می گویند.
تصویر زیر وراثت در solidity را نمایش می دهد
همانطور که اشاره شد سالیدیتی از وراثت چند گانه هم پشتیبانی می کند. تصویر زیر نمایانگر مفهوم وراثت چند گانه در سالیدیتی است
همانطور که مشاهده می کنید قرارداد D از دو قرارداد B , C مشتق شده است که این حالت اصطلاحا وراثت چند گانه است.
خب بریم سراغ یک مثال از وراثت در solidity، البته قبلش پیشنهاد می کنم شما هم با استفاده از محیط Remix چندباری این کد ها را تمرین کنید تا حسابی ملکه ذهنتون بشه.
مثال وراثت در سالیدیتی
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.13;
/* Graph of inheritance
A
/ \
B C
/ \ /
F D,E
*/
contract A {
function foo() public pure virtual returns (string memory) {
return "A";
}
}
// Contracts inherit other contracts by using the keyword 'is'.
contract B is A {
// Override A.foo()
function foo() public pure virtual override returns (string memory) {
return "B";
}
}
contract C is A {
// Override A.foo()
function foo() public pure virtual override returns (string memory) {
return "C";
}
}
// Contracts can inherit from multiple parent contracts.
// When a function is called that is defined multiple times in
// different contracts, parent contracts are searched from
// right to left, and in depth-first manner.
contract D is B, C {
// D.foo() returns "C"
// since C is the right most parent contract with function foo()
function foo() public pure override(B, C) returns (string memory) {
return super.foo();
}
}
contract E is C, B {
// E.foo() returns "B"
// since B is the right most parent contract with function foo()
function foo() public pure override(C, B) returns (string memory) {
return super.foo();
}
}
// Created by Soliditycode.ir
// Inheritance must be ordered from “most base-like” to “most derived”.
// Swapping the order of A and B will throw a compilation error.
contract F is A, B {
function foo() public pure override(A, B) returns (string memory) {
return super.foo();
}
}
همانطور که گفته شد مثال بالا وراثت چندگانه در سالیدیتی را نشان می دهد.
وراثت در solidity ویژگی هایی دارد که باید به آن ها توجه کنید.
ویژگی های وراثت در سالیدیتی
- یک قرارداد مشتق شده می تواند به همه اعضای غیرخصوصی از جمله متغیرهای حالت و روش های داخلی دسترسی داشته باشد
- می توان تابع را نادیده گرفت البته به شرط اینکه امضای تابع ثابت بماند در صورتی که پارامترهای خروجی اختلاف داشته باشند برای کامپایل خطا دریافت می کنید
- تابع یک قرارداد را می توانید با استفاده از کلمه کلیدی و یا با استفاده از نام قرارداد فراخوانی کنید
انواع وراثت در سالیدیتی Solidity
سالیدیتی از انواع مختلفی از روش های ارث بری پشتیبانی می کند. در ادامه با ذکر مثال این روش ها را توضیح می دهیم
وراثت تک سطحی در سالیدیتی یا Single Inheritance
در این نوع وراثت قرارداد فرزند فقط از قرارداد والد ارث بری می کند. در تکه کد زیر این نوع از وراثت را می توانید مشاهده کنید
// Solidity program to
// demonstrate
// Single Inheritance
pragma solidity >=0.4.22 <0.6.0;
// Defining contract
contract parent{
// Declaring internal
// state variable
uint internal sum;
// Defining external function
// to set value of internal
// state variable sum
function setValue() external {
uint a = 10;
uint b = 20;
sum = a + b;
}
}
// Defining child contract
contract child is parent{
// Defining external function
// to return value of
// internal state variable sum
function getValue(
) external view returns(uint) {
return sum;
}
}
// Defining calling contract
contract caller {
// Creating child contract object
child cc = new child();
//Created by soliditycode.ir
// Defining function to call
// setValue and getValue functions
function testInheritance(
) public returns (uint) {
cc.setValue();
return cc.getValue();
}
}
اگر نمونه کد وراثت تک سطحی در سالیدیتی که در بالا است را در محیط ریمیکس امتحان کنید خروجی به شکل زیر خواهد بود
وراثت چند سطحی در سالیدیتی MultiLevel Inheritance
همانطور که در شکل بالا مشاهده می کنید این نوع وراثت شباهت بسیار زیادی به وراثت تک سطحی دارد با این تفاوت که قرارداد والد نیز از قرارداد دیگری ارث بری کرده است. در واقع قرارداد C از قرارداد B و قرارداد B از قرارداد A ارث بری کرده است. تکه کد زیر نمونه ای از وراثت چند سطحی در سالیدیتی است
// Solidity program to
// demonstrate Multi-Level
// Inheritance
pragma solidity >=0.4.22 <0.6.0;
// Defining parent contract A
contract A {
// Declaring state variables
string internal x;
string a = "Geeks" ;
string b = "For";
// Defining external function
// to return concatenated string
function getA() external{
x = string(abi.encodePacked(a, b));
}
}
// Defining child contract B
// inheriting parent contract A
contract B is A {
// Declaring state variables
// of child contract B
string public y;
string c = "Geeks";
// Defining external function to
// return concatenated string
function getB() external payable returns(
string memory){
y = string(abi.encodePacked(x, c));
}
}
// Defining child contract C
// inheriting parent contract A
contract C is B {
// Defining external function
// returning concatenated string
// generated in child contract B
function getC() external view returns(
string memory){
return y;
}
}
// Defining calling contract
contract caller {
// Creating object of child C
C cc = new C();
// created by soliditycode.ir
// Defining public function to
// return final concatenated string
function testInheritance(
) public returns (
string memory) {
cc.getA();
cc.getB();
return cc.getC();
}
}
اگر کد بالا را در محیط توسعه اجرا کنید خروجی زیر را دریافت خواهید کرد
وراثت چندگانه در سالیدیتی Multiple inheritance
همانطور که در ابتدای این مقاله اشاره شد وراثت چندگانه زمانی معنی پیدا می کند که یک فرزند بیش از یک والد داشته باشد که در تصویر بالا این مفهوم کاملا مشخص شده است.
تکه کد زیر هم یک نمونه از وراثت چندگانه در solidity است
// Solidity program to
// demonstrate
// Multiple Inheritance
pragma solidity >=0.4.22 <0.6.0;
// Defining contract A
contract A {
// Declaring internal
// state variable
string internal x;
// Defining external function
// to set value of
// internal state variable x
function setA() external {
x = "GeeksForGeeks";
}
}
// Defining contract B
contract B {
// Declaring internal
// state variable
uint internal pow;
// Defining external function
// to set value of internal
// state variable pow
function setB() external {
uint a = 2;
uint b = 20;
pow = a ** b;
}
}
// Defining child contract C
// inheriting parent contract
// A and B
contract C is A, B {
// Defining external function
// to return state variable x
function getStr(
) external returns(string memory) {
return x;
}
// Defining external function
// to return state variable pow
function getPow(
) external returns(uint) {
return pow;
}
}
// Defining calling contract
contract caller {
// created by soliditycode.ir
// Creating object of contract C
C contractC = new C();
// Defining public function to
// return values from functions
// getStr and getPow
function testInheritance(
) public returns(string memory, uint) {
contractC.setA();
contractC.setB();
return (
contractC.getStr(), contractC.getPow());
}
}
سخن آخر
امیدواریم این مقاله براتون مفید بوده باشه و در آخر اگر سوال یا نظری دارید در بخش نظرات برامون بنویسید
دیدگاهتان را بنویسید