본문 바로가기
백엔드/자바

자바 - 13

by study_yeon 2023. 5. 16.

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 자동생성
 

'백엔드 > 자바' 카테고리의 다른 글

자바 - 15  (0) 2023.05.18
자바 - 14  (0) 2023.05.17
자바 - 12  (0) 2023.05.14
자바 - 11  (0) 2023.05.11
자바 - 10  (0) 2023.05.10