써먹는 웹개발
[Java] 14강 상속, 클래스의 확장 본문
14강 상속, 클래스의 확장
- 상속을 쓰는 이유? A클래스를 만들고 나서 기능이 추가된 B클래스를 만들때 A클래스 소스를 중복없이 그대로 받아와서 사용하려고
1. 상속이란
- 정의 : 기존 클래스를 확장하여 새 클래스를 만드는 것
2. 상속 적용 예
RPG 게임에서 사용할 직업인, 초보자(Novice)와 마법사(Wizard) 두 개의 클래스를 만드려고할때 중복되는 부분을 상속으로 대체한다.
- 중복되는 부분 확인
extends 키워드를 사용하여, 마법사(Wizard)가 초보자(Novice)를 상속받게 했다. 이를 통해 코드를 줄일 수 있다.
3. 상속의 장점 2가지
4. 요약
5. 개념실습
1. 상속을 통한 클래스 확장
public class RPGTest {
public static void main(String[] args) {
// 객체 생성 및 초기화
Novice novice = new Novice();
novice.name = "프로도";
novice.hp = 100;
Wizard wizard = new Wizard();
wizard.name = "해리포터";
wizard.hp = 120;
wizard.mp = 100;
// 두 객체의 펀치
novice.punch();
wizard.punch();
// 위자드 객체의 파이어볼
wizard.fireball();
}
}
class Novice {
String name;
int hp;
public void punch() {
System.out.printf("[%s]의 펀치!!\n", name);
}
}
/* 1. Wizard 클래스를 Novice 클래스로부터 확장하세요. */
class Wizard extends Novice{
/* 2. mp 필드를 추가하세요. */
int mp;
/* 3. fireball() 메소드를 만드세요. */
public void fireball() {
System.out.printf("[%s]의 파이어볼@@\n", name);
}
}
2. 상속을 통한 중복 제거
public class InheritanceTest {
public static void main(String[] args) {
// 객체 생성
Pet dog = new Pet();
/* 4. 객체를 초기화하세요. */
dog.name = "차우차우";
dog.age = 3;
dog.price = 2200000;
// 정보 출력
System.out.printf("Pet { name: %s, age: %d세, price: %d원 }", dog.name, dog.age, dog.price);
}
}
class Animal {
String name; // 이름
public void cry() {
System.out.println("동물이 웁니다!");
}
}
/* 1. Pet 클래스를 Animal로부터 확장 선언 하세요. */
class Pet extends Animal {
/* 2. 부모 클래스 Animal과 중복되는 필드를 제거하세요. */
String name; // 이름
int age; // 나이
int price; // 가격
/* 3. 부모 클래스 Animal과 중복되는 메소드를 지우세요. */
public void cry() {
System.out.println("동물이 웁니다!");
}
public void play() {
System.out.println("애완 동물이 장난을 칩니다~");
}
}
3. 업 캐스팅
public class UpCasting {
public static void main(String[] args) {
// 기사 객체 생성 및 초기화
Knight knight = new Knight();
knight.name = "아서스";
knight.hp = 180;
knight.strength = 50;
// 도적 객체 생성 및 초기화
Thief thief = new Thief();
thief.name = "발리라";
thief.hp = 120;
thief.agility = 40;
// 업 캐스팅 - 부모 타입으로 객체를 해석
Adventurer adv0 = knight;
Adventurer adv1 = thief;
// 모험가들의 배열 생성
Adventurer[] advs = { adv0, adv1 };
// 모든 모험가의 정보 출력
for (int i = 0; i < advs.length; i++) {
System.out.println(advs[i].toString());
}
}
}
/* 1. 부모 클래스 Adventurer를 만드세요. */
class Adventurer {
/* 1.1 공통 필드를 선언하세요. */
String name;
int hp;
/* 1.2 공통 메소드를 작성하세요. */
public void punch() {
System.out.printf("[%s]의 펀치!!\n", name);
}
public String toString() {
return String.format("[%s] HP: %d", name, hp);
}
}
/* 2. Knight를 Adventurer의 자식 클래스로 정의하세요. */
class Knight extends Adventurer {
/* 2.1 부모와 중복된 필드를 제거하세요. */
int strength; // 힘
/* 2.2 부모와 중복된 메소드를 제거하세요. */
public void berserker() {
System.out.println("체력과 공격력이 증가합니다.");
}
}
/* 3. Thief를 Adventurer의 자식 클래스로 정의하세요. */
class Thief extends Adventurer {
/* 3.1 부모와 중복된 필드를 제거하세요. */
int agility; // 민첩
/* 3.2 부모와 중복된 메소드를 제거하세요. */
public void sharpen() {
System.out.println("크리티컬 확률이 증가합니다.");
}
}
4. ★ 메소드 오버라이딩(overriding)
public class Overriding {
public static void main(String[] args) {
// 객체 생성 및 초기화 - 정사각형
Square s = new Square();
s.name = "정사각형";
s.length = 5;
// 객체 생성 및 초기화 - 정삼각형
Triangle t = new Triangle();
t.name = "삼각형";
t.base = 4;
t.height = 3;
// 객체 생성 및 초기화 - 원
Circle c = new Circle();
c.name = "원";
c.radius = 4;
// 업 캐스팅 - 도형 배열에 정사각형, 삼각형, 원 담기
Shape[] shapes = { s, t, c };
// 모든 도형의 넓이 계산 및 출력
for (int i = 0; i < shapes.length; i++) {
Shape tmp = shapes[i];
System.out.printf("%s의 넓이 -> %.2f\n", tmp.name, tmp.area());
}
}
}
// 도형
class Shape {
String name;
// 도형의 넓이를 반환
public double area() {
return 0;
}
}
// 정사각형
class Square extends Shape {
int length; // 한 변의 길이
/* 1. 정사각형 넓이를 구하도록 area()를 재정의하세요. */
public double area() {
return length*length;
}
}
// 삼각형
class Triangle extends Shape {
int base; // 밑변
int height; // 높이
/* 2. 삼각형 넓이를 구하도록 area()를 재정의하세요. */
public double area() {
return base*height/2;
}
}
// 원
class Circle extends Shape {
int radius; // 반지름
/* 3. 원의 넓이를 구하도록 area()를 재정의하세요. */
public double area() {
return radius*radius*Math.PI;
}
}
5. protected 접근 제한자
public class ProtectedFields {
public static void main(String[] args) {
// 객체 생성
Basketball b = new Basketball();
Soccer s = new Soccer();
PingPong p = new PingPong();
// 객체 필드 초기화
b.name = "농구";
s.name = "축구";
p.name = "탁구";
// 부모 타입(업 캐스팅)으로 배열 생성
Sports[] sportsArr = { b, s, p };
// 모든 운동 설명 출력
for (int i = 0; i < sportsArr.length; i++) {
Sports tmp = sportsArr[i];
tmp.description();
}
}
}
// 운동
class Sports {
/* 1. 상속 관계 및 동일 패키지내에서 해당 필드를 자유로이 쓰게 하세요. */
protected String name;
public void description() {
System.out.printf("[%s]는 여가/경기/체력 단련 등을 위한 신체 운동입니다.\n", name);
}
}
// 농구
class Basketball extends Sports {
/* 2. 메소드 오버라이딩(재정의)을 통해 농구을 설명해주세요. */
public void description() {
System.out.printf("[%s]는 손으로 공을 던져 골을 넣는 운동이다.\n", name);
}
}
// 축구
class Soccer extends Sports {
/* 3. 메소드 오버라이딩(재정의)을 통해 축구을 설명해주세요. */
public void description() {
System.out.printf("[%s]는 주로 발로 공을 차 넣는 운동이다.\n", name);
}
}
// 탁구
class PingPong extends Sports {
/* 4. 메소드 오버라이딩(재정의)을 통해 탁구을 설명해주세요. */
public void description() {
System.out.printf("[%s]는 공을 번갈아가며 주고 받는 운동이다.\n", name);
}
}
6. ★ super - 상속과 생성자
public class SuperTest {
public static void main(String[] args) {
/* 1. Orc 객체를 만들고 정보를 출력하시오. */
Orc o = new Orc("오크",80);
System.out.println(o.toString());
/* 2. OrcWarrior 객체를 만들고 정보를 출력하시오. */
OrcWarrior ow = new OrcWarrior("오크전사", 120, 3);
System.out.println(ow.toString());
}
}
class Orc {
protected String name;
protected int hp;
public Orc(String name, int hp) {
this.name = name;
this.hp = hp;
}
public String toString() {
return String.format("Orc { name: %s, hp: %d }", this.name, this.hp);
}
}
class OrcWarrior extends Orc {
protected int amor;
public OrcWarrior(String name, int hp, int amor) {
super(name, hp);
this.amor = amor;
}
// 메소드 오버라이딩!
public String toString() {
return String.format("OrcWarrior { name: %s, hp: %d, amor: %d }", super.name, super.hp, this.amor);
}
}
7. 리뷰: 엘프의 연속 확장
public class ElvesTest {
public static void main(String[] args) {
// 객체 생성
Elf elf = new Elf("티란데", 100);
HighElf high = new HighElf("말퓨리온", 160, 100);
ElfLord lord = new ElfLord("마이에브", 230, 140, 100);
// 객체 배열 생성
Elf[] elves = { elf, high, lord };
// 모든 객체 정보 출력
for (int i = 0; i < elves.length; i++) {
System.out.println(elves[i].toString());
}
}
}
class Elf {
/* 1. 상속을 위한 접근 제한자를 사용하세요. */
protected String name;
protected int hp;
public Elf(String name, int hp) {
this.name = name;
this.hp = hp;
}
public String toString() {
return String.format("[엘프] Name: %s, HP: %d", name, hp);
}
}
class HighElf extends Elf {
protected int mp;
public HighElf(String name, int hp, int mp) {
super(name, hp);
this.mp = mp;
}
public String toString() {
return String.format("[하이엘프] Name: %s, HP: %d, MP: %d", name, hp, mp);
}
}
class ElfLord extends HighElf {
protected int shield;
public ElfLord(String name, int hp, int mp, int shield) {
/* 2. 부모의 생성자를 호출하세요. */
super(name,hp,mp);
this.shield = shield;
}
/* 3. toString() 메소드를 오버라이딩(재정의) 하세요. */
public String toString() {
return String.format("[엘프로드] Name: %s, HP: %d, MP: %d, SH: %d", name, hp, mp, shield);
}
}
강의 출처 : cloudstudying.kr/lectures/246
'Study > Java & Python' 카테고리의 다른 글
[Java] 15강 인터페이스 (0) | 2021.02.26 |
---|---|
[Java] 13강 자바 API (0) | 2021.02.25 |
[Java] 12강 접근 제한자와 게터(getter)&세터(setter) (0) | 2021.02.25 |
[Java] 11강 레퍼런스와 static편 학습 내용 보내드립니다. (0) | 2021.02.25 |
[Java] 10강 생성자 호출과 정의 (0) | 2021.02.25 |