반응형
1. 포함관계(direct Association) - has A관계
- 포함관계를 맺고 있다 = 포함되어 있는 객체의 메소드를 호출할 수 있다
- step1.
- A클래스를 저장하기 위한 그릇 클래스 안에 참조필드로 생성하기!
- 필드에 객체가 저장되어야지만 명확히 객체를 호출할 수 있다!
- step2.
- Setter메소드 또는 생성자를 이용하여 참조필드에 객체가 저장되도록 설정하기!
- 관계를 맺어서 참조필드로 호출할 수 있는 것이 중요!
- Car & Engine의 포함관계가 성립되기 위해서는?
- 반드시 Setter메소드 또는 생성자를 이용하여 참조필드에 객체가 저장되도록 설정하기
- 만약 참조필드에 객체가 저장되지 않으면 이 관계가 성립되지 않음
[VO] 🚓association > Engine.java
package association;
//엔진정보(연료타입, 배기량)를 저장하기 위한 클래스 - VO클래스
public class Engine {
private String fualType;
private int displacement;
public Engine() {
// TODO Auto-generated constructor stub
}
public Engine(String fualType, int displacement) {
super();
this.fualType = fualType;
this.displacement = displacement;
}
public String getFualType() {return fualType;}
public void setFualType(String fualType) {this.fualType = fualType;}
public int getDisplacement() {return displacement;}
public void setDisplacement(int displacement) {this.displacement = displacement;}
//필드값(엔진정보)를 출력하는 메소드
public void displayEngine() {
System.out.println("엔진타입 = "+fualType);
System.out.println("배기량 = "+displacement);
}
}
[VO] 🚓association > Car.java
package association;
//자동차정보(모델명,생산년도,엔진)를 저장하기 위한 클래스
public class Car {
private String modelName;
private int productionYear;
//엔진정보(Engine 객체)를 저장하기 위한 참조필드 - 포함관계 : Direct Association
// => 포함관계가 성립되기 위해서는 반드시 생성자 또는 Setter 메소드를
//이용하여 참조필드에 객체가 저장되도록 설정
private Engine carEngine;
public Car() {
// TODO Auto-generated constructor stub
}
public Car(String modelName, int productionYear, Engine carEngine) {
super();
this.modelName = modelName;
this.productionYear = productionYear;
this.carEngine = carEngine;
}
public String getModelName() {return modelName;}
public void setModelName(String modelName) {this.modelName = modelName;}
public int getProductionYear() {return productionYear;}
public void setProductionYear(int productionYear) {this.productionYear = productionYear;}
public Engine getCarEngine() {return carEngine;}
public void setCarEngine(Engine carEngine) {this.carEngine = carEngine;}
//필드값(자동차정보)을 출력하는 메소드
public void displayCar() {
System.out.println("모델명 = "+modelName);
System.out.println("생산년도 = "+productionYear);
//carEngine의 메모리 주소 반환해줌
//System.out.println("엔진 = "+ carEngine);
//참조필드에 저장된 객체를 사용하여 메소드 호출
// => 만약 참조필드에 객체가 저장되어 있지 않은 경우
//메소드를 호출하면 NullPointerException 발생
// => 포함관계로 설정된 객체의 메소드 호출 가능
//System.out.println("연료타입 = "+carEngine.getFualType());
//System.out.println("배기량 = "+carEngine.getDisplacement());
carEngine.displayEngine();
}
}
[실행] 🚓association > CarApp.java
package association;
public class CarApp {
public static void main(String[] args) {
//엔진 생성
Engine engine=new Engine();
//engine.displayEngine();
engine.setFualType("경유");
engine.setDisplacement(2000);
//자동차 생성
Car carOne=new Car();
//carOne.displayCar();
carOne.setModelName("쏘렌토");
carOne.setProductionYear(2018);
//방법1.
//자동차에 엔진 포함
// - 🌻Setter 메소드를 이용하여 참조필드에 객체 저장 : 포함 관계 성립
carOne.setCarEngine(engine);
carOne.displayCar();
//모델명 = 쏘렌토
//생산년도 = 2018
//[메소드 변경 전] 엔진 = association.Engine@73a28541
//[메소드 변경 후] 연료타입 = 경유
// 배기량 = 2000
//방법2.
//자동차 생성 >> 엔진 포함
// - 🌻생성자를 이용하여 참조필드에 객체 저장 : 포함 관계 성립
Car carTwo=new Car("싼타페", 2022, new Engine("휘발유", 3000));
carTwo.displayCar();
//모델명 = 싼타페
//생산년도 = 2022
//연료타입 = 휘발유
//배기량 = 3000
System.out.println(carOne.getModelName()+"의 엔진정보 >> ");
engine.displayEngine();
//쏘렌토의 엔진정보 >>
//엔진타입 = 경유
//배기량 = 2000
System.out.println(carTwo.getModelName()+"의 엔진정보 >> ");
//자동차(Car 객체)에서 엔진정보(Engine 객체)를 반환받아 메소드 호출
carTwo.getCarEngine().displayEngine();
//싼타페의 엔진정보 >>
//엔진타입 = 휘발유
//배기량 = 3000
}
}
2.상속관계(inheritance) - is A관계
- 포함은 직접 관계를 만들어줘야했지만, 상속은 어떤 작업을 하지 않아도 상속관계가 자동으로 만들어짐
1) 상속(inheritance)이란?
- 클래스 작성 시 다른 클래스를 상속받아 사용하는 기능
2) 상속을 사용하는 이유
- 프로그램의 생산성이 증가함 : 기존 클래스를 재활용하여 보다 쉽고 빠르게 새로운 클래스를 작성할 수 있기 때문
- 프로그램의 유지보수의 효율성이 증가함 : 공통적인 속성과 행위를 가진 다수의 클래스 생성 시 공통적인 속성과 행위를 상속받아 사용 가능하기 때문
만약 동일한 속성과 기능을 가진 3개의 클래스가 있다고 가정 하자!
상속을 이용하여 동일한 속성과 기능을 가진 부모클래스를 만들어
3개의 클래스가 모두 상속받아 자식클래스가 된다면,
프로그램을 유지보수할 때 부모클래스만 변경하면 됨
ex) 기존클래스를 고려하지 않고
그냥 새로운 클래스(자식)를 만들어도 되지만,
Member클래스(부모)와 유사하기 때문에 상속받아 작성하면 생상성 증가
- Member클래스(부모)
- MemberEvent클래스(자식)
3) 상속의 형식
- extends 키워드로 기본클래스(부모클래스)를 상속받아 새로운 클래스(자식클래스) 작성
- 물려주는 클래스 : 부모클래스, 선조클래스, 기본클래스, Super Class
- 물려받는 클래스 : 자식클래스, 후손클래스, 파생클래스, Sub Class
public class 자식클래스 extends 부모클래스{
//자식클래스에서는 부모클래스의 필드 또는 메소드 사용 가능
}
4) 상속의 특징
- 클래스는 부모클래스의 필드 또는 메소드에 접근하여 사용 가능 - 상속성(Inheritance)
- Java에서는 단일 상속만 가능 - 부모클래스는 하나만 설정 가능
- 내꺼를 찾아보고 없다면 부모꺼 사용
- 주의) 속성이나 기능을 사용할 수 있어야 상속임..
5) 상속 시 주의
- 부모클래스의 생성자는 자식클래스에게 상속되지 않음
- 부모클래스의 은닉화 선언된(private) 필드 또는 메소드는 자식클래스에서 접근 불가능
- 자식클래스의 생성자로 객체를 생성할 경우, 부모클래스의 생성자가 먼저 호출되어 부모 클래스의 객체 생성 후 자식클래스의 객체 생성 왜? 부모클래스에 super매개변수가 존재하기 때문
1. [VO] inheritance > Member.java - (부모)
package inheritance;
//회원정보(아이디, 이름)를 저장하기 위한 클래스
public class Member {
private String id;
private String name;
public Member() {
// TODO Auto-generated constructor stub
}
public Member(String id, String name) {
super();
this.id = id;
this.name = name;
}
public String getId() {return id;}
public void setId(String id) {this.id = id;}
public String getName() {return name;}
public void setName(String name) {this.name = name;}
public void display() {
System.out.println("아이디 = "+id);
System.out.println("이름 = "+name);
}
}
[VO] inheritance > MemberEvent.java - (자식)
package inheritance;
//이벤트 관련 회원정보(아이디,이름,이메일)를 저장하기 위한 클래스
public class MemberEvent extends Member {
/*
//부모클래스(Member)을 상속받아 사용하므로 필드 미선언
private String id;
private String name;
*/
private String email;
public MemberEvent() {
//부모클래스의 기본 생성자 호출 - 부모클래스의 객체 생성
//super();//기본 생성자를 호출하는 명령은 생략 가능
}
//비권장
/*
public MemberEvent(String id, String name, String email) {
super();//기본생성자 호출
//자식클래스에서 필드 또는 메소드에 접근하는 순서
// => [1.자식클래스의 필드 또는 메소드 참조] 후 없는 경우 [2.부모클래스의 필드 또는 메소드 참조]
// => 부모클래스의 은닉화 선언된 필드 또는 메소드 접근 불가능
//this.id = id;
setId(id);
//this.name = name;
setName(name);
this.email = email;
}
*/
//권장
//[Alt]+[Shift]+[S] >> 팝업메뉴 >> [O] >> 부모클래스의 생성자 선택 >> 필드 선택 >> Generate
public MemberEvent(String id, String name, String email) {
//부모클래스의 매개변수가 선언된 생성자 호출
// => 부모클래스 객체에 원하는 초기값이 저장되도록 설정 - Setter 메소드 미호출
super(id, name);
this.email = email;
}
/*
//부모참조할 것이므로 생략 가능
public String getId() { return id;}
public void setId(String id) { this.id = id;}
public String getName() { return name;}
public void setName(String name) { this.name = name;}
*/
public String getEmail() {return email;}
public void setEmail(String email) {this.email = email;}
@Override
public void display() {
//super 키워드로 부모클래스의 숨겨진 메소드 호출
super.display();//아이디와 이름 출력
System.out.println("이메일 = "+email);
}
}
[실행] inheritance > MemberApp.java
package inheritance;
public class MemberApp {
public static void main(String[] args) {
Member member1=new Member();
member1.setId("abc123");
member1.setName("홍길동");
member1.display();
Member member2=new Member("xyz789", "임꺽정");
member2.display();
}
}
[실행] inheritance > MemberEventApp.java
package inheritance;
public class MemberEventApp {
public static void main(String[] args) {
//1.
//자식클래스(MemberEvent)의 생성자로 객체를 생성할 경우 부모클래스(Member)의 생성자가
//먼저 호출되어 부모클래스의 객체가 생성된 후 자식클래스의 객체 생성되어 상속 관계 성립
// => 자식클래스의 참조변수에는 자식 클래스의 객체 저장
MemberEvent member1=new MemberEvent();
//참조변수에 저장된 자식클래스의 객체를 참조하여 메소드 호출
// => 자식클래스 객체에 없는 메소드는 부모클래스의 객체를 참조하여 메소드 호출
member1.setId("abc123"); //부모참조
member1.setName("홍길동"); //부모참조
member1.setEmail("abc@itwill.xyz"); //자식참조
member1.display();
//아이디 = abc123
//이름 = 홍길동
//이메일 = abc@itwill.xyz
//2.
//자식클래스의 매개변수가 있는 생성자로 객체 생성
MemberEvent member2=new MemberEvent("xyz789", "임꺽정", "xyz@itwill.xyz");
member2.display();
//아이디 = xyz789
//이름 = 임꺽정
//이메일 = abc@itwill.xyz
//3.
//자식클래스의 매개변수가 있는 생성자로 객체 생성
//=> 매개변수가 없는 부모의 생성자를 불러오는 것이니 아래 처럼 객체 생성 가능함
MemberEvent member2 = new MemberEvent("abc@itwill.xyz");
member2.display();
//아이디 = null
//이름 = null
//이메일 = abc@itwill.xyz
}
}
반응형
'java > inheritance' 카테고리의 다른 글
[inheritance] 6. 학원인적자원관리 ERP프로그램 (AcademyApp) (2) | 2024.04.23 |
---|---|
[inheritance] 5. 메소드 오버라이드(Method override) (0) | 2024.04.22 |
[inheritance] 4. super키워드의 개념 (0) | 2024.04.21 |
[inheritance] 3. 참조변수와 객체와의 관계 (0) | 2024.04.21 |
[inheritance] 1. 객체 간의 관계 (2) | 2024.04.20 |