2023.05.15
* API
application programming interface
- 여러 프로그램들과 데이터베이스, 그리고 기능들의 상호 통신 방법을 규정하고 도와주는 매개체
* 통신방법
rest - msa(마이크로소프트아키텍쳐)
* 개발프로세스 (6-sigma)
계획수립 > 분석 > 설계 > 구축 > 테스트 > 보수
* 애자일 방법론(민첩한, 재빠름)
소프트웨어 전체를 작은 기능 단위로 쪼개어 조금씩 개발(테스트 과정을 거침)하는 방식
● 상속
* 메소드 클래스를 별도로 구분하는 방법
1. 클래스
2. 인터페이스
3. 추상화(abstract)
▷ 상속 연습1 - 억지 코딩
패키지 calculation
1단계(BaseCalc) 변수 x, y, result. toString
2단계(Calc1) add, sub
3단계(Calc2) mul, div
4단계(Calc3) print(x, y, 연산자)
5단계(CalcApp) 실행클래스
- 2단계는 1단계를, 3단계는 2단계를, 4단계는 3단계를 상속
- 실행클래스는 상속 필요 없음
BaseCalc > Calc1 > Calc2 > Calc3
▷ 상속 연습2
* 스토리 : 계산기가 하나밖에 없는 회사
* 패키지 inherit.abstractclass
* 1단계 (AbstractCalc) 메소드
package inherit.abstractclass;
//abstract라는 키워드가 붙으면 이 클래스는 객체로 인스턴스를 만들 수 없다.
public abstract class AbstractCalc {
int add(int x, int y) {
return x + y;
}
int sub(int x, int y) {
return x - y;
}
int mul(int x, int y) {
return x * y;
}
int div(int x, int y) {
return x / y;
}
// 매개변수로 넘어온 계산기가 지금 이 계산기와 같은가?
boolean checkCalcSame(AbstractCalc calcTemp) {
return (this == calcTemp);
}
}
- 메소드를 만들어 실행클래스에서 호출하여 사용
boolean checkCalcSame(AbstractCalc calcTemp) {
return (this == calcTemp);
}
checkCalcSame() : 메소드의 이름
AbstractCalc : 메소드가 허용할 변수 유형
AbstractCalc calcTemp : 매개변수
* 2단계 (DataCalc) 변수 [x, y, result], toString
- DataCalc는 AbstractCalc가 부모
package inherit.abstractclass;
public class DataCalc extends AbstractCalc {
int x;
int y;
int result;
@Override // 오브젝트 클래스로부터 물려받은 메소드를 새로운 기능으로 확장(public접근제한자)
public String toString() {
return "x=" + x + ", "
+ "y=" + y;
}
}
3단계(AbstractCalcApp) 실행클래스
package inherit.abstractclass;
public class AbstractCalcApp {
public static void main(String[] args) {
// 직원1 사용하는 계산기
DataCalc calc1 = new DataCalc();
if (calc1.checkCalcSame(calc1)) {
p("같은 객체입니다.");
} else {
p("다른 객체입니다.");
}
// 키보드로 부터 Scanner를 사용해도 됨
int x = 1000;
int y = 500;
int result;
result = calc1.add(x, y);
p(x + " + " + y + " = " + result);
// 직원2 사용하는 계산기
DataCalc calc2 = new DataCalc(); // 새로운 객체가 만들어짐
if (calc1.checkCalcSame(calc2)) {
p("같은 객체입니다.");
} else {
p("다른 객체입니다.");
}
x = 2000;
y = 1000;
result = calc2.add(x, y);
p(x + " + " + y + " = " + result);
// 직원3 사용하는 계산기
// 업캐스팅
AbstractCalc calc3 = new DataCalc(); // 크기가 AbstractCalc라 DataCalc에서 만들어진 요소를 사용 못함
// ((DataCalc)calc3). 호출 불가
}
// 유틸리티 메소드
public static void p(String msg) { // main에서 사용하고 싶다면 static 붙이기
System.out.println(msg);
}
}
* 업캐스팅 : 자식클래스를 부모클래스로 승격하는 기능
-> 자식클래스가 부모클래스처럼 동작(부모클래스가 가진 기능만 쓸 수 있다)
▷ 상속연습3 - 책 310p
* 자바에서 다중상속이 가능한 조건 : 인터페이스(여러개 지정 가능) 활용
* 모든 메소드는 예외를 가지고 있다.
패키지 inherit.people (315p)
클래스 Student extends People
package inherit.people;
// 부모
public class People {
public String name;
public String ssn;
public People(String name, String ssn) {
this.name = name;
this.ssn = ssn;
}
}
ackage inherit.people;
// 자식
public class Student extends People {
// 필드
public int studentNo;
// 생성자(부모로부터 생성자가 상속 됨) - 자식클래스의 생성자
// 오버로딩 아님(한 클래스안에 같은 이름의 메서드)
// 오버라이딩 아님(부모클래스의 메서드를 자식 클래스에서 재정의하여 사용)
public Student (String name, String ssn, int StudentNo) {
super(name, ssn);
this.studentNo = studentNo;
}
}
실행클래스 StudentApp
package inherit.people;
public class StudentApp {
public static void main(String[] args) {
Student student = new Student("홍길동", "123456-1234567", 1);
System.out.println("name : " + student.name); // 상속
System.out.println("ssn : " + student.ssn); // 상속
// student가 가진 멤버
System.out.println("studentNo : " + student.studentNo);
}
}
* 메소드 재정의 = 오버라이딩 - 317p
- 상속된 일부 메소드를 자식클래스에서 다시 수정하여 사용할 때 이용
- 오버라이딩은 시그니처가 같아야함
(오버로딩의 시그니처는 상이해야함)
- 접근 제한을 더 강하게 재정의할 수 없다
(부모가 public일 경우 재정의하는 자식은 private, default를 가질 수 없다)
▷ overriding 연습 1
* 스토리 : Calculator 만들기(319p)
패키지 inherit.overriding
클래스 Computer extends Calculator
package inherit.overriding;
public class Calculator {
// 변수에 담아 이 곳만 변경(코드관리가 쉬워짐)
// 변수를 상수처럼 쓴다고 해서 변수->기호 상수(값 고정)
// final은 const의 의미(자바 보안프로그램의 시작)
final double PI = 3.14159;
double areaCircle(double r) {
// 로그기록
System.out.println("Calculator 객체의 areaCircle() 실행");
return PI * r * r; // 원의 면적
}
// 하드코딩
double circumferenceCircle(double r) {
return 3.14159 * r * 2;
}
// 기호상수
double circumferenceCircle2(double r) {
return PI * r * 2;
}
}
- 하드코딩 보다는 기호상수 활용하기
package inherit.overriding;
public class Computer extends Calculator {
@Overriding
double areaCircle(double r) { // 재정의
System.out.println("Computer 객체의 areaCircle() 실행");
return Math.PI * r * r; // 기호상수
}
}
실행클래스 ComputerApp
package inherit.overriding;
public class ComputerApp {
public static void main(String[] args) {
// 변수
int r = 10;
// Calculator 부모 객체
Calculator cal = new Calculator();
System.out.println("원면적 : " + cal.areaCircle(r));
// Computer 자식 객체
Computer com = new Computer();
System.out.println("원면적 : " + com.areaCircle(r));
}
}

* 기호상수 : 변경이 불가한 변수
ex) PI(3.141592...)

* 재정의 메소드 자동생성

▷ overriding 연습 2 - 부모 메소드 호출
패키지 inherit.vehicle
클래스 SuperSonicAirplane extends Airplane
package inherit.vehicle;
public class Airplane {
// 멤버변수
String name;
// 생성자
Airplane(String name) {
this.name = name;
}
// 메소드
public void land() {
System.out.println("착륙합니다.");
}
public void fly() {
System.out.println("일반 비행합니다.");
}
public void takeOff() {
System.out.println("이륙합니다.");
}
}
package inherit.vehicle;
// 부모 메소드 호출 - 320p
public class SuperSonicAirplane extends Airplane {
public static final int NORMAL = 1;
public static final int SUPERSONIC = 1;
public int flyMode;
SuperSonicAirplane(String name) {
super(name); // 부모클래스 초기화
flyMode = NORMAL; // 자신 초기화
}
public void fly() {
if(flyMode == SUPERSONIC) {
System.out.println("초음속 비행합니다.");
} else {
super.fly(); // 부모 클래스의 fly()메소드 호출 (클래스이름.메소드())
}
}
}
- 부모 클래스의 메소드 호출 : 클래스이름.메소드()
실행클래스 SuperSonicAirplaneApp
package inherit.vehicle;
public class SuperSonicAirplaneApp {
public static void main(String[] args) {
SuperSonicAirplane sa = new SuperSonicAirplane("콩코드");
sa.takeOff();
sa.fly();
sa.flyMode = SuperSonicAirplane.SUPERSONIC;
sa.fly();
sa.flyMode = SuperSonicAirplane.NORMAL;
sa.fly();
sa.land();
}
}

● 패키지 - 책 286p
* 클래스 이름 표현법 : 상위패키지.하위패키지.클래스
- 경로를 알려주는 이정표 역할
* 패키지 선언
package 상위패키지.하위패키지;
public class 클래스이름 {...}
* 명명법
- 소문자 작성
- 숫자로 시작 안되고, _$를 제외한 특수문자 사용 불가
* import문
- 사용하고자 하는 클래스 또는 인터페이스가 다른 패키지에 소속되어 있을 경우 import문 작성하여 컴파일러에게 알림
- 작성법
1. import 상위패키지.하위패키지.클래스이름;
2. import 상위패키지.하위패키지.*;
● 접근제한자 -책 293p
- (클래스 및 인터페이스 그리고 이들이 가지고 있는 멤버) 접근을 제한하기 위해 사용
public / protected / private / default
● getter/ setter 메소드
- 객체지향프로그램에서는 객체의 필드를 객체 외부에서 직접적으로 접근하는 것을 막음
-> 외부에서 맘대로 변경할 경우 객체의 무결성(결점이 없는 성질)이 깨질 수 있기 때문
ex) 범위 지정
* getter
public 리턴타입 getFieldName() {
return fieldName;
}
- 메소드이름 get + 필드네임(첫 글자는 대문자)
- 리턴값 : 필드값
* setter
public void setFieldName() {
this.fieldName = fieldName;
}
- 메소드이름 set + 필드네임(첫 글자는 대문자)
- 리턴값 없음 : void
* boolean은 get대신 is, has를 사용
- set은 상단의 구조와 동일하게 사용
* Lombok라이브러리 : getter / setter 자동생성