추상클래스 Step09_AbstractClass
- 추상 클래스 : 미완성 상태의 클래스. 상속받은 클래스에서 override하도록 강제할 수 있다.
<Weapon>
package test.mypac;
//미완성된 추상메소드를 멤버로 가지고있는 클래스는 abstract예약어를 붙여서 정의해야 한다.
public abstract class Weapon {
//무기작동을 준비하는 메소드
public void prepare() {
System.out.println("무기 작동을 준비 합니다.");
}
//공격을 하는 메소드의 모양만 정의하고 실제 구현은 하지 않기
//미완성된 추상 메소드를 만들때는 abstract 예약어가 필요하다.
public abstract void attack();
}
<MainClass01>
package test.main;
import test.mypac.MyWeapon;
import test.mypac.Weapon;
/*
* - class 예약어 앞에 abstract 를 명시해서 클래스를 정의한다.
* - 형태만 정의되고 실체 구현은 되지 않는 메소드가 존재할 수 있다.
* - 형태만 정의된 메소드를 만들 때는 abstract 예약어를 뭍여서 메소드를 정의한다.
* - 생성자는 존재하지만, 단독으로 객체 생성은 불가하다.
* - 추상클래스 Type의 id가 필요하다면 추상클래스를 상속받은 자식클래스를 정의해서 객체를 생성한다.
* - 추상클래스를 상속받은 자식클래스는 부모의 추상메소드를 모두 오버라이드(재정의) 해야 한다.
*/
public class MainClass01 {
public static void main(String[] args) {
//추상클래스도 데이터type의 역할을 할 수 있다.
Weapon w1=null;
//Weapon w2=new Weapon(); //추상클래스 단독으로 객체생성 불가
Weapon w2=new MyWeapon();
w2.prepare();
w2.attack();
}
}
public abstract class Weapon { }
- 미완성된 추상메소드를 멤버로 가지고있는 클래스는 abstract 예약어를 붙여서 정의해야 한다.
(미완성인 추상메소드를 가지고 있다면 반드시 클래스에다가도 표시해야 한다.)
- prepare는 완성된 메소드, attack은 미완성된 메소드
public abstract void attack();
- 메소드의 모양만 정의하고 실제 구현은 하지 않기
- 미완성된 추상 메소드를 만들때는 abstract 예약어가 필요하다.
- 보통 메소드를 만들면 클래스의 {} 안에 메소드를 준비하는 것이 일반적이다.
- new Weapon().prepare(); 형태로 사용한다.
- 메소드에 모양만 만들어서 전달만 하고, 구현하지는 않을 수도 있다.
abstract를 붙여서 메소드를 만들고, (){} 하지 않고 ()만 표기한다.
- 추상 클래스도 디폴트 생성자는 존재한다!
- w1.prepare();로 prepare 메소드는 실행할 수 있지만,
w1.attack(); 에는 실행할 코드가 없다.
- 추상클래스로는 new를 할 수 없다. 객체 생성을 할 수 없기 때문에!
→ 클래스 내부의 메소드가 미완성이니 당연히 new 할 수 없음.
- 실제로 해당 클래스를 new 해보면 오류가 발생한다.
- 그러면 new할 수 없는 Weapon 클래스를 생성하는 방법은?
→ 상속을 한 다음에, 상속받은 하위 클래스를 사용해서 new한다.(객체 생성)
- 새 하위클래스를 만든 다음 Weapon 타입으로 객체를 생성한다.
- 단, 자식클래스 MyWeapon 안에서 부모가 구현하지 못한 추상클래스를 구현해야 한다.(override 사용)
상속받은 하위클래스 안에서 불완전한 추상클래스를 완전하게 만들어야한다.(재정의) 선택이 아닌 강제!
<MyWeapon>
package test.mypac;
public class MyWeapon extends Weapon {
@Override
public void attack() {
System.out.println("내 마음대로 공격해요!");
}
}
- Weapon을 부모 클래스로 받는 MyWeapon class 작성
public class MyWeapon extends Weapon { }
- 새 하위클래스를 만들어 상속받으면 오류가 발생한다.
- 오류 발생지점에 마우스를 가져다놓으면 오류를 수정할 수 있는 방안이 자동완성된다.
The type MyWeapon must implement the inherited abstract method Weapon.attack()
1) 부모클래스 Weapon의 미완성 메소드를 override해서 수정하거나
2) MyWeapon도 추상클래스로 만들거나
→ 1)을 선택하면 @override 구문이 자동완성된다.
- 어떤 상황에서 사용하고자 하는지 모르기 때문에 기반 상태만 준비해놓은 것.
개발자가 하고 싶어하는 대상만 정해서 작업할 수 있도록!
추상클래스를 상속받아서 개인의 특별한 클래스를 만들 수 있다.
[ 추상클래스 (Abstract Class) ]
- class 예약어 앞에 abstract 를 명시해서 클래스를 정의한다.
- 형태만 정의되고 실체 구현은 되지 않는 메소드가 존재할 수 있다.
- 형태만 정의된 메소드를 만들 때는 abstract 예약어를 뭍여서 메소드를 정의한다.
- 생성자는 존재하지만, 단독으로 객체 생성은 불가하다.
- 추상클래스 Type의 id가 필요하다면 추상클래스를 상속받은 자식클래스를 정의해서 객체를 생성한다.
- 추상클래스를 상속받은 자식클래스는 부모의 추상메소드를 모두 오버라이드(재정의) 해야 한다.
<MainClass02>
package test.main;
import test.mypac.Gun;
import test.mypac.Weapon;
public class MainClass02 {
//run 했을때 실행의 흐름이 시작되는 특별한 main 메소드
public static void main(String[] args) {
//동일 클래스 안에 있는 static 메소드 호출가능
test("안녕!!");
//직접 클래스를 만들고 객체 생성을 해서 아래의 useWeapon()메소드를 호출해 보세요.
Weapon g1=new Gun();
useWeapon(g1);
}
public static void test(String msg) {
System.out.println(msg);
}
//Weapon type을 인자로 전달받아서 사용하는 static 메소드
public static void useWeapon(Weapon w) {
w.prepare();
w.attack();
}
}
- main 메소드는 특별한 메소드. run을 누르면 실행이 시작되는 도입점 역할을 한다.
- main 메소드는 static method이므로 클래스와 함께 static영역에 올라간다.
- run을 누르면 MainClass2.main(){}; 을 실행해주는 것이다.
- 위의 test 메소드는 사용할 수 없다. static 예약어가 없으므로 static영역에 함께 올라가지 못한다.
- static 메소드만 main과 함께 호출된다. 밑의 test도 static을 붙여주어야 한다.(함께 static영역에 올라가야만 호출 가능)
- test(); 는 앞에 mainClass02.test(){}; 가 생략된 것! 같은 클래스 안이므로.
- test를 전달하는 값이 있는 메소드로 수정. static 메소드를 호출하면서 매개변수를 함께 전달할 수 있다.
<Gun>
package test.mypac;
public class Gun extends Weapon {
@Override
public void attack() {
System.out.println("총으로 공격해요! 빵야~");
}
}
- Weapon클래스를 상속하는 Gun이라는 자식클래스 생성.
Weapon g1=new Gun();
useWeapon(g1);
- 이 클래스를 나중에 만들었음에도 메인메소드 안에 끼워넣으면 함께 잘 기능한다.
- 하지만 Gun 클래스는 타입으로 사용하지도 않고, Gun 클래스에는 메소드도 없다.
오직 객체를 생성하기 위한 매개체에 불과하다.
→ 나중에는 클래스 없이도 객체를 생성해줄 다른방법을 사용할 것!(다음 게시물 참고)
'국비교육(22-23)' 카테고리의 다른 글
17일차(4)/java(19) : Interface (0) | 2022.10.30 |
---|---|
17일차(3)/java(18) : Inner Class, Anonymous Class (1) | 2022.10.30 |
17일차(1)/java(16) : 상속, 다형성, 접근지정자 정리 (0) | 2022.10.28 |
16일차(3)/java(15) : Extends, 접근 지정자 (0) | 2022.10.27 |
16일차(2)/java(14) : Extends, 다형성 (0) | 2022.10.27 |