저번시간
자바 클래스의 상속 흰오리와 청둥오리가 날 수 있다고 하는것과
고무오리와 고무2오리가 날 수 없다고 하는것까지 출력했는데
로봇오리가 날기도 하고 수영도 할 수 있는 컨셉의 코드를 짜야했다.
로봇오리가 날기도 하고 수영도 할 수 있는 컨셉의 코드
// 문제 : 아래와 같이 출력되도록 해주세요.
// 조건 : 소스코드 중복이 없어야 합니다.
// 조건 : 복잡한 상속을 써도 됩니다.
class Main {
public static void main(String[] args) {
System.out.println("== 오리 ==");
오리 a오리 = new 오리();
a오리.날다(); // 오리가 날개로 날아갑니다.
a오리.수영하다(); // 오리가 물갈퀴로 수영합니다.
System.out.println("== 청둥오리 ==");
청둥오리 a청둥오리 = new 청둥오리();
a청둥오리.날다(); // 오리가 날개로 날아갑니다.
a청둥오리.수영하다(); // 오리가 물갈퀴로 수영합니다.
System.out.println("== 흰오리 ==");
흰오리 a흰오리 = new 흰오리();
a흰오리.날다(); // 오리가 날개로 날아갑니다.
a흰오리.수영하다(); // 오리가 물갈퀴로 수영합니다.
System.out.println("== 고무오리 ==");
고무오리 a고무오리 = new 고무오리();
a고무오리.날다(); // 저는 못 날아요 ㅠㅠ
a고무오리.수영하다(); // 오리가 물에 둥둥 떠다닙니다.
System.out.println("== 고무2오리 ==");
고무2오리 a고무2오리 = new 고무2오리();
a고무2오리.날다(); // 저는 못 날아요 ㅠㅠ
a고무2오리.수영하다(); // 오리가 물에 둥둥 떠다닙니다.
System.out.println("== 로봇오리 ==");
로봇오리 a로봇오리 = new 로봇오리();
a로봇오리.날다(); // 오리가 날개로 날아갑니다.
a로봇오리.수영하다(); // 오리가 물에 둥둥 떠다닙니다.
}
}
class 오리 {
void 날다() {
System.out.println("오리가 날개로 날아갑니다.");
}
void 수영하다() {
System.out.println("오리가 물갈퀴로 수영합니다.");
}
}
class 흰오리 extends 오리 { }
class 청둥오리 extends 오리 { }
class 고무오리 extends 오리 {
void 날다() {
System.out.println("저는 못 날아요. ㅜㅠ");
}
void 수영하다() {
System.out.println("오리가 물에 둥둥 떠다닙니다.");
}
}
class 고무2오리 extends 고무오리 { }
class 로봇오리 extends 흰오리 { }
출력
== 오리 ==
오리가 날개로 날아갑니다.
오리가 물갈퀴로 수영합니다.
== 청둥오리 ==
오리가 날개로 날아갑니다.
오리가 물갈퀴로 수영합니다.
== 흰오리 ==
오리가 날개로 날아갑니다.
오리가 물갈퀴로 수영합니다.
== 고무오리 ==
저는 못 날아요. ㅜㅠ
오리가 물에 둥둥 떠다닙니다.
== 고무2오리 ==
저는 못 날아요. ㅜㅠ
오리가 물에 둥둥 떠다닙니다.
== 로봇오리 ==
오리가 날개로 날아갑니다.
오리가 물갈퀴로 수영합니다.
형변환
// 문제 : 아래가 실행되도록 해주세요.
class Main {
public static void main(String[] args) {
칼 a칼 = new 칼(); // a칼은 class 칼에 소속되어있다.
a칼 = new 활(); // a칼은 class 칼에 소속되어있는데
활은 class 칼에 소속되어있지 않아서 활을 칼의 자식으로 상속시켜줘야 소속된다.
}
}
class 칼 {
}
class 활 extends 칼{
}
무기 a무기 = new 칼();
칼을 무기의 자식으로 상속시켜야 하는 상황
무기라는 형태에 맞춰서 칼이라는 값이 들어왔기 때문에
class Main {
public static void main(String[] args) {
무기 a무기 = new 칼();
a무기.공격(); // 출력 : 칼로 공격합니다.
a무기.방어(); // 출력 : 칼로 방어합니다.
}
}
// 리모컨 전용 클래스
class 무기 {
void 공격() { // abstract
}
void 방어() { // abstract
}
}
class 칼 extends 무기{
String weapon = "칼";
void 공격() {
System.out.println (weapon + "로 공격합니다.");
}
void 방어() {
System.out.println(weapon +"로 방어합니다.");
}
}
TV와 리모컨 컨셉으로 적용한 클래스의 형변환과 상속구조 이해
class Main {
public static void main(String[] args) {
TV a리모컨 = new 삼성TV();
a리모컨.채널_업(); // 출력 : 칼로 공격합니다.
a리모컨.채널_다운(); // 출력 : 칼로 방어합니다.
}
}
// 리모컨 전용 클래스
class TV {
void 채널_업() { // abstract
}
void 채널_다운() { // abstract
}
}
class 삼성TV extends TV{
String ch = "채널";
void 채널_업() {
System.out.println (ch + "이 올라갑니다.");
}
void 채널_다운() {
System.out.println(ch + "이 내려갑니다.");
}
}
지역변수와 this.을 활용해서
public class Main {
public static void main(String[] args) {
전사 a전사 = new 전사();
a전사.공격("브라이언", "칼");
// 브라이언(이)가 칼(으)로 공격합니다.
a전사.재공격();
// 브라이언(이)가 칼(으)로 공격합니다.
a전사.공격("필립", "창");
// 필립(이)가 창(으)로 공격합니다.
a전사.공격("마크", "지팡이");
// 마크(이)가 지팡이(으)로 공격합니다.
a전사.재공격();
// 마크(이)가 지팡이(으)로 공격합니다.
a전사.재공격();
// 마크(이)가 지팡이(으)로 공격합니다.
}
}
class 전사 {
String name; // class 내부에 지역변수, 인스턴스 변수(객체화 되면서 만들어진 변수)
String weapon; // class 내부에 지역변수, 인스턴스 변수(객체화 되면서 만들어진 변수)
void 공격 (String name, String weapon) {
this.name = name; // this.를 이용한 변수값을 재할당 해주면서 매개변수 안에 있는 값을 가져올 수 있게 됨.
this.weapon = weapon; // this.를 이용한 변수값을 재할당 해주면서 매개변수 안에 있는 값을 가져올 수 있게 됨.
System.out.println(name + "(이)가 " + weapon + "(으)로 공격합니다.");
}
void 재공격 () {
System.out.println(this.name + "(이)가 " + this.weapon + "(으)로 공격합니다.");
}
}
출력
브라이언(이)가 칼(으)로 공격합니다.
브라이언(이)가 칼(으)로 공격합니다.
필립(이)가 창(으)로 공격합니다.
마크(이)가 지팡이(으)로 공격합니다.
마크(이)가 지팡이(으)로 공격합니다.
마크(이)가 지팡이(으)로 공격합니다.
// 문제 : 매개변수를 사용해서 전사가 매번 다르게 공격하도록 해주세요.
class Main {
public static void main(String[] args) {
전사 a전사 = new 전사();
a전사.공격("브라이언", "칼");
// 브라이언이(가) 칼(으)로 공격합니다.
a전사.재공격();
// 브라이언이(가) 칼(으)로 공격합니다.
a전사.공격("필립", "창");
// 필립이(가) 창(으)로 공격합니다.
a전사.공격("마크", "지팡이");
// 마크(가) 지팡이(으)로 공격합니다.
a전사.재공격();
// 마크(가) 지팡이(으)로 공격합니다.
a전사.재공격();
// 마크(가) 지팡이(으)로 공격합니다.
}
}
class 전사 {
String 공격자명;
String 무기명;
void 공격(String 공격자명, String 무기명) {
this.공격자명 = 공격자명;
this.무기명 = 무기명;
재공격();
}
void 재공격() {
System.out.printf("%s(이)가 %s(으)로 공격합니다!\n", 공격자명, 무기명);
}
}
// 문제 : 아래 코드가 실행되도록 해주세요.
class Main {
public static void main(String[] args) {
샤오미Tv a샤오미Tv = new 샤오미Tv();
삼성Tv a삼성Tv = new 삼성Tv();
LGTv aLGTv = new LGTv();
a샤오미Tv.켜기();
// 출력 => 샤오미Tv 켜집니다.
a샤오미Tv.끄기();
// 출력 => 샤오미Tv 꺼집니다.
a샤오미Tv.vr켜기();
// 출력 => 샤오미Tv vr켜기!
a삼성Tv.켜기();
// 출력 => 삼성Tv 켜집니다.
a삼성Tv.끄기();
// 출력 => 삼성Tv 꺼집니다.
a삼성Tv.ar켜기();
// 출력 => 삼성Tv ar켜기!
aLGTv.켜기();
// 출력 => LGTv 켜집니다.
aLGTv.끄기();
// 출력 => LGTv 꺼집니다.
aLGTv.게임모드전환();
// 출력 => LGTv 게임모드전환!
}
}
// 이하로 정답 작성부분.
class TV {
void 켜기 () {
}
void 끄기 () {
}
}
class 샤오미Tv extends TV{
void 켜기 () {
System.out.println("샤오미tv 켜집니다.");
}
void 끄기 () {
System.out.println("샤오미tv 꺼집니다.");
}
void vr켜기 () {
System.out.println("샤오미tv vr켜기!");
}
}
class 삼성Tv extends TV{
void 켜기 () {
System.out.println("삼성tv 켜집니다.");
}
void 끄기 () {
System.out.println("삼성tv 꺼집니다.");
}
void ar켜기 () {
System.out.println("삼성tv ar켜기!");
}
}
class LGTv extends TV{
void 켜기 () {
System.out.println("LGtv 켜집니다.");
}
void 끄기 () {
System.out.println("LGtv 꺼집니다.");
}
void 게임모드전환 () {
System.out.println("LGtv 게임모드전환!");
}
}
class의 형변환 예제
// 문제 : 알바를 편하게 하기 위해서 표준Tv 리모콘을 구현해주세요.
class Main {
public static void main(String[] args) {
System.out.println("== 표준Tv 리모콘 들여오기 전 ==");
샤오미Tv a샤오미Tv = new 샤오미Tv();
삼성Tv a삼성Tv = new 삼성Tv();
LGTv aLGTv = new LGTv();
a샤오미Tv.켜기();
// 출력 => 샤오미Tv 켜집니다.
a샤오미Tv.끄기();
// 출력 => 샤오미Tv 꺼집니다.
a샤오미Tv.vr켜기();
// 출력 => 샤오미Tv vr켜기!
a삼성Tv.켜기();
// 출력 => 삼성Tv 켜집니다.
a삼성Tv.끄기();
// 출력 => 삼성Tv 꺼집니다.
a삼성Tv.ar켜기();
// 출력 => 삼성Tv ar켜기!
aLGTv.켜기();
// 출력 => LGTv 켜집니다.
aLGTv.끄기();
// 출력 => LGTv 꺼집니다.
aLGTv.게임모드전환();
// 출력 => LGTv 게임모드전환!
System.out.println("== 표준Tv 리모콘 들여온 후 ==");
// 표준Tv 리모콘을 만든다.
표준Tv a표준Tv;
// 예) double a;
// a표준Tv 변수에 샤오미Tv 객체를 연결한다.
a표준Tv = a샤오미Tv;
// 예) a = 1;
a표준Tv.켜기();
// 출력 : 샤오미TV 켜집니다.
a표준Tv.끄기();
// 출력 : 샤오미TV 꺼집니다.
// a표준Tv 변수에 삼성Tv 객체를 연결한다.
a표준Tv = a삼성Tv;
a표준Tv.켜기();
// 출력 : 삼성TV 켜집니다.
a표준Tv.끄기();
// 출력 : 삼성TV 꺼집니다.
// a표준Tv 변수에 LGTv 객체를 연결한다.
a표준Tv = aLGTv;
a표준Tv.켜기();
// 출력 : LGTV 켜집니다.
a표준Tv.끄기();
// 출력 : LGTV 꺼집니다.
// LGTV만의 고유 기능을 표준Tv 리모콘을 이용해서 호출하기 => 불가능
// (LGTv) => a표준Tv 변수에 있던 표준Tv 리모콘이 LGTv리모콘화 해서 `aLGTv2` 변수에 들어간다.
LGTv aLGTv2 = (LGTv)a표준Tv;
aLGTv2.게임모드전환();
}
}
abstract class 표준Tv {
abstract void 켜기();
abstract void 끄기();
}
class 샤오미Tv extends 표준Tv{
void 켜기() {
System.out.println("샤오미Tv 켜집니다.");
}
void 끄기() {
System.out.println("샤오미Tv 꺼집니다.");
}
void vr켜기() {
System.out.println("샤오미Tv vr켜기!");
}
}
class 삼성Tv extends 표준Tv{
void 켜기() {
System.out.println("삼성Tv 켜집니다.");
}
void 끄기() {
System.out.println("삼성Tv 꺼집니다.");
}
void ar켜기() {
System.out.println("삼성Tv ar켜기!");
}
}
class LGTv extends 표준Tv{
void 켜기() {
System.out.println("LGTv 켜집니다.");
}
void 끄기() {
System.out.println("LGTv 꺼집니다.");
}
void 게임모드전환() {
System.out.println("LGTv 게임모드전환!");
}
}
// 문제 : 정수 i가 가지고 있는 10을 double 형 변수에 넣고 해당 변수의 값을 다시 i에 넣는 코드를 작성해주세요.
class Main {
public static void main(String[] args) {
int i = 10;
double d = i; // 여기선 자동형변환 허용 : 10.0
i = (int)d; // 여기선 자동형변환 불가능 (자료형)을 명시해주면 수동형변환 가능: 10
System.out.println(i);
}
}
// 문제 : 자동차 리모콘이 페라리 객체를 가리키게 한 후 해당 리모콘이 가리키고 있는 객체를 다시 페라리 리모콘으로 가리키게(참조하게) 하는 코드를 작성해주세요.
class Main {
public static void main(String[] args) {
// 수정가능지역 시작
//int i = 1;
//double a = i;
페라리 a페라리 = new 페라리();
자동차 a자동차 = (자동차)a페라리;
a자동차 = a페라리;
//i = (int)a;
페라리 a페라리2 = (페라리)a자동차;
a자동차.달리다();
a자동차.서다();
a페라리2.뚜껑이_열리다();
// 수정가능지역 끝
}
}
class 자동차 {
void 달리다() {}
void 서다() {}
}
class 페라리 extends 자동차 {
void 달리다() {System.out.println("페라리 달린다");}
void 서다() {System.out.println("페라리 선다");}
void 뚜껑이_열리다() {System.out.println("뚜껑이 열린다");}
}