JAVA/JAVA BASIC

[JAVA] 상속 - 추상 클래스, 인터페이스

아잠만_ 2024. 3. 27. 10:32

추상클래스

abstract 키워드 

정의할 수 없으므로 구현하지 않을 때 사용

(interface는 상수밖에 정의할 수 없기 때문에 중복되는 멤버를 통합해 줄 땐 추상클래스를 사용한다)


public abstract class Animal {
	// 정의하지 않으므로 중괄호X	
    public abstract void cry();
    
	// 추상클래스라도 모든 메소드가 추상일 필요는 없다
	public void test() {
		
	}
}

public abstract class Unit {
	String name;
	int hp;
	
	public abstract void attack();
	
	public abstract void move();
}
//부모클래스가 구현이 되어있지 않을때 반드시 재정의가 필요하다
public class Zealot extends Unit {

	@Override
	public void attack() {
		
	}

	@Override
	public void move() {
		
	}

}
import java.util.Scanner;

public class UnitExample {

	public static void main(String[] args) {
		Scanner sc = new Scanner(System.in);
		System.out.println("1. 마린");
		System.out.println("2. 뮤탈");
		
		// 클래스를 만들지 않고 재정의를 할 수도 있다
		Unit unit = new Unit() {

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

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

	}
}

인터페이스

추상클래스와 유사한 개념이지만 차이점은 interface에서는 메소드를 구현할 수 없다.

상속을 받을 때는 키워드 implements를 사용한다. 인터페이스 끼리는 다중 상속이 가능하다

(내부의 모든 필드는 public static final 상수 형태)


public interface Animal {
	
	public void cry();
	
}
public class Cat implements Animal {

	@Override
	public void cry() {
		System.out.println("야옹");
	}

}

** 직접입력하는 방법도 있지만 생성 시에 interface에 add로 추가하는 방법도 존재한다

public class Dog implements Animal {

	@Override
	public void cry() {
		System.out.println("멍멍");
	}

}
public class AnimalExample {
	public static void main(String[] args) {
		Animal ani = null;
		
		int sel = 1;
		if(sel==1) ani = new Cat();
		if(sel==2) ani = new Dog();
		
		ani.cry();
	}
}

public interface Unit {

	public void attack();
	
	public void move();
}
public class Marine implements Unit {

	@Override
	public void attack() {
		System.out.println("데미지 5를 줍니다.");
		
	}

	@Override
	public void move() {
		System.out.println("걸어 갑니다");
		
	}

}
public class Mutal implements Unit {

	@Override
	public void attack() {
		System.out.println("스플래시 공격");

	}

	@Override
	public void move() {
		System.out.println("날아 갑니다.");
		
	}

}
import java.util.Scanner;

public class UnitExample {

	public static void main(String[] args) {
		Scanner sc = new Scanner(System.in);
		System.out.println("1. 마린");
		System.out.println("2. 뮤탈");
		
		Unit unit = null;
		int sel = 1;
		if (sel == 1) unit = new Marine();
		if (sel == 2) unit = new Mutal();

		while (true) {
			System.out.println("1. 공격, 2. 이동");
			int sel2 = sc.nextInt();
			if (sel2 == 1) unit.attack();
			if (sel2 == 2) unit.move();
		}

	}
}

인터페이스는 설계도와도 같기 때문에

설계도에 세워진 대로 그 값을 넣으면 된다


public class MemberVo {
	private String id;
	private String pass;
	private String name;
	private int age;
	
	public String getId() {
		return id;
	}
	public void setId(String id) {
		this.id = id;
	}
	public String getPass() {
		return pass;
	}
	public void setPass(String pass) {
		this.pass = pass;
	}
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public int getAge() {
		return age;
	}
	public void setAge(int age) {
		this.age = age;
	}
}

private를 하였을땐 getter setter를 작성해야함 ( alt + shift + s)

public interface IMember {
	// 2가지 방법을 사용할 수 있게 미리 설계해둠
//	public void sign(String id, String pass, String name, int age);
	public void sign(MemberVo member);
	
	public boolean login(String id, String pass);
}
public class MemberSeriveImple implements IMember {

	MemberVo[] memList = new MemberVo[100];
	int cur = 0;
	
	@Override
	public void sign(MemberVo member) {
		memList[cur++] = member;
	}

	@Override
	public boolean login(String id, String pass) {
		for(int i=0; i<cur; i++) {
			MemberVo mem = memList[i];
			if(mem.getId().equals(id)&&mem.getPass().equals(pass)) {
				return true;
			}
		}
		return false;
	}

}
public class MemberMain {
	Scanner sc = new Scanner(System.in);

	public static void main(String[] args) {
		MemberMain obj = new MemberMain();
		obj.process();
	}
	
	public void process() {
		System.out.print("ID : ");
		String id = sc.next();
		System.out.print("pass : ");
		String pass = sc.next();
		System.out.print("name : ");
		String name = sc.next();
		System.out.print("age : ");
		int age = sc.nextInt();
		
		MemberVo mem = new MemberVo();
		mem.setId(id);
		mem.setPass(pass);
		mem.setName(name);
		mem.setAge(age);
		
		IMember memService = new MemberSeriveImple();
		memService.sign(mem);
	}
}

 

어떤 데이터를 줄건지 미리 정함 → 인터페이스로 약속

화면 (입력 받아서 넘겨줌) ~ 로직 ~ 데이터

 

final

상수값을 의미 (한번 값을 정하면 그 값을 고정)

상수는 대문자로 표기


public interface Unit {
	public static final int HP = 0;
}