[Java] 추상(Abstract) 클래스/메서드

2022. 10. 5. 15:00Dev.Program/Java & Spring

728x90

======== JAVA0316

< (public) static final 상수 >

  • 주로 특정 변수 값을 지정하기 위해 클래스 내에 상수 제공
    • ⇒ 이 때, 값 변경이 불가능하고 클래스명만으로 접근하도록 static final 사용

======== Ex.java 만들기

p.270

  • 두 차는 종류로 보면 같은 종류! 그랜져/파란색
  • 근데 자바는 ‘두 차는 다르다’로 인식한다.
  • 자바는 대소문자/한글영문 등 전부 구분하기 때문!

 

> 그럼 같은 차 종류를 구분해야할 땐 어떻게 해야할까?

  • 이런 식으로 멤버변수 값을 저장하는 변수(상수)를 선언 및 초기화 해준다.

그럼 main(){} 내에서 이렇게 가져오기만 하면 됨(값을 안에 저장되어 있기 때문)

 

> 그런데 이런식으로 하면 값을 변경할 수 있다! 값을 변경하지 못하게 하려면?

  • private 를 붙이면 될 거라 생각하겠지만 private 는 붙이면 안됨
  • (위에 빨간 밑줄 뜨는 거 보임 - 오류!)

  • 그럴 땐 final을 사용! 변수 앞에 final을 붙이면 상수이므로 값 변경 불가

 

> 보통 (public) static final은 세트로 따라 다닌다!

  • static을 붙이면 인스턴스끼리 값 공유 / 어디서든 부를 수 있음

  • 위에서 부를 땐 클래스명.** 로 호출(노란 밑줄 없어짐)

 

  • String 타입이던 gearType을 int형으로 바꾸기
  • 원하는 건 String(AUTO/MANUAL)인데 이렇게 int 설정 되는 경우가 있다.
    • ⇒ 그래도 상관 없음! 왜냐하면 1: AUTO / 2:MANUAL 이런식으로만 설정하면 됨
  • 이렇게 설정해두고 위에서 부를 때 클래스명.**으로만 호출하면 된다!

# tip. 잘 모를땐 무조건 클래스명. 찍어보기! 그럼 쭈욱 나온다! 선택만 하면 됨.

⇒ 그래서 실무에선 직관적으로 파악할 수 있도록 이름을 잘 설정하는게 중요

 

======== Ex2.java

p.272 코드 그대로 따라치기

public class Ex2 {

	public static void main(String[] args) {
		Vehicle[] vehicles = {new DieselSUV(), new ElectricCar()};
		for(Vehicle v : vehicles) {
			v.reportPosition();
			v.addFuel();
		}
	}
}

class Vehicle {
	private int curX, curY;
	public void reportPosition() {
		System.out.printf("현재 위치 : (%d, %d)%n", curX, curY);
	}
	public void addFuel() {
		System.out.println("모든 운송 수단은 연료가 필요");
	} ⇒ 안쓰는 부분
}

class DieselSUV extends Vehicle {
	@Override
	public void addFuel() {
		System.out.println("주유소에서 급유");
	}
}

class ElectricCar extends Vehicle {
	@Override
	public void addFuel() {
		System.out.println("급속 충전");
	}
}



======== Ex3.java 만들기

p.275

< 추상 메서드(Abstract Method)>

  • 메서드 구현부(Body)가 없는 메서드 = 실행할 코드(동작)가 없는 메서드
    • ⇒ 메서드 구현부{} 대신 세미콜론(;)으로 끝냄
  • 메서드 선언부 리턴타입 앞에 abstract 키워드 명시
  • 호출할 수 없는 메서드이므로 추상메서드가 포함된 클래스는 반드시 추상클래스로 정의해야한다!

< 기본 문법 >

[접근제한자] abstract 리턴타입 메서드명([파라미터...]);
 

 

< 추상 클래스(Abstract Class) >

  • 인스턴스를 생성할 수 없는 클래스(new 사용 불가) ⇒ 나중에는 배움(지금은 못해~)
  • 클래스 내에 추상메서드가 하나라도 존재할 경우 반드시 추상클래스로 선언
  • 추상메서드는 물론 일반메서드도 가질 수 있으며, 멤버변수와 상수 모두 사용 가능
    • ⇒ 즉, 모든 추상클래스가 추상메서드를 포함해야하는 것은 아니다!
  • 추상메서드가 포함된 클래스(추상클래스)를 상속받는 서브클래스는 반드시 추상메서드를 구현(implements)해야한다. = 오버라이딩과 방법 동일
    • ⇒ 궁극적인 목적 : 서브클래스에서 메서드 구현을 강제하기 위함
    • ⇒ 즉, 서브클래스에서 추상메서드를 구현하지 않으면 컴파일 에러 발생 = 상속 불가
  • 추상클래스를 상속받아 추상메서드를 구현한 서브클래스를 사용해야한다.

< 기본 문법 >

[접근제한자] abstract class 클래스명 {
 	// 멤버변수, 상수
  	// 일반메서드, 추상메서드
}

 

  • 오류 없음

  • 여기까지는 아무 문제 없음
  • 구현부(바디) 없이 선언부만 있음(오류)

  • 오류창 확인 : 바디 부분이 없다

  • 메서드에 abstract를 적어주니까 오류창 달라짐!
  • abstract class(추상클래스) 안에서만 abstract method(추상메서드)를 만들 수 있다.

  • 오류창 확인 : 추상메서드를 가지고 있기 때문에 abstract class(추상클래스) 여야 함

  • 추상클래스를 상속받았는데 추상메서드를 구현하지 않았다(오류)

  • 오류창 확인
  • 추상클래스를 상속받은 서브클래스는 슈퍼클래스인 추상클래스가 포함하는 추상메서드를 반드시 구현(implement) 해야한다 ⇒ 오버라이딩과 동일함

  • 오버라이딩 단축키 눌러보면 체크가 자동으로 되어있다(필수라서!)

  • 추상메서드를 구현(오버라이딩)하니까 오류 다 사라짐!

 

< Ex3.java - main() 메서드 >

  • 이걸로 인스턴스 생성 불가 (우리 평소에 하던대로는 인스턴스 생성 불가!)
  • 오류창 확인 : 추상클래스는 인스턴스 생성이 불가능하다.

  • 추상클래스를 상속받아 추상메서드를 구현한 서브클래스를 사용해야한다.

 

======== Test3.java 만들기

Ex2.java에서 Vehicle class 복사해오기 → Vehicle4로 이름 바꾸기

  • 바디를 정의할 수 없다(오류창 그냥 확인만 하기)

  • 문제 ) DieselSUV4 와 ElectricCar4 클래스 정의 - 추상클래스 Vehicle4 클래스를 상속
  • A : Abstract

  • 답!

  • 오버라이딩 단축키 써도 되지만 이렇게 오류 난 부분 눌러서 Add 눌러줘도 됨!

 

p.273/275/276

======== Ex4.java 만들기

  • 추상클래스 만들기

  • 상속받은 추상메서드를 구현하지 않을 경우 앞에 abstract 붙이면 오류 사라짐
  • 그치만 이 클래스 역시 메서드 사용은 불가!

 

> 최종적으로 서브클래스 중 누군가가 추상메서드를 구현해야 사용 가능하다!

  • 최종!

  • 추상클래스를 상속받은 서브클래스는 반드시 추상메서드를 구현해야하지만 만약, 추상메서드 구현을 회피해야할 경우 자신도 추상클래스로 선언하면 된다.
  • (자신도 추상메서드를 포함하게 되므로 추상클래스가 되어야함)
    • ⇒ 단, 서브클래스 중 누군가는 반드시 추상메서드를 구현해야만 사용 가능하다!



======== Test4.java 만들기

문제 )

Shape 클래스 정의

- draw() 메서드 정의 ⇒ 파라미터X, 리턴값X, 추상메서드로 정의

 

Circle, Rectangle, Triangle 클래스 정의 ⇒ Shape 클래스 상속

- draw() 메서드 = "원 그리기!", "사각형 그리기!", "삼각형 그리기!" 구현

  • 푼 답!

 

>

상속 관계에서 다형성 활용이 가능하므로

레퍼런스 타입으로 사용 가능한 추상클래스도 다형성 활용이 가능하다!

  • 추상클래스를 사용하는 이유 : 특정 메서드에 대한 강제성 부여
  • 나중에 배울 interface : 강제성의 끝판!!

 

------------ 여기서부턴 복습~

  • 오버라이딩??
  • 슈퍼클래스로부터 상속받은 메서드를 서브클래스에서 재정의한 것
  • 슈퍼클래스가 정의한 메서드를 그대로 사용하기 어렵기 때문(기능 부족 등)
    • ⇒ 필요성
  • 조상의 메서드와 이름이 같아야한다.
  • 매개변수의 수와 타입이 모두 같아야 한다.
  • 접근 제어자는 조상의 메서드보다 같거나 넓은 범위로만 변경할 수 있다.



728x90