0401 상속 활용

Fifty·2025년 4월 1일

2. JAVA

목록 보기
17/33

예제

예제1

[Mouse 클래스]
멤버함수

  • clickLeft(): void, '왼쪽 클릭'이라고 출력
  • clickRight(): void, '오른쪽 클릭'이라고 출력

↑ 상속

[WheelMouse클래스]
멤버함수

  • scroll(): void, '스크롤합니다.'라고 출력

↑ 상속

[OpticalMouse클래스]
멤버함수

  • clickLeft(): void, @override, '광센서로 왼쪽 클릭'이라고 출력
  • clickRight(): void, @override, '광센서로 오른쪽 클릭'이라고 출력

→ 반복문을 활용해서 clickleft, clickright를 하기

package ex0401;

public class MouseTest {

	public static void main(String[] args) {
		
		Mouse mouse = new Mouse();
		Mouse wmouse = new WheelMouse();
		Mouse omouse = new OpticalMouse();
		
		Mouse[] mouseArr = {mouse, wmouse, omouse};
		for(int i=0; i<mouseArr.length; i++) {
			mouseArr[i].clickLeft();
			mouseArr[i].clickRight();
		}
	}
}

결과

예제2

→ 반복문 활용해서 scroll()하기

		for(int i=0; i<mouses.length; i++) {
			mouses[i].clickLeft();
			mouses[i].clickRight();
			if(mouses[i] instanceof WheelMouse) {
				WheelMouse wm =(WheelMouse)mouses[i];
				wm.scroll();
			}
		}

또는

		for(int i=0; i<mouses.length; i++) {
			mouses[i].clickLeft();
			mouses[i].clickRight();
			if(mouses[i].getClass()==WheelMouse.class) {
				WheelMouse wm =(WheelMouse)mouses[i];
				wm.scroll();
			}	
		}

어떤 클래스(Mouse, WheelMouse, OpticalMouse)의 인스턴스인지 출력

		for(int i=0; i<mouses.length; i++) {
			if(mouses[i] instanceof OpticalMouse)
				System.out.println("OpticalMouse 인스턴스입니다.");
			else if(mouses[i] instanceof WheelMouse)
				System.out.println("WheelMouse 인스턴스입니다.");
			else
				System.out.println("Mouse 인스턴스입니다.");
		}
		
		for(int i=0; i<mouses.length; i++) {
			if(mouses[i].getClass()==OpticalMouse.class)
				System.out.println("OpticalMouse 인스턴스입니다.");
			else if(mouses[i].getClass()==WheelMouse.class)
				System.out.println("WheelMouse 인스턴스입니다.");
			else
				System.out.println("Mouse 인스턴스입니다.");
		}

instanceof나 getClass()를 했을 때,
모든 mouse 인스턴스는 Mouse로부터 상속받았기 때문에
if(mouses[i] instanceof Mouse)를 하면 모두 true가 된다.
*if문은 위에서부터 순서대로 확인

		for(int i=0; i<mouses.length; i++) {
			if(mouses[i] instanceof Mouse)
				System.out.println("Mouse 인스턴스입니다.");
			else if(mouses[i] instanceof WheelMouse)
				System.out.println("WheelMouse 인스턴스입니다.");
			else
				System.out.println("OpticalMouse 인스턴스입니다.");
		}

그래서 작은 범위인 OpticalMouse인지를 먼저 물어봐야한다.
Mouse인스턴스는 OpticalMouse로부터 나온 것이 아니기 때문에 else까지 내려간다.

		for(int i=0; i<mouses.length; i++) {
			if(mouses[i] instanceof OpticalMouse)
				System.out.println("OpticalMouse 인스턴스입니다.");
			else if(mouses[i] instanceof WheelMouse)
				System.out.println("WheelMouse 인스턴스입니다.");
			else
				System.out.println("Mouse 인스턴스입니다.");
		}


예제3

Bus와 Train, BusanTravel 클래스가 아래와 같을 때,
콘솔에 버스or기차를 타고 부산여행을 간 결과로
'부산행 버스or기차에 몸을 싣고...'가 출력되게 하시오.

Bus.java

package ex0401;

public class Bus {
	public void goBus() {
		System.out.println("부산행 버스에 몸을 싣고..");
	}
}

Train.java

package ex0401;

public class Train {
	public void goTrain() {
		System.out.println("부산행 기차에 몸을 싣고..");
	}
}

BusanTravel.java

package ex0401;

public class BusanTravel {

	// 버스타고 가는 메서드
	public void goBusan() {
		
	}
	// 기차타고 가는 메서드
	public void goBusan() {
		
	}
}

BusanTravel부터 빈칸을 채워주고,
BusanTravel.java

package ex0401;

public class BusanTravel {

	// 버스타고 가는 메서드
	public void goBusan(Bus b) {
		b.goBus();
	}
	// 기차타고 가는 메서드
	public void goBusan(Train t) {
		t.goTrain();
	}
}

main에서 해당 함수를 호출해준다.
TravelTest.java

package ex0401;

public class TravelTest {

	public static void main(String[] args) {
		
		BusanTravel bt = new BusanTravel();
		Bus b = new Bus();
        Train t = new Train();
		// 콘솔에 버스를 타고 부산여행을 간 결과로 '부산행 버스에 몸을 싣고...'가 출력되게 하시오.
		bt.goBusan(b);
		// 콘솔에 기차를 타고 부산여행을 간 결과로 '부산행 기차에 몸을 싣고...'가 출력되게 하시오.
		bt.goBusan(t);
		
	}
}

예제4

Bus와 Train은 대중교통이므로 상속으로 통일한다.

Transportation
↑ 상속
버스, 기차

Transportation과 TravelTest가 아래와 같을 때,
부산행 버스 or 기차에 몸을 싣고.. 가 출력되게 하시오.

Transportation.java

package ex0401;

public class Transportation {
	public void go() {
		System.out.println("알아서 갑니다.");
	}
	
	public void goBusan() {
		// 완성하시오.
		go();
	}
}

TravelTest.java

package ex0401;

public class TravelTest {

	public static void main(String[] args) {
		
		Bus bus = new Bus();
        Train train = new Train();
        
        Transportation t = new Transportation();
        t.goBusan(bus);
        t.goBusan(train);
	}
}

Transportation.java

방법1.
t.goBusan에 매개변수가 bus와 train이므로
매개변수로 Transportation을 넣어주고
매개변수가 Bus인지 Train인지에 따라 출력

package ex0401;

public class Transportation {
	public void go() {
		System.out.println("알아서 갑니다.");
	}
	
	public void goBusan(Transportation t) {
		BusanTravel bt = new BusanTravel();
		if(t instanceof Bus) 
			bt.goBusan((Bus)t);
		else if(t instanceof Train) 
			bt.goBusan((Train)t);
		else
			go();
	}
}

방법2.
Transportation의 go()와 Bus(), Train()의 goBus(), goTrain()을 override한다.
override를 하면 상속관계에서 자식의 메소드를 실행하기 때문에
Transportation의 goBusan()이 간결해진다.

Trainsportation.java

package ex0401;

public class Transportation {
	public void go() {
		System.out.println("알아서 갑니다.");
	}
	
	public void goBusan(Transportation t) {
		t.go();
	}
}

Bus.java

package ex0401;

public class Bus extends Transportation{
	@Override
	public void go() {
		System.out.println("부산행 버스에 몸을 싣고..");
	}
}

Train.java

package ex0401;

public class Train extends Transportation{
	@Override
	public void go() {
		System.out.println("부산행 기차에 몸을 싣고..");
	}
}

BusanTravel.java

package ex0401;

public class BusanTravel {

	// 버스타고 가는 메서드
	public void goBusan(Bus b) {
		b.go();
	}
	// 기차타고 가는 메서드
	public void goBusan(Train t) {
		t.go();
	}
}

final

마지막!

아래와 같이 함수에 final 설정을 해주면,
상속받아 override를 하고 있는 클래스에서 에러가 남

	public final void go() {
		System.out.println("알아서 갑니다.");
	}

클래스에 final을 붙이면 상속 자체를 할 수가 없다.

public final class Transportation {
}

abstract

추상! 미완성된 메소드

abstract를 설정해주면 new Transportation을 할 때 에러가 남

public abstract class Transportation {
}

완성되지 않은 메소드 public abstract void go();
추상메소드를 가지고 있는 클래스를 추상클래스라고 한다.

왜 쓰냐? 상속을 위해서
상속은 가능한데 자신의 인스턴스를 만드는 것은 안된다.
인스턴스는 만들고 싶지 앟ㄴ지만

추상클래스를 상속받은 자식클래스는
부모로부터 미완성된 메소드를 상속받았기 때문에
자식은 반드시 미완성된 메소드를 구현해야한다.

Transportation 타입으로 새로운 인스턴스 생성은 불가능 하나,
상속을 받은 Bus와 Train은 Transportation배열로는 존재할 수 있다.

abstract는 상속받는 자식 클래스 간의 약속이다.

BusanTravel.java도 아래처럼 수정이 가능하다.
기존

	// 버스타고 가는 메서드
	public void goBusan(Bus b) {
		b.go();
	}
	// 기차타고 가는 메서드
	public void goBusan(Train t) {
		t.go();
	}

수정

	// 버스/기차타고 가는 메서드
	public void goBusan(Transportation t) {
		t.go();
	}

예제5 / Class연습

Class명 MyIntArray

  1. 멤버변수
    정수배열

  2. 기본생성자
    기본 생성자를 사용해서 멤버변수에 정수 5개를 저장할 수 있는 배열을 할당한다.

  3. getter & setter
    배열의 특정 인덱스 요소를 얻어낼 수 있는 getter: 매개변수(인덱스)
    배열의 특정 인덱스 요소를 저장할 수 있는 setter: 매개변수(인덱스, 저장값)

  4. 멤버함수
    배열에 저장되어 있는 모든 값을 출력

MyIntArray.java

package ex0401;

public class MyIntArray {
	
	// 멤버변수: 정수배열
	private int[] arr;
	
	// 기본생성자를 사용해서 정수5개를 저장할 수 있는 배열 할당
	MyIntArray(){
		this.arr = new int[5];
	}
	
	// 특정 인덱스의 요소를 얻어내는 getter
	public int getter(int index) {
		return arr[index];
	}
	
	// 특정 인덱스의 요소를 저장하는 getter
	public void setter(int index, int data) {
		arr[index]=data;
	}
	
	// 배열에 저장되어 있는 모든 값 출력
	public void printArray() {
		for(int i=0; i<arr.length; i++)
			System.out.print(arr[i]+" ");
	}
}

MyIntArrayTest.java

package ex0401;

public class MyIntArrayTest {

	public static void main(String[] args) {
		
		MyIntArray mia = new MyIntArray();
		
		mia.setter(0, 2);
		mia.setter(1, 4);
		mia.setter(2, 6);
		mia.setter(3, 8);
		mia.setter(4, 10);
		
		System.out.println(mia.getter(3));
		
		mia.printArray();
	}
}

결과

0개의 댓글