작성 : 2024. 4. 11. 

 

  • 다향성과 관련된 추상 클래스
package polymorphism;

public abstract class AbstractClass {
	// abstract 라고 붙여지면 추상 클래스
	
	// 추상 클래스의 특징
	// abstract 키워드를 선언한다.
	// 추상 메서드는 멤버변수, 메서드, 생성자와는 다름 (추상 메서드는 선언부만 있고 구현부는 없다)
	// 객체생성이 불가
	// 상속만 가능하다.
	// 자식클래스 반드시 추상 메서드를 오버라이딩 해야한다.
	
	// 추상 클래스에 아래의 형식이 다 들어갈 수 있음
	int x;
	int y; 
	
	AbstractClass() {
		
	}
	
	// 접근제한자 생략 가능
	void add() {
		System.out.println (2 + 3);
	}
	
	abstract void play(int pos); // 추상 메서드

}

 

 

  • extends AbstractClass 한 자식 클래스
package polymorphism;

public class AbstractChild extends AbstractClass {

	@Override
	void play(int pos) {
		System.out.println("play");
	}

}

 

  • 상속 시, 하위 객체(자식)는 상위 객체(부모)의 특징(메소드, 변수 등)을 물려받게 된다.
  • 이 때, 상위 객체(부모)의 특징(메소드, 변수 등)을 '새롭게 구현'하는가, '그대로 사용'하는가에 따라서 상속의 형태가 갈리게 된다.

 

  • extends
    • 부모에서 선언/정의를 모두하며, 자식은 오버라이딩 할 필요 없이 부모의 메소드/변수를 그대로 사용할 수 있다.
    • "부모의 특징을 연장해서 사용한다."라고 기억하면 될 듯!
  • implements (interface 구현)
    • 부모 객체는 선언만 하며, 정의는 반드시 자식이 오버라이딩해서 사용한다.
    • "부모의 특징을 도구로 사용해 새로운 특징을 만들어 사용한다."라고 기억하면 될 듯!
  • abstract
    • extends와 interface의 혼합이다.
    • extends를 사용하지만, 몇 개는 추상 메소드로 구현되어 있다.

 

참조 ) 

 

[Java] extends, implements의 차이

상속(Inheritance)이란? 상속에 대해서 다루기 전에 우선, OOP(Object-Oriented Programming, 객체지향프로그래밍)가 무엇인지에 대해 알고 있어야한다. OOP는 다음과 같은 특징을 가지고 있다. 상속과 인터페

wooono.tistory.com

 

 

  • 인터페이스

 

형식 :

interface 인터페이스명 {

변수

메서드 3 가지

}

 

4가지의 요소가 들어감 : 변수, 메서드 (추상 메서드, 기본 메서드(구현부 존재), 클래스 메서드(구현부 존재))

추상 메서드 - 오버라이딩 가능

기본 메서드 - 오버라이딩 가능

클래스 메서드 - 오버라이딩이 안된다!

강사님이 어노테이션 어노테이션 하길래 몰라서 찾아봄..

어노테이션은 다른 프로그램에게 유용한 정보를 제공하기 위해 사용되는 것으로 주석과 같은 의미를 가진다.

인터페이스는 안에 아무 내용이 없어도 된다

다향성만 이용하고 싶다면 추상 클래스 사용하지 않고 인터페이스만 사용 가능

package polymorphism;

public interface Interfaceable {
	// 인터페이스를 만들 때 관습적으로 able 를 붙임
	
	// 인터페이스의 특징
	// 변수 : public static final
	// 메서드 : public abstract void add();
	// 객체생성이 불가
	// 상속만 가능
	// 자식 클래스는 반드시 추상 메서드 오버라이딩
	// public static final, public abstract 생략 가능
	// 인터페이스간 상속이 가능하다
	// 자식클래스에게 다중 상속이 가능하다
	
	public static final int MAX = 0; // 초기화하고 사용
	public abstract void add();
	
	default void dafaultMethod() {
		
	}
	
	static int getHour() {
		return 0; 
	}

}
// 인터페이스를 상속받는 클래스
package polymorphism;

public class ChildImpl implements Interfaceable {
	// 인터페이스를 상속받는 클래스는 Impl 라는 이름을 붙임

	@Override
	public void add() {
		// TODO Auto-generated method stub
		
	}
}

 

 

  • 게임 만들기
// 0411 유닛들의 부모 클래스

package polymorphism;

public abstract class Unit {
	
	// 추상 메서드의 목적은 자식이 반드시 오버라이딩
	// 왜 자식들에게 오버라이딩 할까
	// 자식들이 상황에 맞춰 수정해서 사용할 수 있도록 큰 틀을 주는 것
	int x;
	int y;
	
	// 움직이는 기능 
	// 추상 메서드 만들기
	// abstract 쓸 때는 클래스 이름 앞에도 abstract 붙이기
	abstract void move(int x, int y);
	
	// 멈추는 기능
	void stop() {
		
	}
	
	// 공통된 코드들은 부모클래스에 넣기

}
package polymorphism;
// 유닛
public class Tank extends Unit{
	
	
	// tank 만의 기능
	void changeMode() {
		
	}
	
	@Override
	void move(int x, int y) {
		
	}

}
package polymorphism;
// 유닛
public class Marine extends Unit{
	
	// marine 이라는 캐릭터가 게임에서 할 수 있는 것
	void sticPack() {
		
	}
	
	@Override
	void move(int x, int y) {
		
	}

}
package polymorphism;
// 유닛
public class Dropship extends Unit{
	
	// dropship은 공중에서 움직이는 캐릭터
	// x, y 의 범위가 다름
	
	void load() {
		
	}
	
	@Override
	void move(int x, int y) {
		
	}

}
package polymorphism;

public class Fighter extends Unit implements Fightable{

	@Override
	void move(int x, int y) {
		// TODO Auto-generated method stub

	}
}
//0411
package polymorphism;

public interface Fightable extends Moveable, Attacktable {
	// 인터페이스 간에는 다중 상속 가능

}

 

//0411
package polymorphism;

public interface Attacktable {

}

 

인터페이스와 상속의 차이점

자바에서 인터페이스와 상속은 코드 재사용과 다형성을 실현하는 방법이지만, 몇 가지 주요 차이점이 있습니다.

  • 인터페이스는 클래스가 어떤 행동을 해야하는지 지정하는 반면, 상속은 클래스가 어떻게 동작하는지 지정합니다.
  • 인터페이스는 클래스가 여러 개를 동시에 구현할 수 있지만, 클래스는 상속을 통해 하나의 클래스만 확장할 수 있습니다.
  • 인터페이스는 메서드와 상수만 포함할 수 있지만, 추상 클래스(상속의 한 형태)는 메서드, 변수, 그리고 생성자를 포함할 수 있습니다.
  • 인터페이스는 모든 메서드가 기본적으로 public이며, 모든 변수는 public static final입니다. 반면, 클래스는 다양한 접근 제어자를 가질 수 있습니다.

이러한 차이점들은 상황에 따라 인터페이스와 상속 중 어떤 것을 사용할지 결정하는 데 도움을 줄 수 있습니다.

인터페이스의 용도가 굉장히 많음!

 

  • 인터페이스를 이용한 간단한 게임 만들기
// 조상클래스

package Interfaces;

public class Unit {
	int hitPoint;
	final int MAX_HP;
	
	Unit(int hp) {
		MAX_HP = hp;
	}

}
// 부모 - 지상에서 싸우는 애들

package Interfaces;

public class GroundUnit extends Unit {

	GroundUnit(int hp) {
		super(hp);
	}

}
// 지상에서 싸우는 애 Tank

package Interfaces;

public class Tank extends GroundUnit implements Repairable {

	Tank() {
		super(150);
		hitPoint = MAX_HP;
	}

	@Override
	public String toString() {
		// TODO Auto-generated method stub
		return "Tank";
	}
	

}
// 하늘에서 싸우는 애 Dropship

package Interfaces;

public class Dropship extends AirUnit implements Repairable {

	Dropship() {
		super(125);
		hitPoint = MAX_HP;
	}
	
	@Override
	public String toString() {
		// TODO Auto-generated method stub
		return "Dropship";
	}

}

 

마린 빼고 SCV, 드랍쉽, 탱크는 치료할 수 있게

1. 일단, 묶기 위해 인터페이스 만들기

package Interfaces;

public interface Repairable {

}

 

 

2. SCV, 드랍쉽, 탱크에 implements Repairable 추가

+마린도 치료 기능 추가하기 위해 madic 만들기

package Interfaces;

public class Madic extends GroundUnit implements Repairable2 {

	Madic() {
		super(30);
		hitPoint = MAX_HP;
	}

	void repair(Repairable2 r) {
		Unit u = (Unit) r;

		while ((u.hitPoint) != u.MAX_HP) {
			u.hitPoint++;
		}
		System.out.println(u + "의 수리가 완료!");

	}

	@Override
	public String toString() {
		// TODO Auto-generated method stub
		return "Madic";
	}
}

 

 

이제 위 코드들을 테스트할 메인함수 만들기!

package Interfaces;

public class UnitTest {

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		
		Marine mr = new Marine();
		Tank tk = new Tank();
		SCV scv = new SCV();
		Madic md = new Madic();
		
		// ***** 경로 잘 설계..!
		
		scv.repair(tk);
		// scv.repair(mr); // 안된다!
		md.repair(mr);
		// md.repair(tk); // 안된다!
		
	}

}

 

 

 

 

  • 포함관계를 알아보기 위한 코드
package Interfaces;

//0411
public class Tv {
	// 상속이 아닌 모든 관계를 포함관계라고 한다
	// 포함관계를 알아보기 위한 코드

	// LgSpeak lgSpeak;
	// SmSpeak smSpeak;

	Speakable speak;

	public Tv(Speakable speak) {
		this.speak = speak;
	}

//	public Tv(SmSpeak smSpeak) {
//		this.smSpeak = smSpeak;
//	}

	void speakSound() {
		speak.sound();
	}

}
package Interfaces;

public class LgSpeak implements Speakable {
	public void sound() {
		System.out.println("LgSpeak 소리입니다.");
	}

}
package Interfaces;

public class SmSpeak implements Speakable {
	public void sound() {
		System.out.println("SmSpeak 소리입니다.");
	}

}
package Interfaces;

public class AppleSpeak implements Speakable {

	@Override
	public void sound() {
		System.out.println("AppleSpeak 소리입니다.");
	}

}

 

위 엘지스피커, 삼성스피커, 애플스피커와 같은 스피커들 뿐 아니라 새로 들어오게 될 스피커들까지 처리하기 위해 인터페이스를 생성한다.

package Interfaces;

public interface Speakable {
	//public 은 반드시 연계
	
	public abstract void sound();

}

 

그 후 테스트를 위해 메인함수를 만들어 원하는 값을 출력해본다.

package Interfaces;

public class TvTest {

	public static void main(String[] args) {
		
		LgSpeak lgs = new LgSpeak();
		SmSpeak sms = new SmSpeak();
		AppleSpeak apps = new AppleSpeak();
		
		Tv t = new Tv(apps);
		
		t.speakSound();

	}

}

// 코딩을 할 때는 결합도가 낮도록 프로그래밍해야한다. → 인터페이스가 이 일을 해줌 → 이것이 다형성

→ 사용하는 쪽의 코드 수정을 최소화 할 수 있다.

여러 자식 공통적인 요소를 표현하고 싶은 게 상속

포함은 상속 외의 다!

'2024_UIUX 국비 TIL' 카테고리의 다른 글

UIUX _국비과정 0415  (0) 2024.05.29
UIUX _국비과정 0412 [학생성적관리 시스템 및 첫 조별과제]  (0) 2024.05.29
UIUX _국비과정 0409  (0) 2024.05.29
UIUX _국비과정 0408  (0) 2024.05.29
UIUX _국비과정 0405  (0) 2024.05.29

+ Recent posts