11. 클래스들의 관계
현실 세계에 존재하는 객체들의 독자적으로 존재하거나 사용되지 않고 일반작으로 여러 객체들 간에 특정 관계를 맺으면서 존재하게 된다.
종류
is a 관계 : 대학생 is a 학생, 중학생 is a 학생, 초등학생 is a 학생
has a 관계 : 자동차 has a 엔진, 자동차 has a 바퀴, 자동차 has a 라디오
상속
is a 관계가 성립되는 클래스들간의 관계
상속을 자바 코드에서는 extends 키워드로 표현한다.
형식
public class 자식클래스명 extends 부모클래스명 { }
상속과 생성자
생성자는 상속되지 않는다.
클래스를 객체 생성할 때에는 자동으로 부모 클래스를 먼저 객체 생성 후에 자신의 클래스가 생성된다.
부모 클래스의 객체가 생성되면 부모 클래스의 기본 생성자가 자동으로 호출된다. 기본 생성자가 존재하지 않는 경우에는 에러가 발생된다.
명시적으로 super 키워드를 이용해서 기본 생성자 또는 인자가 있는 생성자도 호출할 수 있다.
super 키워드
this는 메모리에 올라간 자신의 인스턴스를 의미하고 super는 부모의 인스턴스를 의미한다. 상속관계의 하위클래스에서 상위클래스의 구성 요소를 명시적으로 호출할 때 사용한다.
일반적으로 2가지 경우에 사용된다.
부모 클래스의 멤버와 자식클래스의 멤버가 이름이 동일한 경우
자식 클래스에서 명시적으로 부모 생성자를 호출하는 경우
접근 지정자
접근지정자 |
같은 클래스 |
같은 패키지 |
상속관계 |
다른 패키지 |
public |
가능 |
가능 |
가능 |
가능 |
protected |
가능 |
가능 |
가능 |
불가능 |
(friendly) |
가능 |
가능 |
불가능 |
불가능 |
private |
가능 |
불가능 |
불가능 |
불가능 |
메소드 오버라이딩
상속 관계시 부모 클래스의 메소드를 하위 클래스에서는 선언 없이 사용 가능하다. 이때 하위 클래스에서 부모 클래스의 메소드를 수정해서 사용할 수도 있는데 이런 형태의 메소드를 오버라이딩 메소드라고 한다.
메소드 오버라이딩 규칙
상속이 전제되어야 한다.
메소드 이름이 반드시 동일해야 된다.
메소드 리턴타입이 반드시 동일해야 된다.
메소드 인자 리스트가 반드시 동일해야 된다.
접근 지정자는 확대만 가능하다.
예외 클래스는 축소만 가능하다.
static, final, private 지정자를 가진 메소드는 오버라이딩이 불가능하다.
상속 예제]
class Employee { String name; int salary;
public String getEmployee() { return name + " " + salary; }
public Employee() { }
public Employee(String name, int salary) { this.name = name; this.salary = salary; } }
class Manager extends Employee { String depart;
public String getManager() { return name + " " + salary + " " + depart; }
public Manager(String name, int salary, String depart) { this.name = name; this.salary = salary; this.depart = depart; } } public class Ex01 {
public static void main(String[] args) { Employee emp = new Employee("홍길동", 2000); Manager man = new Manager("이순신", 4000, "개발"); System.out.println(emp.getEmployee()); System.out.println(man.getManager()); System.out.println(man.getEmployee()); } } |
실행 결과] 홍길동 2000 이순신 4000 개발 이순신 4000 |
[상속, super, 다형성과 오버라이딩]
1. Shape 클래스는 부모 클래스이고 Rectangle, Triangle, Circle등은 자식클래스이다. 아래의 그림을 보고 각각의 클래스를 작성하고 부모 클래스인 Shape를 상속받아 출력 예와 같이 출력하시오.
( 단 클래스의 필드값은 출력예와 같이 대입한다.)
출력 예]
도형 : 사각형
도형 : 삼각형
도형 : 원형
2. 이 문제는 메소드 오버라이딩으로 부모 클래스와 자식 클래스의 메소드의 이름이 동일하다. 아래의 그림을 보고 각각의 클래스를 작성하고 부모 클래스인 Shape을 상속 받아 각각의 도형의 면적을 출력한다.
입력 예] | 출력 예] |
사각형 가로 : 4 세로 : 5 |
도형 : 사각형 면적 : 20.0 |
입력 예] | 출력 예] |
원형 반지름 : 5 |
도형 : 원형 면적 : 78.5 |
3. 아래의 그림을 보고 클래스를 작성하시오.
① Insect클래스를 자료형으로 받는 인스턴스 변수를 생성하여 출력예와 같이 잠자리에 대해서 출력하시오.
② 자식 클래스인 Ant 클래스를 자료형 받는 인스턴스 변수를 생성하여 출력예와 같이 개미에 대해서 출력 하시오.
4. 아래 그림을 보고 클래스를 작성하시오. (단 Manager 클래스에서 super키워드를 사용하여 메소드를 작성)
클래스를 생성하고 main함수에서 아래와 같이 입력한다.
Employee test1 = new Employee("홍길동", "도사", "123-1234");
test1.view();
System.out.println();
Manager test2 = new Manager("일지매", "무술생도", "555-5555", "킬러");
test1.view();
출력 예]
홍길동 | 도사 | 123-1234
일지매 | 무술생도 | 555-5555 | 킬러
5. 아래 그림을 보고 클래스를 작성하시오.
클래스를 생성하고 main함수에서 아래와 같이 입력한다.
Programmer p1 = new Programmer("홍길동", "12346", 3);
p1.gotoOffice();
p1.dispGrade();
p1.startJob();
p1.gotoHome();
System.out.println();
Designer d1 = new Designer("일지매", "23256", "일러스트레이터");
d1.gotoOffice();
d1.dispMajorTech();
d1.startJob();
출력 예]
홍길동님 출근하였습니다...
홍길동 님의 기술자 등급은 3 입니다.
홍길동 님이 S/W개발업무를 시작합니다.
홍길동님 퇴근하였습니다...
일지매님 출근하였습니다...
일지매 님의 주 사용기술은 일러스트레이터 입니다.
일지매 님이 디자인 업무를 시작 합니다.
6. 아래 소스코드를 작성하여 실행한 다음 결과 값을 “출력 값”에 작성하시오.
instanceof 연산자란 무엇일까요?
참조변수가 참조하고 있는 인스턴스의 실제 타입을 알아보기 위한 연산자이다. 주로 조건문에 사용되며, instanceof의 왼쪽에는 참조변수를 오른쪽에는 타입(클래스명)이 피연산자로 위치한다. 그리고 연산의 결과로 boolean값인 true, false 중의 하나를 반환 합니다.
소스 코드]
class Car
{
String color;
int door;
void drive() { //운전하는 기능
System.out.println("빠르게 달린다.");
}
void stop() { // 멈추는 기능
System.out.println("정지!!!");
}
}
class FireEngine extends Car { // 소방차
void water() { // 물 뿌리는 기능
System.out.println("물 발사 ~~~ ");
}
}
class Ambulance extends Car { // 앰뷸런스
void siren() { // 사이렌을 울리는 기능
System.out.println("삐뽀 삐뽀");
}
}
public class Ex02 {
public static void main(String[] args) {
FireEngine f = new FireEngine();
Ambulance a = new Ambulance();
Ex02 test = new Ex02();
test.doWork(f);
test.doWork(a);
}
public void doWork(Car c) {
if (c instanceof FireEngine) {
FireEngine f = (FireEngine)c;
f.water();
}
else if (c instanceof Ambulance)
{
Ambulance a = (Ambulance)c;
a.siren();
}
}
}
출력 값]
7. 추상 클래스로 만들고 값을 입력 받아 출력 예와 같이 출력 하시오.
실행 방법]
Shape ref = null;
ref= new Rectangle(g, s);
ref.area();
ref.printarea();
입력 예] | 출력 예] |
사각형 가로 : 4 세로 : 5 |
도형 : 사각형 면적 : 20.0 |
입력 예] | 출력 예] |
원형 반지름 : 5 |
도형 : 원형 면적 : 78.5 |
8. 추상 클래스를 이용하여 더하기, 빼기, 곱하기, 나누기등 추상 메소드를 만들고 서브 클래스를 만들어 각각의 추상 메소드를 처리할 수 있게 코딩한다. 그리고 메인 함수에서 입력 값을 받아 처리하는 프로그램을 작성하시오.( [클래스 선언, 멤버변수, 메소드 작성] 9번 문제 참조하여 작성 )
추상 메소드
abstract void Plus();, abstract void Minus();, abstract void Multiply();, abstract void Division();
입력 예]
두 개의 숫자를 입력 : 10 2
사칙연산 중 하나를 입력 : /
출력 예]
10.0 / 2.0 = 5.0
9. 추상 클래스를 작성하고 abstract void ect()와 abstract void moving() 메소드를 작성하여 서브 클래스를 이용하여 아래의 출력 예와 같이 출력하도록 클래스를 작성하이오.
출력 예]
진독개는 사료를 먹는다.
진독개는 주인 집으로 간다.
고양이는 물고기를 먹는다.
고양이는 공원에 간다.
쥐는 치즈를 먹는다.
쥐는 쥐구멍으로 들어 간다.
10. 위 8번 문제의 추상 클래스부분을 수정하여 인터페이스로 만들어 사칙연산을 수행하는 프로그램을 작성하시오.
다음 소스 코드는 참조용으로 실행해 보고 위 문제를 풀어보시오.
소스 코드]
package dun.com;
interface a {
int plus(int a, int b);
}
interface b {
int minus(int a, int b);
}
class Result implements a, b {
int su = 100;
void show() {
System.out.println("현재 숫자 : " + su);
}
public int plus(int a, int b) {
return a+b;
}
public int minus(int a, int b) {
return a-b;
}
}
public class Ex10 {
public static void main(String[] args) {
Result t = new Result();
t.show();
System.out.println("2 + 3 = : " + t.plus(2, 3));
System.out.println("5 + 3 = : " + t.minus(5, 3));
}
}
실행 결과]
현재 숫자 : 100
2 + 3 = : 5
5 + 3 = : 2
입력 예]
두 개의 숫자를 입력 : 10 2
사칙연산 중 하나를 입력 : /
출력 예]
10.0 / 2.0 = 5.0
11. 위 7번 문제의 추상 클래스를 수정하여 인터페이스로 작성하고 도형의 면적을 출력하는 프로그램을 작성하시오.
입력 예] 출력 예]
사각형 사각형의 면적 : 20.0
가로 : 4
세로 : 5
12. 위 9번 문제의 추상 클래스를 수정하여 인터페이스로 작성하고 출력 예와 같이 출력되도록 프로그램을 작성하시오.
출력 예]
진독개는 사료를 먹는다.
진독개는 주인 집으로 간다.
고양이는 물고기를 먹는다.
고양이는 공원에 간다.
쥐는 치즈를 먹는다.
쥐는 쥐구멍으로 들어 간다.