추상화

Mia Lee·2021년 12월 29일
0

JAVA

목록 보기
80/98
package ex_abstract;

public class Ex1 {

	public static void main(String[] args) {

		/*
		 * 추상클래스와 추상메서드
		 * 1. 추상메서드
		 *   < 추상메서드 정의 기본 문법 >
		 *   [접근제한자] abstract 리턴타입 메서드명([매개변수...]);
		 *   
		 * 2. 추상클래스
		 *   ex) 용도
		 *   - 공통된 필드와 메서드를 통일할 목적
		 *   - 실체 클래스 구현 시 시간 절약
		 *   - 규격에 맞는 실체클래스 구현
		 *   
		 *   < 추상클래스 정의 기본 문법 >
		 *   [public] abstract class 클래스명 {}
		 *   
		 *   
		 */
		
//		Shape s = new Shape(); // 에러 발생! 추상클래스는 인스턴스 생성이 불가!
		
		Shape c = new Circle();
		c.draw();
		
	}

}

// 추상클래스와 추상메서드를 사용하여 강제성을 부여하는 방법
// 1. 추상메서드 draw()를 갖는 추상클래스 Shape 정의
abstract class Shape {
	
//	public abstract void draw() {} // 추상메서드는 바디를 가질 수 없다!
	public abstract void draw(); // 반드시 세미콜론으로 끝남
	
}

// 2. 추상클래스 Shape를 상속받는 서브클래스 Circle 정의
// => 추상메서드가 존재하는 경우 서브클래스에서 반드시 추상메서드를 구현(implements)해야한다!
// 구현(implements)과 오버라이딩(Overriding)은 동일한 기능이지만 메서드 바디{}를 구현하는데 목적이
// 있기 때문에 다른 용어로 표현함
class Circle extends Shape {

	@Override
	public void draw() { // Shape 클래스의 draw() 메서드를 상속받아 구현!(Overriding)
		System.out.println("추상클래스로부터 상속받은 추상메서드 오버라이딩!");
		System.out.println("원 그리기!");
		
	}
	
}

class Circle2 extends Circle {}

// Shape 클래스를 상속받는 Rectangle 클래스 정의
class Rectangle extends Shape {
	// 추상메서드 오버라이딩에 대한 강제성이 부여되므로
	// 개발자가 실수로 빠트릴 위험이 없어짐!
	public void draw() {
		System.out.println("사각형 그리기!");
		
	}
	
}

// ==========================================================================
// 강제성을 부여하지 않고 클래스를 정의하게 될 경우 발생하는 문제점!
// 도형 클래스 정의
//class Shape {
//	
//	public void draw() {
//		System.out.println("도형 그리기!");
//		
//	}
//	
//}
//
//// 원(Circle) 클래스 정의 - Shape 상속
//class Circle extends Shape {
//	
//	// Shape 클래스를 상속받는 Circle 클래스는 draw() 메서드를 갖게 되지만
//	// draw() 메서드를 오버라이딩 하지 않고 다른 메서드를 정의하여
//	// 원을 그려도 부모(Shape) 입장에서는 강제할 방법이 없다!
//	public void circleDraw() {
//		System.out.println("원 그리기!");
//		
//	}
//	
//}
//
//// 사각형(Rectangle) 클래스 정의 - Shape 상속
//class Rectangle extends Shape {
//	
//	// Shape 클래스를 상속받는 Rectangle 클래스도 draw() 메서드를 갖게 되지만
//	// 실수로 인해 draw() 메서드를 오버라이딩을 하지 않았더라도 부모(Shpae) 입장에서는
//	// 강제할 방법이 없다!
//	
//}


















package ex_abstract;

public class Ex2 {

	public static void main(String[] args) {

		SubClass sc = new SubClass();
		// 접근 가능한 메서드 : 3개
		// 상속받은 일반메서드
		sc.normalMethod();
		// MiddleClass에서 구현한 추상메서드
		sc.abstractMethod1();
		// SubClass에서 구현한 추상메서드
		sc.abstractMethod2();
		
		// 추상클래스로 인스턴스 생성 불가
//		AbstractClass ac = new AbstractClass();
//		MiddleClass mc = new MiddleClass();
		
		// 변수 타입으로 사용되어 업캐스팅 활용은 가능
		MiddleClass mc = sc;
		// 참조변수 mc에서 접근 가능한 메서드 : 3개
		mc.normalMethod(); // 상속받은 일반메서드
		mc.abstractMethod1(); // MiddleClass에서 구현한 추상메서드
		mc.abstractMethod2(); // SubClass에서 구현한 추상메서드
		
		AbstractClass ac = sc;
		ac.normalMethod();
		ac.abstractMethod1();
		ac.abstractMethod2();
		
	}

}

// 추상클래스
abstract class AbstractClass {
	// 일반 멤버변수
	String var;
	
	// 생성자
	public AbstractClass() {}
	
	// 일반 메서드
	public void normalMethod() {
		System.out.println("추상클래스의 일반 메서드!");
		
	}
	
	// 추상 메서드
	// => 현재 클래스를 반드시 추상클래스로 선언!
	public abstract void abstractMethod1();
	public abstract void abstractMethod2();
	
}

// 추상클래스 AbstractClass를 상속받는 MiddleClass 정의
// => 2개의 추상메서드 중 하나의 메서드만 오버라이딩(abstractMethod1())
abstract class MiddleClass extends AbstractClass {
	// 모든 추상메서드를 오버라이딩 하지 않고, 일부만 구현할 경우
	// 여전히 추상메서드를 포함하게 되므로 일반클래스로 정의할 수 없다!
	// => 추상메서드를 모두 오버라이딩 하거나, 현재클래스를 추상클래스로 선언
	@Override
	public void abstractMethod1() {
		System.out.println("MiddleClass에서 구현한 추상메서드 abstractMethod1()");
		
	}
	
}

// MiddleClass를 상속받는 SubClass 정의
// => MiddleClass에서 구현되지 않은 abstractMethod2() 메서드에 대한 구현 책임이 발생함!
//    => 남은 추상메서드에 대한 구현 실행!(오버라이딩 필수)
class SubClass extends MiddleClass {

	@Override
	public void abstractMethod2() {
		System.out.println("SubClass에서 구현한 추상메서드 abstractMethod2()");
		
	}
	
}











0개의 댓글