반응형
static을 쓰는 경우 클래스명(참조변수)로 메서드를 호출할 수 있다
/*
* 추상메서드(Abstract Method)
* - 메서드 바디(= 구현부, {})가 존재하지 않는 메서드 = 미완성 메서드
* => 실행 코드가 없으므로 실행(호출)될 수 없는 메서드
* - 메서드 선언부 접근제한자 뒤에 abstract 키워드를 붙여서 선언
* => 바디가 없으므로 메서드 마지막을 세미콜론(;)으로 마무리
* - 메서드 실행 코드(바디)가 없으므로 외부에서 호출되면 안되는 메서드
*
* < 추상메서드 정의 기본 문법 >
* [접근제한자] abstract 리턴타입 메서드명([매개변수...]);
* -------------------------------------------------------------
* 추상클래스(Abstract Class)
* - 인스턴스를 생성할 수 없는 미완성 클래스
* => 내부에 추상메서드를 가지고 있을 경우
* 추상메서드가 호출되면 안되므로 인스턴스 생성을 못하게 차단함
* - class 키워드 앞에 abstract 키워드를 붙여서 정의
* - 추상메서드 뿐만 아니라 일반메서드, 멤버변수, 생성자를 가질 수 있음
* => 추상메서드가 없는 메서드도 추상클래스로 정의할 수 있음
* - 인스턴스는 생성할 수 없지만, 상속을 통한 슈퍼클래스로 사용하거나
* 다형성 활용을 위한 참조변수 타입으로 사용 가능함
* => 추상메서드를 포함하는 추상클래스를 상속받는 서브클래스에서는
* 반드시 오버라이딩을 통해 추상메서드 바디{} 를 구현해야한다!
* 즉, 추상메서드 오버라이딩을 강제할 수 있다!
* (what 에 대한 강제, how 는 서브클래스에게 위임)
* - 추상메서드에 대한 구현을 강제함으로써 코드의 강제성 및 통일성 향상
*
* < 추상클래스 정의 기본 문법 >
* [접근제한자] abstract class 클래스명 {
* // 멤버변수
* // 생성자
* // 일반메서드
* // 추상메서드
* }
*
*/
public class Ex {
public static void main(String[] args) {
// 추상클래스인 AbstractClass 인스턴스 생성
// AbstractClass ac = new AbstractClass();// 컴파일 에러 발생!, 추상클래스는 인스턴스 생성불가
// 추상클래스를 상속받은 서브클래스 인스턴스 생성
SubClass sc = new SubClass();
sc.normalMethod();
sc.abstractMethod();
sc.subClassMethod();
// 추상클래스를 참조변수 타입으로 활용 가능 = 업캐스팅을 통한 다형성
AbstractClass ac = new SubClass(); //업캐스팅
ac.normalMethod(); // 공통(상속된) 메서드
ac.abstractMethod(); // 공통(상속된) 메서드
// ac.subClassMethod(); //참조영역의 축소로 보이지 않는 메서드
System.out.println("==========================");
// Flyer 클래스를 상속받은 SuperMan, Bird, AirPlane 인스턴스 생성
SuperMan sm = new SuperMan();
sm.takeOff();
sm.fly();
sm.land();
Bird b = new Bird();
b.takeOff();
b.fly();
b.land();
AirPlane ap = new AirPlane();
ap.takeOff();
ap.fly();
ap.land();
System.out.println("-----------------------------");
// SuperMan, Bird, Airplane -> Flyer 타입 업캐스팅하여 다형성 활용
Flyer fl = new SuperMan();
fl.takeOff();
fl.fly();
fl.land();
fl = new Bird();
fl.takeOff();
fl.fly();
fl.land();
fl = new AirPlane();
fl.takeOff();
fl.fly();
fl.land();
}
}
abstract class AbstractClass {
// public abstract void abstractMethod() {} //오류발생
// => 추상메서드 정의 시 반드시 중괄호를 제거해야함(Abstract methods do not specify a body)
public abstract void abstractMethod();
// 추상메서드를 갖는 클래스는 반드시 추상클래스로 선언되어야 한다!
// => class 키워드 앞에 abstract 키워드 필수!
//추상클래스가 추가로 가질 수 있는 것
public void normalMethod() {} //일반 메서드
public AbstractClass() {} //생성자
String member; //인스턴스 변수
}
//추상클래스 AbstractClass 를 상속받는 서브클래스 SubClass 정의
class SubClass extends AbstractClass {
//추상클래스를 상속받은 서브클래스는 반드시 추상메서드 오버라이딩 필수!
// => 바디를 갖지 않는 추상메서드의 바디를 구현(implement)하는 작업
@Override
public void abstractMethod() {
System.out.println("서브클래스에서 오버라이딩(구현)된 추상메서드!");
}
public void subClassMethod() {
System.out.println("서브클래스에서 정의한 메서드!");
}
}
/*
* 슈퍼맨, 새, 비행기의 공통점 : 비행 가능
* => 공통점을 추출하여 상위클래스로 정의하되,
* 각 서브클래스에서 비행 기능을 반드시 구현하도록 강제성을 부여
*/
abstract class Flyer {
// 모든 날아다니는 것들에 대한 이륙, 비행, 착륙 메서드 정의
// => 슈퍼클래스로 사용할 Flyer 클래스의 메서드들에는
// 실행할 코드가 불필요하므로 추상메서드로 정의하고
// 추상메서드를 포함하는 Flyer 클래스를 추상클래스로 정의
public abstract void takeOff();
public abstract void fly();
public abstract void land();
}
//Flyer 클래스를 상속받는 SuperMan, Bird, AirPlane 클래스 정의
class SuperMan extends Flyer {
@Override
public void takeOff() {
System.out.println("SuperMan 이륙!");
}
@Override
public void fly() {
System.out.println("SuperMan 비행!");
}
@Override
public void land() {
System.out.println("SuperMan 착륙!");
}
}
class Bird extends Flyer {
@Override
public void takeOff() {
System.out.println("Bird 이륙!");
}
@Override
public void fly() {
System.out.println("Bird 비행!");
}
@Override
public void land() {
System.out.println("Bird 착륙!");
}
}
class AirPlane extends Flyer {
@Override
public void takeOff() {
System.out.println("AirPlane 이륙!");
}
@Override
public void fly() {
System.out.println("AirPlane 비행!");
}
@Override
public void land() {
System.out.println("AirPlane 착륙!");
}
}
/*
서브클래스에서 오버라이딩(구현)된 추상메서드!
서브클래스에서 정의한 메서드!
서브클래스에서 오버라이딩(구현)된 추상메서드!
==========================
SuperMan 이륙!
SuperMan 비행!
SuperMan 착륙!
Bird 이륙!
Bird 비행!
Bird 착륙!
AirPlane 이륙!
AirPlane 비행!
AirPlane 착륙!
-----------------------------
SuperMan 이륙!
SuperMan 비행!
SuperMan 착륙!
Bird 이륙!
Bird 비행!
Bird 착륙!
AirPlane 이륙!
AirPlane 비행!
AirPlane 착륙!
*/
public class Ex2 {
public static void main(String[] args) {
}
}
abstract class AbstractClass2 {
public abstract void method1();
public abstract void method2();
}
//추상메서드 2개를 갖는 추상클래스를 상속받아 서브클래스 정의
abstract class MiddleClass extends AbstractClass2 {
//상속받은 추상메서드 2개 중 하나만 구현하는 경우
// => 추상메서드가 구현되지 않은 채 그대로 존재할 경우
// 해당 서브클래스도 추상클래스로 선언해야한다!
@Override
public void method1() {
System.out.println("MiddleClass에서 구현한 method1()");
}
}
//추상메서드를 모두 구현하지 않은 서브클래스(추상클래스) MiddleClass 를
//상속받는 서브클래스 SubClass2 정의
class SubClass2 extends MiddleClass {
// method1() 메서드는 MiddleClass 에서 이미 구현되어 있으므로 강제성 X
// 여전히 강제성이 남아있는 method2() 메서드는 반드시 구현해야한다!
@Override
public void method2() {
System.out.println("SubClass2 에서 구현한 method2()");
}
}
public class Test2 {
public static void main(String[] args) {
// Vehicle v = new vehicle(); // 인스턴스 생성 불가
// 추상클래스 Vehicle 타입을 참조변수로 활용
Vehicle v = new ElectricCar();
v.reportPosition();
v.addFuel();
v = new DiselCar();
v.reportPosition();
v.addFuel();
}
}
abstract class Vehicle {
int curX, curY; // 현재 위치 좌표를 저장하는 변수
public void reportPosition() { //서브클래스에서 오버라이딩 옵션
System.out.println("현재위치: " + curX + ", " + curY );
}
// public void addFuel() {
//// System.out.println("자동차의 연료 공급!");
// }
// => 차량마다 연료 공급 방법이 달라지므로 오버라이딩을 해야하며
// 오버라이딩 강제성을 부여하기 위해 추상메서드로 정의할 수 있다!
public abstract void addFuel();//서브클래스에서 구현 필수
}
//Vehicle 클래스를 상속받는 ElectricCar, DieselCar 클래스 정의
//=> ElectricCar 의 addFuel() : "전기차 충전소에서 배터리 충전!"
//=> DieselCar 의 addFuel() : "주유소에서 디젤 연료 공급!"
class ElectricCar extends Vehicle {
@Override
public void addFuel() {
System.out.println("전기차 충전소에서 배터리 충전!");
}
}
class DiselCar extends Vehicle {
@Override
public void addFuel() {
System.out.println("주유소에서 디젤 연료 공급!");
}
}
/*
현재위치: 0, 0
전기차 충전소에서 배터리 충전!
현재위치: 0, 0
주유소에서 디젤 연료 공급!
*/
반응형
'JAVA' 카테고리의 다른 글
| [Java] 상수(Constant), 열거형(enum type) (0) | 2021.11.01 |
|---|---|
| [Java] 다형성 연습 (0) | 2021.11.01 |
| [Java] 다형성(Polymorphism) (0) | 2021.11.01 |
| [Java] 상속(inheritance) - 동적 바인딩 (0) | 2021.10.31 |
| [Java] instanceof (0) | 2021.10.31 |