|
524 | 524 | "## 구성" |
525 | 525 | ] |
526 | 526 | }, |
| 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 | + }, |
527 | 604 | { |
528 | 605 | "cell_type": "markdown", |
529 | 606 | "id": "6f06227c", |
530 | 607 | "metadata": {}, |
531 | 608 | "source": [ |
532 | 609 | "**구성**<font size='2'>composition</font>은 다른 클래스의 인스턴스를 인스턴스 속성으로\n", |
533 | | - "지정하여 사용하는 기법을 의미한다.\n", |
534 | | - "\n", |
535 | | - "상속은 공통 기능을 재활용하는 데 유용하지만, 모든 확장을 상속만으로 해결하려고 하면 클래스의 종류가\n", |
536 | | - "너무 많아질 수 있다. 특히 기능이 실행 중에 바뀌어야 하는 경우에는 구성이 더 자연스럽다." |
| 610 | + "지정하여 사용하는 기법을 의미한다." |
537 | 611 | ] |
538 | 612 | }, |
539 | 613 | { |
|
546 | 620 | }, |
547 | 621 | { |
548 | 622 | "cell_type": "markdown", |
549 | | - "id": "de8e84c9", |
550 | 623 | "metadata": {}, |
551 | 624 | "source": [ |
552 | | - "예를 들어 영웅마다 비행 방식이 다를 수 있다.\n", |
553 | | - "\n", |
554 | | - "- 아이언맨: 로켓 장치 사용\n", |
555 | | - "- 팔콘: 날개 사용\n", |
556 | | - "- 토르: 특별한 장치 없이 스스로 비행\n", |
557 | | - "\n", |
558 | 625 | "가장 단순한 방식은 비행 방식에 따라 `RocketFlyingHero`, `WingFlyingHero`, `SelfFlyingHero` 같은\n", |
559 | 626 | "여러 자식 클래스를 만드는 것이다. 하지만 이 방식은 비행 방식이 객체 생성 시점에 고정된다는 단점이 있다.\n", |
560 | 627 | "\n", |
|
777 | 844 | " self.flying = flying" |
778 | 845 | ] |
779 | 846 | }, |
| 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 | + }, |
780 | 885 | { |
781 | 886 | "cell_type": "code", |
782 | 887 | "execution_count": 19, |
|
814 | 919 | "id": "fcd6d1b7", |
815 | 920 | "metadata": {}, |
816 | 921 | "source": [ |
817 | | - "## OOP 디자인 패턴" |
| 922 | + "## OOP 디자인 원칙" |
818 | 923 | ] |
819 | 924 | }, |
820 | 925 | { |
|
833 | 938 | "따라서 비행 방식처럼 변할 수 있는 기능은 하나의 클래스에 고정하지 않고\n", |
834 | 939 | "독립적인 객체로 분리하는 편이 좋다.\n", |
835 | 940 | "\n", |
836 | | - "**디자인 원칙 2: 상속보다 구성을 선호하라.**\n", |
| 941 | + "**디자인 원칙 2: 상속과 구성을 함께 활용하라.**\n", |
837 | 942 | "\n", |
838 | 943 | "상속은 공통 기능을 재사용하는 데 유용하지만, 모든 문제를 상속으로 해결하려고 하면\n", |
839 | 944 | "클래스가 지나치게 많아지고 프로그램의 유연성이 떨어질 수 있다.\n", |
|
844 | 949 | "상속은 공통 속성과 기능을 재사용하는 도구이고,\n", |
845 | 950 | "구성은 변할 수 있는 기능을 유연하게 교체하는 도구이다." |
846 | 951 | ] |
| 952 | + }, |
| 953 | + { |
| 954 | + "cell_type": "markdown", |
| 955 | + "metadata": {}, |
| 956 | + "source": [] |
847 | 957 | } |
848 | 958 | ], |
849 | 959 | "metadata": { |
|
0 commit comments