반응형
[1] 상속
(1) 클래스 상속 inheritance
- 기존 클래스의 속성이나 기능을 상속받아 새로운 기능을 추가하거나 재정의 하여 새로운 클래스를 확장할때 사용한다
- 하위클래스는 상위클래스보다 더 구체적인 기능을 가져야한다
- 아예 다른 속성의 클래스를 상속하지는 않는다
- 상위 클래스 명칭 = parent class = base class = super class
- 하위 클래스 명칭 = child class= derived class =subclass
- 하위클래스의 생성자는 상위 클래스의 생성자를 호출한다. 왜냐하면 하위클래스는 상위클래스의 속성을 받았기 때문에
- 하위 클래스는 모든 멤버를 상속받는다. 하지만 생성자와 초기화 블럭은 상속되지 않는다
IS-A 관계 : 상속 O |
HAS-A 관계 : 상속 X |
is a relationship : inheritance 상위 클래스 : 일반적인 개념 (먹는다) 하위 클래스 : 구체적인 개념 (고기를먹는다 , 야채를 먹는다 ) 상위클래스와 하위클래스 사이에 관계가 성립되는 형태 상위 클래스의 수정이 많은 하위 클래스에 영향을 미칠 수 있다 계층구조가 복잡하거나 hierarchy가 높으면 좋지 않음 |
composition 클래스가 다른 클래스를 포함하는 관계 ( 변수로 선언 ) 코드 재사용의 가장 일반적인 방법 서로 상속하지 않는다 주문-배송 같은 연계는 되어있지만 직접적인 속성은 아닌 애매한 관계? |
(2) 상속 적용하기 extends
- class 상속받는 클래스 extends 상속해주는 클래스 1개
package 패키지;
public class VIPCustomer extends Customer {
double salesRatio;
String agentId;
public VIPCustomer() {
coustomerGrade ="VIP";
bonusRatio = 0.05;
salesRatio = 0.1;
}
public String getAgentId() {
return agentId;
}
public void setAgentId(String agentId) {
this.agentId = agentId;
}
}
(3) 단일상속 single inheritance
JAVA | C++ | |
상속 | 단일상속 | 다중상속 |
장점 | 클래스 간의 관계가 명확하고 코드가 신뢰가 가능하다 | 여러 클래스로부터 상속받을수 있어 복합적인 기능을 가진 클래스를 쉽게 작성할수 있다 |
단점 | 복합적인 기능을 가진 클래스 관리를 포기한다 | 클래스간의 관계가 복잡해진다 다른 클래스로부터 상속받은 멤버간의 이름이 같으면 구별이 어렵다 |
(4) 상속의 접근제어자
- 상위 클래스에 선언된 private 멤버 변수는 하위 클래스에서 접근 할 수 없음
- 외부 클래스는 접근 할 수 없지만, 하위 클래스는 접근 할 수 있도록 protected 접근 제어자를 사용
(5) 상속 구현 예시
회사에서 고객 정보를 활용한 맞춤 서비스를 하기 위해
일반고객(Customer)과 우수고객(VIPCustomer)에 따른 서비스를 제공하고자 함
물품을 구매 할때 적용되는 할인율과
적립되는 보너스 포인트의 비율이 다르다
여러 멤버십에 대한 각각 다양한 서비스를 제공할 수 있음
멤버십에 대한 구현을 클래스 상속을 활용하여 구현해보기
- Customer 일반 고객 클래스
- 넓은 범위의 고객
- 상위 클래스
package ch02;
public class Customer {
protected int customerId;
protected String customerName;
protected String coustomerGrade;
int bonusPoint;
double bonusRatio; // 적립비율
public Customer() {
coustomerGrade ="SILVER";
bonusRatio = 0.01;
}
public int calcPrice(int price) {
bonusPoint += price * bonusRatio;
return price;
}
//캡슐화
public int getCustomerId() {
return customerId;
}
public void setCustomerId(int customerId) {
this.customerId = customerId;
}
public String getCustomerName() {
return customerName;
}
public void setCustomerName(String customerName) {
this.customerName = customerName;
}
public String getCoustomerGrade() {
return coustomerGrade;
}
public void setCoustomerGrade(String coustomerGrade) {
this.coustomerGrade = coustomerGrade;
}
public String showCustomerInfo() {
return customerName +"님의 등급은 "+coustomerGrade + " 이고 , 보너스 포인트는 "+bonusPoint +"입니다 ";
}
}
- VIP 고객 클래스
- 작은 범위의 고객
- 하위 클래스
- 상위클래스에 구현된 기능을 제외한 vip 고객에만 해당하는 기능을 넣는다
package ch02;
public class VIPCustomer extends Customer {
double salesRatio;
String agentId;
public VIPCustomer() {
coustomerGrade ="VIP";
bonusRatio = 0.05;
salesRatio = 0.1;
}
public String getAgentId() {
return agentId;
}
public void setAgentId(String agentId) {
this.agentId = agentId;
}
}
- 본 main 클래스
- 실제 고객의 정보를 입력한다
package ch02;
public class Service {
public static void main(String[] args) {
Customer customerA = new Customer();
customerA.setCustomerName("이순신 ");
customerA.setCustomerId(10010);
customerA.bonusPoint=1000;
System.out.println(customerA.showCustomerInfo());
VIPCustomer customerB = new VIPCustomer();
customerB.setCustomerName("김유신 ");
customerB.setCustomerId(10020);
customerB.bonusPoint = 10000;
System.out.println(customerB.showCustomerInfo());
}
}
(6) 상속 & 인스턴스 객체 메모리
- 상위클래스 인스턴스 생성 후 하위 클래스 인스턴스가 생성된다
[2] Super
현재 클래스의 부모클래스의 멤버변수나 메서드를 접근할때 사용한다
(1) super 참조변수
- 상위 클래스와 하위 클래스의 멤버이름이 같고, 상위 클래스의 멤버를 참조하는데 사용된다
- 만약에 x의 값이 같다면 this.x 와 super.x 의 값은 같다
- super는 생성된 상위 클래스 인스턴스의 참조 값을 가진다
(2) super() 생성자 호출
- 상위클래스의 생성자를 호출한다
- 상위 클래스에 기본생성자가 있고 , 하위 클래스에서 상위 클래스의 생성자를 호출하지 않으면 super()가 자동으로 호출 된다
- 상위 클래스에 기본 생성자가 없고 다른 생성자가 있는 경우 ,하위 클래스 생성자가 super() 자동으로 호출 하여 상위클래스의 생성자를 호출한다
(2) 상속 & super & this 사용
class Person {
String name;
int age;
public int a1;
private int a2; // 상속은 받았지만 다른 클래스라서 불러오기 불가
Person() {}
Person(String name, int age) {
this.name =name;
this.age =age;
}
public void printInfo() {
System.out.println(name);
System.out.println(age);
}
}
class Student extends Person { // 상속
Student() {
a1 =1;
}
class Stuenst2 extends Person {
String name;
int stdId;
Stuenst2 (String name, int age, int stdId) {
this.name = name; // 바로 위의 Student2 의 name 을 가져오느라 this
super.name = name ; // 바로위 this가 아닌 student의 name 가져옴
super(name,age); // this가 아닌 student 의 name 과 age를 가져옴
this.age =age;
this.stdId =stdId;
}
}
public class Main {
public static void main(String[] args) {
Student s1 = new Student();
s1.name ="a";
s1.age = 25;
s1.printInfo();
Student s2 = new Student("b",32,1);
s2.printInfo();
}
}
(3) 상위클래스에 기본생성자 있을때 super 참조변수로 사용
- 상위클래스에 기본생성자 있고 , 하위 클래스에 super가 자동으로 호출하여 상위클래스 생성자를 호출한다
- Customer 상위 클래스
package 패키지 ;
public class Customer {
protected int customerId;
protected String customerName;
protected String customerGrade;
int bonusPoint;
double bonusRatio; // 적립비율
public int calcPrice(int price) {
bonusPoint += price * bonusRatio;
return price;
}
//상위 클래스 생성자
public Customer() {
this.customerId =customerId;
this.customerName = customerName;
customerGrade = " Siver ";
bonusRatio = 0.01;
}
public int getCustomerId() {
return customerId;
}
public void setCustomerId(int customerId) {
this.customerId = customerId;
}
public String getCustomerName() {
return customerName;
}
public void setCustomerName(String customerName) {
this.customerName = customerName;
}
public String getCoustomerGrade() {
return customerGrade;
}
public void setCoustomerGrade(String coustomerGrade) {
this.customerGrade = coustomerGrade;
}
public String showCustomerInfo() {
return customerName +"님의 등급은 "+customerGrade + " 이고 , 보너스 포인트는 "+bonusPoint +"입니다 ";
}
}
VIPCustomer 하위 클래스
package 패키지;
public class VIPCustomer extends Customer {
double salesRatio;
String agentId;
public VIPCustomer() {
//super(); 컴파일러가 자동으로 상위클래스를 호출한다
customerGrade ="VIP";
bonusRatio = 0.05;
salesRatio = 0.1;
System.out.println("VIPCustomer() call");
}
public String getAgentId() {
return agentId;
}
public void setAgentId(String agentId) {
this.agentId = agentId;
}
}
실행 클래스
package ch03;
public class Service {
public static void main(String[] args) {
VIPCustomer customerB = new VIPCustomer();
customerB.setCustomerName("김유신 ");
customerB.setCustomerId(10020);
customerB.bonusPoint = 10000;
System.out.println(customerB.showCustomerInfo());
}
}
(4) 상위클래스에 기본생성자 없을때 super 참조변수로 사용
- 상위 클래스에 기본생성자가 아닌 매개변수가 있는 다른생성자가 있다면 하위클래스에서 super(매개변수)를 통해 호출한다
- Customer 상위 클래스
package 패키지 ;
public class Customer {
protected int customerId;
protected String customerName;
protected String customerGrade;
int bonusPoint;
double bonusRatio; // 적립비율
public int calcPrice(int price) {
bonusPoint += price * bonusRatio;
return price;
}
// 디폴트 생성자 없애고 매개 변수가 있는 생성자 추가
public Customer(int customerID, String customerName) {
this.customerID = customerID;
this.customerName = customerName;
customerGrade = "SILVER";
bonusRatio = 0.01;
System.out.println("Customer(int, String) 생성자 호출");
}
public int getCustomerId() {
return customerId;
}
public void setCustomerId(int customerId) {
this.customerId = customerId;
}
public String getCustomerName() {
return customerName;
}
public void setCustomerName(String customerName) {
this.customerName = customerName;
}
public String getCoustomerGrade() {
return customerGrade;
}
public void setCoustomerGrade(String coustomerGrade) {
this.customerGrade = coustomerGrade;
}
public String showCustomerInfo() {
return customerName +"님의 등급은 "+customerGrade + " 이고 , 보너스 포인트는 "+bonusPoint +"입니다 ";
}
}
VIPCustomer 하위 클래스
package 패키지;
public class VIPCustomer extends Customer {
double salesRatio;
String agentId;
// super를 이용하여 상위 클래스의 생성자 명시적으로 호출
public VIPCustomer(int customerID, String customerName) {
super(customerID, customerName);
customerGrade = "VIP";
bonusRatio = 0.05;
salesRatio = 0.1;
System.out.println("VIPCustomer(int, String) 생성자 호출");
}
public String getAgentId() {
return agentId;
}
public void setAgentId(String agentId) {
this.agentId = agentId;
}
}
실행 클래스
public class CustomerTest {
public static void main(String[] args) {
Customer customerLee = new Customer(10010, "이순신");
customerLee.bonusPoint = 1000;
System.out.println(customerLee.showCustomerInfo());
VIPCustomer customerKim = new VIPCustomer(10020, "김유신");
customerKim.bonusPoint = 10000;
System.out.println(customerKim.showCustomerInfo());
}
}
반응형
'🌈 백엔드 > 객체 지향' 카테고리의 다른 글
JAVA_객체지향_다형성 & 업캐스팅 & 다운캐스팅 (0) | 2023.06.18 |
---|---|
JAVA_객체지향_오버로딩 & 오버라이딩 (0) | 2023.06.18 |
JAVA_객체지향_디자인 > 템플릿 메서드 패턴 (0) | 2023.06.03 |
JAVA_객체지향_디자인 > 싱글톤 패턴 (0) | 2023.06.03 |
JAVA_객체지향_this (0) | 2023.06.03 |
댓글