오늘은 상속에 대해서 배웠다. 상속에 대한 추상과 구상, 그리고 abstract와 함께.
- 상속(extends)
(자식)클래스를 품을 수 있는 추상적인(덜 구체적) (부모)클래스 - 예제코드
// 문제 : 아래와 같이 출력되도록 해주세요. // 조건 : `숨쉬다` 기능을 중복하지 말아주세요.``
class Main {
public static void main(String\[\] args) {
사람 a사람 = new 사람();
a사람.숨쉬다();
}
}
class 동물 {
void 숨쉬다() {
System.out.println("숨쉬다.");
}
}
class 사람 extends 동물{ //동물 클래스 상속
}
예제 코드를 보면 부모 클래스인 동물의 메서드 숨쉬다 라는 기능을 상속(extends)을 받아서 사람 클래스에는 아무런 메서드가 없지만(눈에 보이지 않을 뿐 상속받아서 숨쉬다 메서드가 존재한다.) 숨쉬다라는 메서드가 작동한다. 부모 클래스인 동물은 광범위하고 덜 구체적이고, 따라서 추상적인 개념이고 사람은 동물로 분류되지만 동물보다는 구체적인 자식클래스이기 때문에 상속이 가능하다.
- 예제코드
class 고양이 {
void 숨쉬다() { }
void 야옹() { }
void 뛰어넘다() { }
}
class 검은고양이 extends 고양이 {
void 미래를\_예지하다() { }
}
class 흰고양이 extends 고양이 {
void 목숨을\_늘린다() { }
}
class 점박이고양이 extends 고양이 {
void 춤춘다() { }
} //상속 받으면 코드가 줄어든다.
흰고양이 a = new 흰고양이();
a.숨쉬다();
a.야옹();
a.미래를\_예지하다();
검은고양이 b = new 검은고양이();
b.숨쉬다();
b.야옹();
b.목숨을\_늘린다();
점박이고양이 c = new 점박이고양이();
c.숨쉬다();
c.야옹();
//상속 받지 못하면 같은 기능의 메서드가 늘어나 코드가 복잡해진다.
상속은 이런 개념이다. 상속을 하면 오버라이딩(overriding)을 할 수 있는데, 이는 같은 이름을 갖는 메서드를 덮어쓰면서 사용하는 개념이다. 정확하게는 상속 관계에 있는 부모 클래스에서 이미 정의된 메소드를 자식 클래스에서 같은 시그니쳐를 갖는 메소드로 다시 정의하는 것이라고 할 수 있다.
- 예제코드
// 문제 : 고무오리, 고무2오리, 흰오리, 청둥오리 객체를 만들고 날게 해주세요. 단 고무오리 계열은 날 수 없습니다.
// 조건 : 메서드는 중복될 수 없습니다.
class Main {
public static void main(String\[\] args) {
고무오리 a고무오리 = new 고무오리();
a고무오리.날다();
고무2오리 a고무2오리 = new 고무2오리();
a고무2오리.날다();
흰오리 a흰오리 = new 흰오리();
a흰오리.날다();
청둥오리 a청둥오리 = new 청둥오리();
a청둥오리.날다();
로봇오리 a로봇오리 = new 로봇오리();
a로봇오리.날다();
}
}
class 오리 {
void 날다 () {
System.out.println("오리날다.");
}
}
class 흰오리 extends 오리 {
}
class 청둥오리 extends 오리 {
}
class 고무오리 extends 오리 {
void 날다 () { //오버라이딩 (다형성)
System.out.println("오리 못날다.");
}
}
class 고무2오리 extends 오리 {
void 날다 () { //오버라이딩 (다형성)
System.out.println("오리 못날다.");
}
}
class 로봇오리 extends 오리 {
}
예제 코드가 '날다'라는 메서드를 고무오리에서 덮어쓴 형태다. 이게 오버라이딩이라고 한다.
- 오버라이딩 (Overriding) : 상위 클래스가 가지고 있는 메서드를 하위 클래스가 재정의해서 사용하는 것을 의미한다. 메서드의 이름은 물론 파라미터의 개수나 타입도 동일해야 하며, 주로 상위 클래스의 동작을 상속받는 하위 클래스에서 변경하기 위해 사용된다.
그리고 문제를 풀었다.
// 문제 : 매개변수를 사용해서 전사가 매번 다르게 공격하도록 해주세요.
class Main {
public static void main(String[] args) {
전사 a전사 = new 전사();
a전사.공격("브라이언", "칼");
// 브라이언이(가) 칼(으)로 공격합니다.
a전사.재공격();
// 브라이언이(가) 칼(으)로 공격합니다.
a전사.공격("필립", "창");
// 필립이(가) 창(으)로 공격합니다.
a전사.공격("마크", "지팡이");
// 마크(가) 지팡이(으)로 공격합니다.
a전사.재공격();
// 마크(가) 지팡이(으)로 공격합니다.
a전사.재공격();
// 마크(가) 지팡이(으)로 공격합니다.
}
}
class 사람 {
public void 공격() {
}
}
class 전사 extends 사람 {
String 마지막사람;
String 마지막공격;
void 공격(String a, String b) {
System.out.println(a + "이(가) " + b +"(으)로 공격합니다.");
this.마지막사람 = a;
this.마지막공격 = b;
}
void 재공격() {
System.out.println(this.마지막사람 + "이(가) " + this.마지막공격 + "(으)로 재공격합니다.");
}
}
- 형변환 문제
// 문제 : 정수 i가 가지고 있는 10을 double 형 변수에 넣고 해당 변수의 값을 다시 i에 넣는 코드를 작성해주세요.
class Main {
public static void main(String[] args) {
int i = 10;
double d = i; // 여기선 자동형변환 허용
i = (int) d; // 여기선 자동형변환 불가능 (형변환(캐스팅))
System.out.println(i);
}
}
이거는 어렵지 않게 이해가 되는데,
- 형변환 문제
// 문제 : 자동차 리모콘이 페라리 객체를 가리키게 한 후 해당 리모콘이 가리키고 있는 객체를
//다시 페라리 리모콘으로 가리키게(참조하게) 하는 코드를 작성해주세요.
class Main {
public static void main(String\[\] args) {
// `a페라리` 변수안의 리모콘은 버튼 개수가 3개 여야 한다.
페라리 a페라리 = new 페라리();
// `a자동차` 변수안의 리모콘은 버튼 개수가 2개 여야 한다.
자동차 a자동차;
// 수동형변환, 수동캐스팅
// `a페라리`안에 있던 리모콘은 가지고 있던 버튼 3개 중에서 `뚜껑이_열리다` 버튼이 뽑힌 후 `a자동차`에 저장된다.
a자동차 = (자동차)a페라리;
// 자동형변환, 자동캐스팅
// 자바가 판단하기에 안전한 경우만 자동형변환이 가능하다.
// 리모콘의 버튼 개수를 줄이는 경우는 언제나 안전하다.
a자동차 = a페라리;
// 아래에서는 `a자동차`변수에 들어있던 리모콘에 `뚜껑이_열리다` 버튼이 추가된다.
// 자바에서는 리모콘에 버튼이 빠지는건 상관하지 않지만 추가되는건 굉장히 무서워 한다.
// 왜냐하면 추가된 버튼에 해당된 기능이 연결된 객체에 없을 수도 있기 때문이다.
// 그렇기 때문에 여기서는 무조건 수동형변환을 사용한다.
// 수동형변환을 사용하는 이유는 자바에게 개발자의 의도(이게 실수가 아니라는 뜻)를 명확히 밝히는 것과 같다.
페라리 a페라리2 = (페라리)a자동차;
}
}
class 자동차 {
void 달리다() {}
void 서다() {}
}
class 페라리 extends 자동차 {
void 뚜껑이\_열리다() {}
이건 솔직히 봐도 무슨말인지 잘 모르겠다. 어렴풋이 알 것 같다가도 뭔소린가 싶기도 하고 나중에 집 가면 그림으로 한번 그려봐야겠다. 강사님도 지금은 이해가 안될거라고 한번 훑어보라고만 하셨는데 아무리 그래도 당최 모르겠다.
아무튼 내준 숙제 하고 얼른 집 가서 잠을 자야겠다.
'Coding History' 카테고리의 다른 글
국비 지원 IT(웹앱개발) 취업반 강의 11일차 (0) | 2024.06.20 |
---|---|
국비 지원 IT(웹앱개발) 취업반 강의 10일차 (0) | 2024.06.19 |
2024. 06. 17 문제 풀이 (0) | 2024.06.18 |
국비 지원 IT(웹앱개발) 취업반 강의 8일차 (0) | 2024.06.17 |
2024. 06. 13 IP주소를 알아봅시다! (Feat. 공인/사설/고정/유동IP, 포트포워딩, DMZ, DDNS) (0) | 2024.06.13 |