Skip to content

Commit 958fdfb

Browse files
committed
Update oop-inheritance.ipynb
1 parent f17171c commit 958fdfb

1 file changed

Lines changed: 123 additions & 13 deletions

File tree

oop-inheritance.ipynb

Lines changed: 123 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -524,16 +524,90 @@
524524
"## 구성"
525525
]
526526
},
527+
{
528+
"cell_type": "markdown",
529+
"metadata": {},
530+
"source": [
531+
"상속은 공통 기능을 재활용하는 데 유용하지만, 모든 확장을 상속만으로 해결하려고 하면 클래스의 종류가\n",
532+
"너무 많아질 수 있다. 특히 기능이 실행 중에 바뀌어야 하는 경우에는 구성이 더 자연스럽다.\n",
533+
"예를 들어 영웅마다 비행 방식이 다를 수 있다.\n",
534+
"\n",
535+
" - 아이언맨: 로켓 장치 사용\n",
536+
" - 팔콘: 날개 사용\n",
537+
" - 토르: 특별한 장치 없이 스스로 비행"
538+
]
539+
},
540+
{
541+
"cell_type": "code",
542+
"execution_count": 21,
543+
"metadata": {},
544+
"outputs": [],
545+
"source": [
546+
"class Hero(Person):\n",
547+
" def __init__(self, *args, power, health, damage, inventory, flying=None, **kwargs):\n",
548+
" super().__init__(*args, **kwargs)\n",
549+
" self.power = power\n",
550+
" self.health = health\n",
551+
" self.damage = damage\n",
552+
" self.inventory = inventory\n",
553+
" self.flying = flying\n",
554+
"\n",
555+
" def introduction(self):\n",
556+
" super().introduction()\n",
557+
" print(f\"파워: {self.power}\")\n",
558+
" print(f\"무기: {self.inventory['weapon']}\")\n",
559+
"\n",
560+
" def attack(self, other):\n",
561+
" print(f\"{self.name}: {other.name} 공격!\")\n",
562+
" if self.power >= 300:\n",
563+
" attack_power = self.damage * 0.2\n",
564+
" else:\n",
565+
" attack_power = self.damage * 0.1\n",
566+
" other.health -= attack_power\n",
567+
" \n",
568+
" def fly(self):\n",
569+
" if self.flying is None:\n",
570+
" print(f\"{self.name}: 저는 날 수 없어요.\")\n",
571+
" else:\n",
572+
" print(f\"{self.name}: {self.flying}(으)로 날아갑니다!\")"
573+
]
574+
},
575+
{
576+
"cell_type": "code",
577+
"execution_count": 22,
578+
"metadata": {},
579+
"outputs": [],
580+
"source": [
581+
"ironman = Hero(\"아이언맨\", 45, \"남성\", power=100, health=100, damage=200, inventory={\"suit\": 500, \"weapon\": \"레이저\"}, flying=\"제트 엔진\")\n",
582+
"hulk = Hero(\"헐크\", 42, \"남성\", power=400, health=400, damage=300, inventory={\"suit\": 0, \"weapon\": \"주먹\"})"
583+
]
584+
},
585+
{
586+
"cell_type": "code",
587+
"execution_count": 24,
588+
"metadata": {},
589+
"outputs": [
590+
{
591+
"name": "stdout",
592+
"output_type": "stream",
593+
"text": [
594+
"아이언맨: 제트 엔진(으)로 날아갑니다!\n",
595+
"헐크: 저는 날 수 없어요.\n"
596+
]
597+
}
598+
],
599+
"source": [
600+
"ironman.fly()\n",
601+
"hulk.fly()"
602+
]
603+
},
527604
{
528605
"cell_type": "markdown",
529606
"id": "6f06227c",
530607
"metadata": {},
531608
"source": [
532609
"**구성**<font size='2'>composition</font>은 다른 클래스의 인스턴스를 인스턴스 속성으로\n",
533-
"지정하여 사용하는 기법을 의미한다.\n",
534-
"\n",
535-
"상속은 공통 기능을 재활용하는 데 유용하지만, 모든 확장을 상속만으로 해결하려고 하면 클래스의 종류가\n",
536-
"너무 많아질 수 있다. 특히 기능이 실행 중에 바뀌어야 하는 경우에는 구성이 더 자연스럽다."
610+
"지정하여 사용하는 기법을 의미한다."
537611
]
538612
},
539613
{
@@ -546,15 +620,8 @@
546620
},
547621
{
548622
"cell_type": "markdown",
549-
"id": "de8e84c9",
550623
"metadata": {},
551624
"source": [
552-
"예를 들어 영웅마다 비행 방식이 다를 수 있다.\n",
553-
"\n",
554-
"- 아이언맨: 로켓 장치 사용\n",
555-
"- 팔콘: 날개 사용\n",
556-
"- 토르: 특별한 장치 없이 스스로 비행\n",
557-
"\n",
558625
"가장 단순한 방식은 비행 방식에 따라 `RocketFlyingHero`, `WingFlyingHero`, `SelfFlyingHero` 같은\n",
559626
"여러 자식 클래스를 만드는 것이다. 하지만 이 방식은 비행 방식이 객체 생성 시점에 고정된다는 단점이 있다.\n",
560627
"\n",
@@ -777,6 +844,44 @@
777844
" self.flying = flying"
778845
]
779846
},
847+
{
848+
"cell_type": "code",
849+
"execution_count": null,
850+
"metadata": {},
851+
"outputs": [],
852+
"source": [
853+
"class Hero(Person):\n",
854+
" def __init__(self, *args, power, health, damage, inventory, flying=None, **kwargs):\n",
855+
" super().__init__(*args, **kwargs)\n",
856+
" self.power = power\n",
857+
" self.health = health\n",
858+
" self.damage = damage\n",
859+
" self.inventory = inventory\n",
860+
" self.flying = flying\n",
861+
"\n",
862+
" def introduction(self):\n",
863+
" super().introduction()\n",
864+
" print(f\"파워: {self.power}\")\n",
865+
" print(f\"무기: {self.inventory['weapon']}\")\n",
866+
"\n",
867+
" def attack(self, other):\n",
868+
" print(f\"{self.name}: {other.name} 공격!\")\n",
869+
" if self.power >= 300:\n",
870+
" attack_power = self.damage * 0.2\n",
871+
" else:\n",
872+
" attack_power = self.damage * 0.1\n",
873+
" other.health -= attack_power\n",
874+
" \n",
875+
" def fly(self):\n",
876+
" if self.flying is None:\n",
877+
" print(f\"{self.name}: 저는 날 수 없어요.\")\n",
878+
" else:\n",
879+
" self.flying.fly()\n",
880+
"\n",
881+
" def setFlying(self, flying):\n",
882+
" self.flying = flying"
883+
]
884+
},
780885
{
781886
"cell_type": "code",
782887
"execution_count": 19,
@@ -814,7 +919,7 @@
814919
"id": "fcd6d1b7",
815920
"metadata": {},
816921
"source": [
817-
"## OOP 디자인 패턴"
922+
"## OOP 디자인 원칙"
818923
]
819924
},
820925
{
@@ -833,7 +938,7 @@
833938
"따라서 비행 방식처럼 변할 수 있는 기능은 하나의 클래스에 고정하지 않고\n",
834939
"독립적인 객체로 분리하는 편이 좋다.\n",
835940
"\n",
836-
"**디자인 원칙 2: 상속보다 구성을 선호하라.**\n",
941+
"**디자인 원칙 2: 상속과 구성을 함께 활용하라.**\n",
837942
"\n",
838943
"상속은 공통 기능을 재사용하는 데 유용하지만, 모든 문제를 상속으로 해결하려고 하면\n",
839944
"클래스가 지나치게 많아지고 프로그램의 유연성이 떨어질 수 있다.\n",
@@ -844,6 +949,11 @@
844949
"상속은 공통 속성과 기능을 재사용하는 도구이고,\n",
845950
"구성은 변할 수 있는 기능을 유연하게 교체하는 도구이다."
846951
]
952+
},
953+
{
954+
"cell_type": "markdown",
955+
"metadata": {},
956+
"source": []
847957
}
848958
],
849959
"metadata": {

0 commit comments

Comments
 (0)