💁♀️ Super 키워드(Super Keyword)란,
부모클래스의 인스턴스 주소를 보관하는 레퍼런스 변수인 super와 부모 생성자를 호출하는 구문인 super( )로 나뉨
- super
- 자식클래스 내의 모든 생성자와 메소드 내에서 부모클래스의 레퍼런스 변수를 사용할 수 있음
- super()
- 부모 생성자를 호출하는 구문으로 매개변수의 타입, 개수, 순서가 일치하는 부모의 생성자를 호출하게 됨
- this()는 해당 클래스의 생성자를 호출하는 구문
- super()는 부모 클래스가 가지는 private 생성자를 제외한 나머지 생성자를 호출하는 구문
public class Product {
// 필드(전역 변수)
private String code; >>> 상품코드
private String brand; >>> 제조사
private String name; >>> 상품명
private int price; >>> 가격
private Date menufacturingDate; >>> 제조일자
// 기본 생성자
public Product() {
super();
System.out.println("Product 클래스의 기본 생성자 호출");
}
// 모든 필드를 초기화 하는 생성자
>>> 객체를 생성할 때 생성자를 사용
>>> (초기화할 값이 있다면 객체 생성할 때 함께 초기화)
public Product(String code, String brand, String name, int price, Date menufacturingDate) {
super();
this.code = code;
this.brand = brand;
this.name = name;
this.price = price;
this.menufacturingDate = menufacturingDate;
System.out.println("Product 클래스의 매개변수가 있는 생성자 호출");
}
// getters & setters
>>> 하나의 필드값을 가져오거나 수정하는 용도 (생성자와 용도가 다름)
public String getCode() {
return code;
}
public void setCode(String code) {
this.code = code;
}
public String getBrand() {
return brand;
}
public void setBrand(String brand) {
this.brand = brand;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getPrice() {
return price;
}
public void setPrice(int price) {
this.price = price;
}
public Date getMenufacturingDate() {
return menufacturingDate;
}
public void setMenufacturingDate(Date menufacturingDate) {
this.menufacturingDate = menufacturingDate;
}
// 모든 필드 값을 문자열로 반환하는 메소드
public String getInformation() {
return "Product [code = " + code + ", brand = " + brand + ", name = " + name +
", price = " + price + ", menufacturingDate = " + menufacturingDate + "]";
}
}
>>> Computer는 하나의 Product임 (IS-A)
public class Computer extends Product {
// Computer만 가지는 추가적인 속성을 필드로 정의
private String cpu;
private int hdd;
private int ram;
private String operationSystem;
public Computer() {
super();
System.out.println("Computer 클래스의 기본 생성자 호출");
}
public Computer(String cpu, int hdd, int ram, String operationSystem) {
super();
this.cpu = cpu;
this.hdd = hdd;
this.ram = ram;
this.operationSystem = operationSystem;
System.out.println("Computer 클래스의 모든 필드를 초기화 하는 생성자 호출");
}
// 부모의 필드까지 모두 초기화 하는 생성자
public Computer(String code, String brand, String name, int price, Date manufacturingDate,
String cpu, int hdd, int ram, String operationSystem) {
// 부모 클래스의 모든 필드 초기화 매개변수 생성자 호출
super(code, brand, name, price, manufacturingDate);
// this(cpu, hdd, ram, operationSystem);
>>> 위와 같이 작성하면 this()로 다시 한번 생성자를 호출하게 되는 것인데
>>> 생성자를 두 번 호출하는 것은 허용되지 않음
>>> (이미 바로 위에서 super 생성자 호출함)
>>> => Constructor call must be the first statement in a constructor 오류
this.cpu = cpu;
this.hdd = hdd;
this.ram = ram;
this.operationSystem = operationSystem;
System.out.println("Computer 클래스의 부모 필드도 초기화 하는 생성자 호출");
}
// getter, setter
>>> 부모 필드의 메소드에 대해서는 자신의 멤버처럼 사용 가능하므로 따로 작성할 필요가 없음
>>> 자식 클래스에 추가된 필드에 대해서만 작성
public String getCpu() {
return cpu;
}
public void setCpu(String cpu) {
this.cpu = cpu;
}
public int getHdd() {
return hdd;
}
public void setHdd(int hdd) {
this.hdd = hdd;
}
public int getRam() {
return ram;
}
public void setRam(int ram) {
this.ram = ram;
}
public String getOperationSystem() {
return operationSystem;
}
public void setOperationSystem(String operationSystem) {
this.operationSystem = operationSystem;
}
// 모든 필드 값을 문자열로 반환하는 메소드
@Override
public String getInformation() {
>>> 부모 클래스에 작성한 getter를 이용해서 부모 필드가 가지고 있는 값도 한 번에 문자열로 합침
>>> 부모가 가진 멤버는 super.와 this. 둘 다 사용이 가능
>>> 하지만 코드의 의미를 명확히 하기위해 super. 을 사용
// return "Computer ["
// + "code = " + super.getCode()
>>> 간접접근 할 메소드명을 이용해야함
>>> (Product에 private으로 접근이 제한되어있으므로)
// + ", brand = " + super.getBrand()
// + ", name = " + super.getName()
// + ", price = " + super.getPrice()
// + ", manufacturingDate = " + super.getMenufacturingDate()
// + ", cpu = " + this.cpu
>>> Computer 클래스 내의 필드이므로 this. 사용
// + ", hdd = " + this.hdd
// + ", ram = " + this.ram
// + ", operationSystem = " + this.operationSystem
// + "]";
// 바로 위와 비슷한 결과인 코드 (출력 순서 조금 다름)
>>> 여기서는 super.대신 this.을 사용할 수 없음
>>> super.getInformation() : 정상적으로 부모의 메소드를 호출한다.
>>> this.getInformation() : 재귀 호출(자기 자신의 메소드를 다시 호출하는 것)이 일어나며 StackOverFlowError 발생
>>> getInformation() : this. 이 자동으로 추가되어 위와 동일하게 재귀 호출이 일어난다.
return super.getInformation()
>>> 부모의 클래스에서 참조할 것이라는 것을 분명히 해야함(super.)
+ "Computer ["
+ "cpu = " + this.cpu
+ ", hdd = " + this.hdd
+ ", ram = " + this.ram
+ ", operationSystem = " + this.operationSystem
+ "]";
}
}
public class Application {
public static void main(String[] args) {
// Product 기본 생성자로 인스턴스 생성 후 정보 출력
Product product1 = new Product();
System.out.println(product1.getInformation());
// Product 모든 필드 초기화 생성자로 인스턴스 생성 후 정보 출력
Product product2 = new Product("s-01234", "삼성", "갤럭시z폴드2", 2398000, new Date());
System.out.println(product2.getInformation());
// Computer 기본 생성자로 인스턴스 생성 후 정보 출력
Computer computer1 = new Computer();
System.out.println(computer1.getInformation());
// Computer의 모든 필드를 초기화하는 생성자로 인스턴스 생성 후 정보 출력
Computer computer2 = new Computer("퀼컴 스냅드래곤", 512, 12, "안드로이드");
System.out.println(computer2.getInformation());
// Computer의 모든 필드를 초기화하는 생성자로 인스턴스 생성 후 정보 출력
Computer computer3 = new Computer("s-01234", "삼성", "갤럭시z폴드2", 2398000, new Date(),
"퀼컴 스냅드래곤", 512, 12, "안드로이드");
System.out.println(computer3.getInformation());
}
}
💻 Mini Console
Product 클래스의 기본 생성자 호출
Product [code = null, brand = null, name = null, price = 0, menufacturingDate = null]
Product 클래스의 매개변수가 있는 생성자 호출
Product [code = s-01234, brand = 삼성, name = 갤럭시z폴드2, price = 2398000, menufacturingDate = Sun Jan 01 01:08:13 KST 2023]
Product 클래스의 기본 생성자 호출
Computer 클래스의 기본 생성자 호출
Product [code = null, brand = null, name = null, price = 0, menufacturingDate = null]Computer [cpu = null, hdd = 0, ram = 0, operationSystem = null]
Product 클래스의 기본 생성자 호출
Computer 클래스의 모든 필드를 초기화 하는 생성자 호출
Product [code = null, brand = null, name = null, price = 0, menufacturingDate = null]Computer [cpu = 퀼컴 스냅드래곤, hdd = 512, ram = 12, operationSystem = 안드로이드]
Product 클래스의 매개변수가 있는 생성자 호출
Computer 클래스의 부모 필드도 초기화 하는 생성자 호출
Product [code = s-01234, brand = 삼성, name = 갤럭시z폴드2, price = 2398000, menufacturingDate = Sun Jan 01 01:08:13 KST 2023]Computer [cpu = 퀼컴 스냅드래곤, hdd = 512, ram = 12, operationSystem = 안드로이드]