* 추상클래스
- 추상(abstract) <-> 구체(구상)(concrete)
- 추상 : 지시,명령
- ex) 부모님 : 공부해라(추상) -> 자녀 : 공부하다(구체)
- ex) 선임 : ~ 하세요(추상) -> 후임 : ~ 하겠습니다(구체)
- 추상 메서드 : 메서드 구현부(몸통,body)가 없다
- 추상 클래스 : 실체클래스(객체 생성용 클래스)들의 공통적인 특성(필드,메소드)을 추출하여 선언한 것
- 추상클래스와 실체 클래스는 부모,자식 클래스로서 상속 관계를 가진다
- 추상 클래스는 추상 메서드가 있을 수도 없을 수도 있다
package company; // 추상 클래스는 "항상" 추상 메서드가 있어야 한다(X) // 추상 클래스는 추상 메서드를 가질 수 있다(O) // ex) 회사 직급 : 과장(중간 계층) //public abstract class AbstractClass { // 접근성 강조 abstract public class AbstractClass { // 추상 강조 String name; // 추상 클래스의 생성자는 직접 호출될 수 없으나 // 인스턴스 생성시 간접적으로 호출 된다(ex) 뒷바라지,support(후견,후원)) public AbstractClass() { // 기본 생성자 System.out.println("추상 클래스의 생성자"); } // abstract static void demoMethod(); // (X) // static, final -> 오버라이딩 안됨 -> "추상"은 오버라이딩 해야된다 // 추상 : 지시,명령 // ex) 부모님 : 공부해라(추상) -> 자녀 : 공부하다(구체) // ex) 선임 : ~ 하세요(추상) -> 후임 : ~ 하겠습니다(구체) // 추상 메서드 : 메서드 구현부(몸통,body)가 없다 abstract void abstractMethod(); // body{}가 없다 //void abstractMethod();(X) // 참고) 그러나 인터페이스(interface)에서는 추상(abstract) 키워드를 생략할 수 있다 void parentMethod() { System.out.println("추상 클래스의 인스턴스 메서드"); } public static void main(String[] args) { // 추상 클래스의 생성자는 직접 호출 할 수 없다 // ex) 과장님이 아래 직원들과 소통 없이 혼자 일하면 과장 직임에 적합하지 않다(추상 클래스가 아니다) // ex) 과장님(추상 클래스)은 아래 직원들과의 소통을 통해서 일을 구현해야 한다 // 추상 클래스는 상속받는(계약관계, 구현,구체) 클래스의 생성자에 의해서 일(인스턴스,객체)을 생성(업무 이행)할 수 있다 // AbstractClass obj = new AbstractCalss(); // 다형성(poly-morhp-ism) AbstractClass obj = new ConcreteClass(); // 1) ConcreteClass obj = new ConcreteClass(); // 2) obj.abstractMethod(); obj.parentMethod(); obj.childMethod(); // 2)의 경우에만 호출 가능 : 다형성 } }
package company; public class ConcreteClass extends AbstractClass { public ConcreteClass() { System.out.println("구현 클래스의 생성자"); } @Override void abstractMethod() { System.out.println(" 지시대로 구현하다"); } void childMethod() { System.out.println("구현 클래스의 인스턴스 메서드"); } }
* 인터페이스
- 함수의 선언부 -> 인터페이스(추상메서드 덩어리), 지시, 추상 메서드
- 인터페이스는 상수(constant)”만” 멤버 필드로 허용한다
- 인터페이스는 생성자를 가질 수 없다 : 일하는 것(구현)과 무관
- 정적 블럭 (X)
- 인스턴스 블럭 (X)
- static 메소드 (O)
- main 메소드 (o)
- default 메소드 (O) : 오버라이딩을 할 수 있으나 강제성(의무성)이 없다,일반 클래스의 인스턴스 멤버 메서드 처럼 메서드의 구현부(몸통)을 가질 수 있다
- default(기정) 키워드 1) switch ~ case : 기정값 2) default(package) 접근 제한자 (무표기) 3) interface의 default 메서드
- 구현 클래스에서 오버라이딩한 메서드가 있으면 호출 시 구현 클래스의 메서드를 호출하고, 구현 메서드가 없으면 인터페이스 자신의 디폴트 메서드를 호출한다
- ex) 이(구현 클래스)가 없으면 잇몸(인터페이스)으로 한다
* 계산기 프로그램 구현하기
- 코드 1) interface 생성
package com.javateam.jse; public interface CalcInterface { int add (int num1, int num2); int subtract (int num1, int num2); int multiply (int num1, int num2); float divide (int num1, int num2); int remainder (int num1, int num2); }
-
코드 2) class 생성 => return 값(기능) 입력
package com.javateam.jse; public class CalcClass implements CalcInterface { @Override public int add(int num1, int num2) { return num1 + num2; } @Override public int subtract(int num1, int num2) { return num1 - num2; } @Override public int multiply(int num1, int num2) { return num1 * num2; } @Override public float divide(int num1, int num2) { return (float)num1 / num2; } @Override public int remainder(int num1, int num2) { return num1 % num2; } }
-
코드 3) test 클래스 생성 => 메서드 테스트
package com.javateam.jse.test; import com.javateam.jse.CalcClass; import com.javateam.jse.CalcInterface; public class CalcTest extends CalcClass { public static void main(String[] args) { //CalcClass calc = new CalcClass(); // (O) CalcInterface calc = new CalcClass(); System.out.println(calc.add(2, 15)); System.out.println(calc.subtract(2, 15)); System.out.println(calc.multiply(2, 15)); System.out.println(calc.divide(15, 2)); System.out.println(calc.remainder(15, 2)); } }