일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | ||||||
2 | 3 | 4 | 5 | 6 | 7 | 8 |
9 | 10 | 11 | 12 | 13 | 14 | 15 |
16 | 17 | 18 | 19 | 20 | 21 | 22 |
23 | 24 | 25 | 26 | 27 | 28 |
- cicd
- Persistent Volume
- AWS
- Persistent Volume Claim
- NFS Client Privisioner
- grafana
- k8s
- node exporter
- emptyDir Volume
- ncp
- volume
- Prometheus
- alertmanager
- ALB
- ingress controller
- kubernetes
- SSL Offload
- aws-dop
- DevOps
- Codedeploy
- emptyDir
- Codebuild
- Codepipeline
- HTTPS Redirect
- RKE2
- slack
- ingress
- Naver cloud platform
- codecommit
- pod
- Today
- Total
Cloud SA's This and That
[JAVA] 상속과 인터페이스 + ChatGPT 활용하기 본문
chatGPT를 통해 상속과 인터페이스를 사용한 자바 코드 학습을 진행해보았다.
<학습 키워드 정리>
[상속] : 자식 클래스가 부모의 속성을 물려받는 것.
> 상속의 장점 : 클래스 확장이 용이하며 코드의 재사용이 가능하다.
> 사용 키워드 : extends - 상속 관계 / super - 부모 클래스 생성자 호출
-> 부모의 디폴트 생성자의 경우 자식 클래스의 생성자 호출 시 자동 호출된다
-> 다만 부모 클래스에 디폴트 생성자가 없고 매개변수를 받는 생성자만 있다면 명시적으로 super()을 사용하여 호출해줘야 함.
> 메소드 오버라이딩 : 부모 메소드를 자식 클래스에서 재정의
> 자식 객체 생성 시 주의점 : 부모 클래스의 영역을 먼저 만들어야 한다.
[인터페이스] : 역할을 정의하는 하나의 타입으로 Prototype 메소드를 갖는다.(Prototype : 내용이 없는 메소드)
> 인터페이스 장점 : 다형성 (한 객체를 다양하게 해석) / 그룹화 (여러 객체를 한 타입으로 관리)
> 사용 키워드 : interface
> 인터페이스는 클래스 정의와 유사한 형식을 가지며 인터페이스에서 선언된 메소드는 해당 인터페이스를 구현하는 클래스에서 반드시 메소드 오버라이딩되어야 한다.
[추상클래스] : 객체 생성이 불가한 클래스로 자식 클래스를 통해 간접적으로 객체를 생성할 수 있다.
> 사용 키워드 : abstract
> 언제 사용? : 객체가 스스로 존재할 수 없는(하면 안되는) 경우에 사용한다.
> 추상클래스 장점 : 코드 중복 제거 / 다형성 및 그룹화
========================================================================================
<상속과 인터페이스를 사용한 코드> - 해당 코드로 ChatGPT를 통해 학습을 진행해 보았다.
코드 출처 : 홍팍 (https://www.youtube.com/watch?v=Wuyr_X7CKCU&list=PLyebPLlVYXCjs-KSw3HF2jFX9-7S8HjlJ&index=36)
설명 : 기사(Knight)는 탱커(Tanker)의 역할을 수행하며 기사(Knight)는 성기사(HolyKnight)와 마검사(MagicKnight)로 2차 전직이 가능하다. 성기사(HolyKnight)의 경우 힐러(Healer)의 역할을, 마검사(MagicKnight)의 경우 마법사(Socerer)의 역할을 추가로 부여 받는다.
public class Main {
public static void main(String[] args) {
Knight uther = new HolyKnight("우서",200,10);
Knight arthas = new MagicKnight("아서스",150,20);
uther.increaseArmor();
uther.increaseHp();
HolyKnight holyUther = (HolyKnight) uther;
holyUther.healingAura();
holyUther.holyArmor();
arthas.increaseHp();
arthas.increaseArmor();
MagicKnight magicArthas = (MagicKnight) arthas;
magicArthas.fireArmor();
magicArthas.thunderBlade();
}
}
interface Tanker{ // 탱커 역할을 인터페이스로 정의
public void increaseArmor(); // Prototype 메소드
public void increaseHp(); // Prototype 메소드
}
interface Healer{ // 힐러 역할을 인터페이스로 정의
public void healingAura(); // Prototype 메소드
public void holyArmor(); // Prototype 메소드
}
interface Sorcerer{ // 마법사 역할을 인터페이스로 정의
public void fireArmor(); // Prototype 메소드
public void thunderBlade(); // Prototype 메소드
}
class Knight implements Tanker{ // 탱커 역할을 부여받은 Knight 클래스
protected String name;
protected int hp;
protected int armor;
public Knight(String name, int hp, int armor){ // 생성자
this.name = name;
this.hp = hp;
this.armor = armor;
}
public void increaseArmor(){ // 메소드 오버라이딩
System.out.printf("[%s] increaseArmor() 시전!\n", name);
System.out.println("\t아머가 +5 증가합니다.");
armor += 5;
}
public void increaseHp(){ // 메소드 오버라이딩
System.out.printf("[%s] increaseHp() 시전!\n", name);
System.out.println("\t체력이 +100 증가합니다");
hp += 100;
}
}
class HolyKnight extends Knight implements Healer{ // Knight 클래스를 상속받은 힐러 역할을 부여받은 HolyKnight 클래스
public HolyKnight(String name, int hp, int armor){
super(name,hp,armor); // 부모 클래스 생성자 호출
}
public void healingAura(){ // 메소드 오버라이딩
System.out.printf("[%s] healingAura() 시전!\n", name);
System.out.println("\t초당 체력회복이 +10 증가합니다.");
}
public void holyArmor(){ // 메소드 오버라이딩
System.out.printf("[%s] holyArmor() 시전!\n", name);
System.out.println("\t데미지를 -10 덜 받습니다.");
}
}
class MagicKnight extends Knight implements Sorcerer{ // Knight 클래스를 상속받은 마법사 역할을 부여받은 HolyKnight 클래스
public MagicKnight(String name, int hp, int armor){
super(name, hp, armor); // 부모 클래스 생성자 호출
}
public void fireArmor(){ // 메소드 오버라이딩
System.out.printf("[%s] fireArmor() 시전!\n", name);
System.out.println("\t주변 적에게 초당 +10의 데미지를 줍니다.");
}
public void thunderBlade(){ // 메소드 오버라이딩
System.out.printf("[%s] thunderBlade() 시전!\n", name);
System.out.println("\t매 공격시 +10의 추가 데미지를 줍니다.");
}
}
<출력결과>
<메인 클래스>
public static void main(String[] args) {
Knight uther = new HolyKnight("우서",200,10);
Knight arthas = new MagicKnight("아서스",150,20);
uther.increaseArmor();
uther.increaseHp();
HolyKnight holyUther = (HolyKnight) uther;
holyUther.healingAura();
holyUther.holyArmor();
arthas.increaseHp();
arthas.increaseArmor();
MagicKnight magicArthas = (MagicKnight) arthas;
magicArthas.fireArmor();
magicArthas.thunderBlade();
}
}
> 여기서 아직 학습이 부족한 나로써는 메인 클래스 부분에 대해 더 정확히 분석하고 싶어 ChatGPT를 사용해보았다.
> 우선 질문할 주제에 알려준 뒤 위의 코드를 올리고 질문을 던져보았다.
> 해당 답변을 통해 메인 클래스의 메인 메소드에서 Knight 타입의 uther 변수가 HolyKnight 객체를 참조한다는 것과 실제 선언된 타입은 Knight이기 때문에 형변환을 통해 HolyKnight로써 사용(HolyKnight 클래스 메소드 사용)할 수 있다는 것을 알게되었다.
그렇다면 왜 이렇게 객체를 참조를 하는지에 대해 궁금했고 이어서 질문을 던져보았다.
> 정리하자면 Knight 타입으로 선언하여 HolyKnight 객체를 참조하는 것은 코드의 유연성과 확장성, 다형성 등을 최대한 활용하기 위함이라고 한다. 그리고 ChatGPT 사용 전 Custom 설정 부분이 있는데 그 설정 부분에 답을 어떤식으로 해달라고 적은 적이 있다. (예를 들어 모르겠다라는 답은 하지말라던가, 나에게 추가 질문을 해달라던가..) 이 덕분인지 ChatGPT는 나에게 3가지의 질문을 던졌다.
> 나의 현재 학습에 매우 도움이 될 것 같아 해당 질문에 대한 답을 해달라고 하였고 ChatGPT는 각 질문에 대해 답해주었다.
> 확실히 답변을 보면 현재 내가 알고자하는 것에 대해 정확히 파악하고 나를 더 성장시켜줄 수 있도록 질문을 던지는 것이 보였다..(너무 신기..)
그리고 추가적으로 대화를 이어가다 다형성에 대해 좀 더 학습하고자 해당 질문을 던졌다. (형변환은 가독성을 떨어뜨린다기에 질문에 추가하였다.)
> 다형성을 통해 코드를 구성하기 위해서는 공통된 인터페이스나 부모 클래스를 통해 작업하는 방식을 채택하는 것을 권하며 예제를 보여준다. 위의 대화들을 통해 메인메소드를 수정하여 주석처리를 한 뒤 ChatGPT에 확인요청을 하였다.
(수정한 메인클래스 코드) - 3문단 모두 같은 출력 결과이다
public static void main(String[] args) {
Knight uther = new HolyKnight("우서",200,10); //knight 타입의 uther 변수가 HolyKnight 객체 참조
HolyKnight holyUther = (HolyKnight) uther; // 형변환 (Knight -> HolyKnight)
holyUther.healingAura(); // HolyKnight 클래스의 메소드 호출
holyUther.holyArmor(); // HolyKnight 클래스의 메소드 호출
Healer healerUther = (Healer) uther; // 형변환 (Knight -> Healer) <다형성에 최적화>
healerUther.healingAura(); // Healer 인터페이스의 메소드 호출
healerUther.holyArmor(); // Healer 인터페이스의 메소드 호출
((Healer)uther).healingAura(); // 같은 결과 (코드 가독성에는 별로)
((Healer)uther).holyArmor();
}
}
> 솔직히 해당 내용들을 독학으로 책이나 인터넷 서칭을 통해 알아내려 했다면 이미 지쳐서 예전의 과오를 되풀이하고있지 않았을까싶다..ㅎㅎ 물론 아직 갈날이 멀었지만 ChatGPT 덕분에 좀 더 빠르고 효율적으로 학습이 가능한 것은 틀림이 없다!
Spring Boot 가쟈!