01 상속 개요
스마트 컨트랙 사이의 상속은 재산이나 권리를 주는것이 아닌, 변수와 함수들을 상속 해준다.
📌 예제 코드
// SPDX-License-Identifier: GPL-3.0
pragma solidity >= 0.7.0 < 0.9.0;
contract Father{
string public familyName = "Kim";
string public givenName = "Jung";
uint256 public money = 100;
function getFamilyName() view public returns(string memory){
return familyName;
}
function getGivenName() view public returns(string memory){
return givenName;
}
function getMoney() view public returns(uint256){
return money;
}
}
contract Son is Father{
}
→ 위 예제는 Father과 Son 컨트랙트에 대한 내용이다.
Father 컨트랙트에는 각각 "Kim","Jung",100의 값을 지닌 변수 familyName, givenName, money가 선언되었다. 또한 각각 familyName, givenName, money를 return하는 함수 getFamilyName, getGivenName, getMoney가 존재한다.
Son 컨트랙트는 Father 컨트랙트를 상속받았다. 이처럼 상속을 할 때에는 contract 컨트랙트명 is 상속받고자 하는 컨트랙트 명 순으로 작성할 수 있다.
위 예제 코드를 배포해보면 다음과 같은 결과 화면을 볼 수 있다.
▶ Son컨트랙트가 Father 컨트랙트를 상속 받았기 때문에 위와 같이 Son 컨트랙트를 배포하면 Father 컨트랙트에 있는 모든 것을 사용할 수 있음을 확인할 수 있다.
📌 추가 예제 코드
// SPDX-License-Identifier: GPL-3.0
pragma solidity >= 0.7.0 < 0.9.0;
contract Father{
string public familyName = "Kim";
string public givenName = "Jung";
uint256 public money = 100;
//추가
constructor(string memory _givenName) public {
givenName = _givenName;
}
function getFamilyName() view public returns(string memory){
return familyName;
}
function getGivenName() view public returns(string memory){
return givenName;
}
function getMoney() view public returns(uint256){
return money;
}
}
//추가
contract Son is Father("James"){
}
위 예제 코드에서는 Father 컨트랙트에 constructor 생성자를 추가하였다. 이 경우 contract 컨트랙트 명 is 상속받고자하는 컨트랙트 명(생성자) 순으로 작성해 상속을 받을 수 있다.
이처럼 추가 예제 코드를 실행한 후, 다시 배포한 결과를 확인해보면 변수 givenName의 값이 초기 생성자의 인자로 준 값인 "James" 인 것을 알 수 있다.
02 Overriding 오버라이딩
상속함에 따라, 상속 받은 함수를 다르게 변경하는 것을 오버라이딩이라고 한다. 즉, 상속받은 함수를 덮어씌기라고 생각할 수 있다.
📌 예제 코드
// SPDX-License-Identifier:GPL-30
pragma solidity >= 0.7.0 < 0.9.0;
contract Father{
string public familyName = "Kim";
string public givenName = "Jung";
uint256 public money = 100;
constructor(string memory _givenName) public {
givenName = _givenName;
}
function getFamilyName() view public returns(string memory){
return familyName;
}
function getGivenName() view public returns(string memory){
return givenName;
}
function getMoney() view public returns(uint256){
return money;
}
}
contract Son is Father("James"){
}
지난 실습 코드에서 발전시켜서 getMoney 부분을 오버라이딩해볼 수 있도록 코드를 작성해보자.
✅ 오버라이딩 함수 작성
→ 오버라이딩할 함수에 virtual을 명시해주어야 함.
function getMoney() view public virtual returns(uint256){
return money;
}
위에 작성한 코드와 같이 아버지 컨트랙에 virtual을 작성해주어 자식 컨트랙에서 오버라이딩을 할 것이라고 알려줄 수 있다.
이후 Son 컨트랙에 아래와 같이 작성해줄 수 있다.
contract Son is Father("James"){
uint256 public earning = 0;
function work() public {
earning += 100;
}
function getMoney() view public override returns(uint256){
return money+earning;
}
}
▶ 해당 오버라이드를 명시함으로써 getMoney의 함수를 오버라이딩 할 수 있게 된다. 즉, getMoney안의 내용들을 자유롭게 변경할 수 있다는 의미이다.→ 소스 코드를 더 살펴보면 기존 getMoney와 다르게 Son 컨트랙에서 return money+earning으로 변경된 것을 확인할 수 있다. 즉, getMoney가 오버라이딩 된 것이다.
이렇게 오버라이딩을 반영한 전체 코드는 아래와 같다.
// SPDX-License-Identifier:GPL-30
pragma solidity >= 0.7.0 < 0.9.0;
contract Father{
string public familyName = "Kim";
string public givenName = "Jung";
uint256 public money = 100;
constructor(string memory _givenName) public {
givenName = _givenName;
}
function getFamilyName() view public returns(string memory){
return familyName;
}
function getGivenName() view public returns(string memory){
return givenName;
}
function getMoney() view public virtual returns(uint256){
return money;
}
}
contract Son is Father("James"){
uint256 public earning = 0;
function work() public {
earning += 100;
}
function getMoney() view public override returns(uint256){
return money+earning;
}
}
03 두 개 이상 상속하기
우선, Father, Mother, Son 이렇게 총 3개의 컨트랙이 있다고 가정해보다.아들 컨트랙이 아버지와 어머니 컨트랙에게 기능 상속을 받기 위해서는 아래와 같이 상속받기 코드를 작성해줄 수 있다.
contract Son is Father,Mother{
}
만약, 아래와 같이 Father, Mother 컨트랙에 같은 이름의 함수가 있다면 어떻게 될까?
// SPDX-License-Identifier:GPL-30
pragma solidity >= 0.7.0 < 0.9.0;
contract Father{
uint256 public fatherMoney = 100;
function getFatherName() public pure returns(string memory){
return "KimJung";
}
function getMoney() public view returns(uint256){
return fatherMoney;
}
}
contract Mother{
uint256 public motherMoney = 500;
function getMotherName() public pure returns(string memory){
return "Leesol";
}
function getMoney() public view returns(uint256){
return motherMoney;
}
}
contract Son is Father, Mother {
}
먼저, Father 과 Mother 컨트랙 두개를 보면, 매우 유사하다.
getFatherName 과 getMotherName 은 아버지와 어머니 이름을 리턴하는 함수이다. 그리고, getMoeny라는 같은 이름의 함수가 Father , Mother 컨트랙에 각각 들어 있다.
이럴경우, Son 컨트랙이 Father과 Mother 컨트랙을 상속 받는다면 에러가 발생하고, override 하라고 명시하라고 에러가 뜨게 된다.
그렇기에, 이 똑같은 이름의 함수 getMoeny 를 가진 두개의 다른 Father, Mother 스마트컨트랙에, getMoeny 부분에 virtual 이라고 명시 해주어야 한다.
이후, overrride (Father,Mother) 을 써주어야 한다. 즉, 이런식으로 override ( 중복이름의 함수를 가진 스마트 컨트랙 명시) 해줄 수 있다.
// SPDX-License-Identifier:GPL-30
pragma solidity >= 0.7.0 < 0.9.0;
contract Father{
uint256 public fatherMoney = 100;
function getFatherName() public pure returns(string memory){
return "KimJung";
}
function getMoney() public view virtual returns(uint256){
return fatherMoney;
}
}
contract Mother{
uint256 public motherMoney = 500;
function getMotherName() public pure returns(string memory){
return "Leesol";
}
function getMoney() public view virtual returns(uint256){
return motherMoney;
}
}
contract Son is Father, Mother {
function getMoney() public view override(Father,Mother) returns(uint256){
return fatherMoney+motherMoney;
}
}
'Study > Blockchain & Solidity' 카테고리의 다른 글
[Blockchain A-Z] 블록체인의 직관적 이해 (0) | 2024.07.15 |
---|---|
[Solidity 깨부수기] 상속 & 이벤트 (2) (0) | 2024.06.05 |
[Solidity 깨부수기] Instance - constructor (0) | 2024.05.22 |
[Solidity 깨부수기] Instance 정의 (0) | 2024.05.15 |
[Solidity 깨부수기] Function (0) | 2024.04.29 |