kosta 클라우드 네이티브 애플리케이션 개발 과정 day 14
지난 시간 복습 !
오버라이딩 overriding
- 상속 관계
-> 왜 하느냐? 부모 클래스의 메서드를 자식 클래스에서 다시 재정의 !
-> 왜? 내게 적합하지 않기 때문에
- 원칙 : 부모 메서드 시그니처는 일치해야 한다 !
-> 자바의 다형성을 표현한다 !
public class Dog{
private String name;
public void bark();
}
public class BorderCollie extends Dog {
@Override
public void bark(){
sout("왈왈!")
}
}
public class Yorkshire extends Dog {
@Override
public void bark(){
sout("와우와우!");
}
}
Object 형변환
- 객체간의 형변환은 필수다 ! (배열)
- 원칙 : 부모 클래스의 데이터 타입이 자식 클래스보다 크다 ==> 상속 관계
List<String> list = new ArrayList<>();
Video movie = new Movie();
Video drama = new Drama();
Video[] videos = { new Movie(), new Drama(), new Sport() }
for ( Video video : videos) {
video.watch();
}
- 단, 부모형으로 변환시에는 제약이 있다 ! 자신만이 가지고 있던 메서드는 사용 불가
- 부모 -> 자식으로 형 변환시 반드시 강제 캐스팅 필요 !
- 자식 obj = (자식) 부모형 객체
- if (obj instance of 변환하고자 하는 타입) =>
모든 새로운 기술이 나오면 게시판을 짜본다.
짜봐야 안다 !
과제 : phoneInfo 예제 v2
1.일반 2.동창 3.직장
-> General
-> University
-> Company
-> Contact를 하나로 관리한다고 할 때 얘네 타입을 일치하여 관리하는 방법이 어떻게 가능할까?
=> 다형성 !
상속을 이용한 contact 프로그램 리팩토링 !
public void addInfo() {
String type = InputView.getType();
String name = InputView.getName(ADDITION);
String number = InputView.getNumber();
LocalDate localDate = LocalDate.of(InputView.getDobYear(), InputView.getDobMonth(), InputView.getDobDate());
switch (type) {
case "일반" -> contacts.add(new ContactGeneral(type, name, number, localDate));
case "동창" -> contacts.add(new ContactUniversity(type, name, number, localDate));
}
}
함수형 인터페이스를 이용한 print 메서드 분리 (전략 패턴 구현)
package kosta.mission2.mission2_07.ui.printAction;
public interface PrintAction {
void print();
}
package kosta.mission2.mission2_07.ui.printAction;
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
public class PrintGeneralContact implements PrintAction{
private String type;
private String name;
private String number;
private String dobFormatted;
public PrintGeneralContact() {
}
public PrintGeneralContact(String type, String name, String number, LocalDate dob) {
this.type = type;
this.name = name;
this.number = number;
this.dobFormatted = DateTimeFormatter.ofPattern("yyyy년 MM월 dd일").format(dob);
}
@Override
public void print() {
System.out.printf("\n[%s] 이름: %s 전화번호: %s 생년월일: %s\n", type, name, number, dobFormatted);
}
}
package kosta.mission2.mission2_07.ui.printAction;
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
public class PrintUniversityContact implements PrintAction{
private String type;
private String name;
private String number;
private String dobFormatted;
private String major;
private String studentId;
public PrintUniversityContact(String type, String name, String number, LocalDate dob, String major, String studentId) {
this.type = type;
this.name = name;
this.number = number;
this.dobFormatted = DateTimeFormatter.ofPattern("yyyy년 MM월 dd일").format(dob);
this.major = major;
this.studentId = studentId;
}
@Override
public void print() {
System.out.printf("\n[%s %s %s] 이름: %s 전화번호: %s 생년월일: %s\n", type, major, studentId, name, number, dobFormatted);
}
}
abstract 클래스를 알아보자 !
인스턴스화를 금지하는 abstract => 객체화가 불가하다.
추상 메서드의 목적 => 자식에게 반드시 overriding을 통해 구현을 강제한다 !
public abstract class Account{
add();
}
추상 클래스를 인스턴스화하면 에러가 발생한다 !
Account obj = new Account("111", "lee");
=> 에러
그런데 왜 추상클래스는 구체적인 구현을 금지할까?
추상클래스니까... ?
객체 생성 목적이 아니라 자식 클래스의 구현을 위해 존재한다.
추상 클래스를 구현해보자
package kosta.basic.day014.oop2;
public abstract class Role {
abstract void doSomething();
}
다음과 같은 다형성이 가능하다.
Person person1 = new Person("홍길동", new Study());
person1.doSomething();
Person person2 = new Person("홍길동", new Study());
person2.doSomething();
그런데 그냥 일반 상속을 사용해도 가능하다.
왜 ?
강제하도록 하기 위해서.
코드의 일관성 => 반드시 해당 메서드가 구현될 것이며, 설계로서 존재한다는 것이 보장된다.
코드의 독립성 => 한 클래스를 수정할 때 다른 코드가 바뀌지 않는다.
인터페이스와 추상클래스를 사용하는 이유 !
인터페이스
인터페이스가 왜 나왔을까?
자바에서 다중 상속을 허용하지 않기 때문
사용 용도
1. 자신이 인터페이스를 생성해서 사용하는 경우
2. 자바 API 인터페이스를 사용하는 경우
-> 추상클래스와 용도가 같다
-> 모두 추상 메서드 => abstract를 붙여도 되고 안 붙여도 된다.
인터페이스로 형변환이 가능하다 !
role을 인터페이스로도 구현하기
package kosta.basic.day014.oop2.abstractEx2;
public interface RoleInterface {
void doSomething();
}
자바 api에서 쓰는 interface는 기능을 구현하기 위해 사용한다 !
package kosta.mission2.mission2_11.interfaceExample2;
public class MyThread implements Runnable{
@Override
public void run() {
for (int i = 0; i< 10; i++){
try{
Thread.sleep(1000);
} catch (Exception e){
System.out.println(i);
}
}
}
public static void main(String[] args) {
MyThread myThread = new MyThread();
Thread thread = new Thread(myThread);
thread.start();
for (int i = 11; i<=20; i++){
try {
Thread.sleep(1000);
} catch (Exception e){
System.out.println(i);
}
}
}
}
인터페이스 wrap up
- 자바의 다중 상속 제약에 따른 대안 - 필요
- implements => 구현한다 (overriding을 통한 추상 메서드 구현)
- 직접 인터페이스를 생성하는 경우 -> 코드의 독립성, 일관성을 추구
- Java API 인터페이스를 사용 -> 특정한 고유 기능을 구현하기 위함
- 인터페이스로 형변환 가능하다 ! => 자바의 다형성 표현
추상클래스 vs 인터페이스 !
존재 목적 부터 다르다! 추상 클래스는 그 클래스를 상속 받아 확장하는 것, 인터페이스는 껍데기만 있는 클래스의 설계를 강제적으로 구현하도록 하는 것.
공통점
- 추상 메서드를 갖고 있다 : 직접 구현이 아닌 extends와 implements를 통한 하위 객체 구현의 설계 방식을 제공
- 하위 객체 구현을 강제함
차이점
- 추상클래스는 상속의 방식을 이용하므로 상위 객체의 필드와 기능을 공통으로 소유함
- 클래스/인터페이스
- 추상클래스는 다중 상속이 불가능하며, 인터페이스는 다중 구현이 가능함
- 추상클래스는 메서드 명에 abstract를 필수적으로 붙여야 함. 인터페이스는 필수가 아님.
'교육 > Java&Spring' 카테고리의 다른 글
kosta 클라우드 네이티브 애플리케이션 개발 과정 day 16 (0) | 2023.01.10 |
---|---|
kosta 클라우드 네이티브 애플리케이션 개발 과정 day 15 (0) | 2023.01.09 |
kosta 클라우드 네이티브 애플리케이션 개발 과정 day 13 (0) | 2023.01.05 |
kosta 클라우드 네이티브 애플리케이션 개발 과정 day 12 (0) | 2023.01.04 |
kosta 클라우드 네이티브 애플리케이션 개발 과정 day 11 (0) | 2023.01.03 |