abstract
final과 abstract는 약간 반대의 개념
final은 변경의 금지를 의미, abstract는 꼭 ~해라 는 의미.
abstract는 클래스와 메서드에만 사용
abstract를 붙이면 '추상 클래스'가 되고, '추상 메서드'가 된다.
추상 클래스는 객체를 생성할 수가 없다!
추상 메서드는 몸체가 없는 불안정한 메서드. {}가 없다. 메서드 선언만 있음
추상 클래스를 쓰는 목적은 추상 메서드를 쓰기 위해. 둘은 같이 사용.
추상 클래스를 설계할 때 자식 클래스가 반드시 실행 내용을 채우도록 강요하고 싶은 메서드가 있을 때,
해당 메서드를 추상 메서드로 선언한다.-> 즉 추상 메서드는 자식클래스에서 무조건 오버라이딩된다.
따라서 자식 클래스에서 추상 메서드를 오버라이딩하지 않으면 컴파일에러가 난다.
부모클래스의 추상화, 자식클래스에서 구체화.
자식클래스는 super()로 부모클래스의 생성자를 가져온다. 따라서 추상클래스에도 생성자가 있어야 한다.
abstract badcase
부모
package day09.abs.bad;
public class Store {
//부모클래스
public void apple() {System.out.println("자식에서 재정의하세요");}
public void melon() {System.out.println("자식에서 재정의하세요");}
public void orange() {System.out.println("자식에서 재정의하세요");}
}
자식
package day09.abs.bad;
public class SeoulStore extends Store {
//부모님에 있는 3개의 메서드를 반드시 오버라이딩 해야하는데, 깜빡한다면?
public void apple() {
System.out.println("서울의 사과는 500원");
}
public void melon() {
System.out.println("서울의 멜론은 600원");
}
}
main
package day09.abs.bad;
public class MainClass {
public static void main(String[] args) {
SeoulStore s = new SeoulStore();
s.apple();
s.melon();
s.orange();//오버라이딩을 반드시 해야하는데, 하지 않았다면 잘못된 메서드가 실행될 수 있습니다
}
}
서울의 사과는 500원
서울의 멜론은 600원
자식에서 재정의하세요
s.orange는 오버라이딩을 하지 않았기에 오버라이딩된 값이 나오지 않는다. 이처럼 깜빡하고 못했을 경우가 발생할 수 있음.
abstract goodcase
부모
package day09.abs.good;
public abstract class Store {
/*
* 1. 메서드에 abstract를 붙이면 추상메서드가 됩니다( {}가 없는 메서드)
* 2. 추상메서드를 사용하고 싶다면, 추상클래스가 되어야 합니다.
*/
//추상메서드
public abstract void apple();
public abstract void melon();
public abstract void orange();
//멤버변수, 생성자, 일반메서드 전부 사용가능합니다.
//멤버변수
private String name="호식이네";
//생성자
public Store() {
System.out.println("추상클래스 생성자 호출");
}
//일반메서드. getter setter
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
추상클래스에서도 멤버변수, 생성자, 일반메서드를 전부 사용할 수 있다.
자식
package day09.abs.good;
public class SeoulStore extends Store {//추상클래스 상속
public void apple() {
System.out.println("서울지점 사과는 500원");
}
public void melon() {
System.out.println("서울지점 멜론은 600원");
}
public void orange() {
System.out.println("서울지점 오렌지는 700원");
}
}
자식
package day09.abs.good;
public class BusanStore extends Store{
@Override
public void apple() {
System.out.println("부산싸과 500원");
}
@Override
public void melon() {
System.out.println("부산멜론 600원");
}
@Override
public void orange() {
System.out.println("부산오렌지 700원;");
}
}
main
package day09.abs.good;
public class MainClass {
public static void main(String[] args) {
//1. 추상클래스는 객체 생성이 안됩니다.
// 반두시 자식으로 구체화 됩니다.
//Store s = new Store(); 불가능
Store s = new SeoulStore();//클래스 추상화.
//자식으로 생성해서 부모로 받아도 결과가 바뀌지 않음. 왜? Store의 기능을 사용할 수 있지만 오버라이딩된 자식의 메서드가 먼저 나오기 때문
s.apple();
s.melon();
s.orange();
System.out.println(s.getName());//상속받은 메서드
Store s1 = new BusanStore();
s1.apple();
s1.melon();
s1.orange();
System.out.println(s.getName());
}
}
추상클래스 생성자 호출
서울지점 사과는 500원
서울지점 멜론은 600원
서울지점 오렌지는 700원
호식이네
추상클래스 생성자 호출
부산싸과 500원
부산멜론 600원
부산오렌지 700원;
호식이네
실제로 abstract가 많지는 않음.
사용자 클래스를 정의할 때 굳이 abstract클래스로 설계한 필요도 없음
하지만, 자바 내부의 많은 클래스는 abstract클래스로 정의되어있음
또한, 자식클래스로 생성해서 부모(추상)클래스에 저장해서 사용가능하다는 점에 익숙해져야한다!
'JAVA' 카테고리의 다른 글
221014 abstract 실습 유닛 (0) | 2022.10.14 |
---|---|
221013 abstract 실습 원과 사각형 넓이 구하기 (0) | 2022.10.13 |
221013 final키워드와 상수 (0) | 2022.10.13 |
221013 Singleton과 static (0) | 2022.10.13 |
221013 static 실습 (0) | 2022.10.13 |