package ex_super;
public class Ex1 {
public static void main(String[] args) {
/*
* 2. 생성자 super()
* - 서브클래스의 생성자에서는 묵시적으로 슈퍼클래스의 기본생성자를 자동으로 호출함
* => 이 때, 슈퍼클래스에 기본 생성자 없이, 파라미터 생성자만 존재할 경우
* 슈퍼클래스의 생성자에서 기본 생성자를 호출하면 오류 발생
* - 해결책1) 슈퍼클래스에 기본생성자를 명시적으로 정의
* - 해결책2) 슈퍼클래스의 파라미터 생성자를 명시적으로 호출
* => 생성자 super()를 통해 파라미터 생성자 호출 가능
* - 생성자 super()를 사용하여 슈퍼클래스 생성자를 호출하면
* 슈퍼클래스의 멤버변수는 슈퍼클래스가, 서브클래스의 멤버변수는 서브클래스가
* 초기화하게 되어, 초기화 코드 중복을 제거하게 됨
* => 생성자 this()와 사용 용도가 동일함
* - 생성자 this() 처럼 생성자 내의 첫번째 라인에서 호출 필수!
* => 따라서, 생성자 this()와 super()는 동시 사용 불가!
*/
Employee emp = new Employee("홍길동", 3000);
System.out.println(emp.getEmployee());
System.out.println("------------------------");
Manager man = new Manager("이순신", 4000, "개발1팀");
System.out.println(man.getEmployee());
}
}
class Employee {
String name;
int salary;
public Employee() {} // 기본생성자를 명시적으로 정의하면 문제 해결
public Employee(String name, int salary) {
this.name = name;
this.salary = salary;
}
// => 파라미터 생성자를 하나라도 정의할 경우
// 컴파일러에 의해 기본 생성자가 자동으로 정의되지 않는다!
// 이름, 연봉을 문자열로 결합하여 리턴 하는 getEmployee() 메서드 정의
public String getEmployee() {
return name + ", " + salary;
}
}
class Manager extends Employee {
String depart;
// String name;
/*
* 서브클래스의 생성자내에서는 묵시적으로 슈퍼클래스의 기본생성자를 자동으로
* 호출(super())하게 됨
* => 이 때, 슈퍼클래스에 기본 생성자 없이, 파라미터 생성자만 존재할 경우
* 슈퍼클래스의 생성자에서 기본 생성자를 호출하면 오류 발생하게 됨!
*/
public Manager(String name, int salary, String depart) {
// super(); // 슈퍼클래스의 기본 생성자를 호출하는 코드(자동으로 포함)
// System.out.println("Manager(String, int, String) 생성자 호출됨!");
super(name, salary);
// => 슈퍼클래스의 파라미터 생성자에서 멤버변수를 초기화하므로
// 서브클래스의 멤버변수만 직접 초기화하면 됨 => 코드 중복 제거
// this.name = name;
// this.salary = salary;
this.depart = depart;
}
// 이름, 연봉, 부서명을 문자열로 결합하여 리턴하는 getEmployee() 메서드 오버라이딩
@Override
public String getEmployee() {
return super.getEmployee() + ", " + depart;
// => name + ", " + salary + ", " + depart 동일
}
}
연습
package ex_super;
public class Test1 {
public static void main(String[] args) {
// Student 클래스의 인스턴스 생성
Student s = new Student("홍길동", 20, "901010-1111111", "아이티윌", "20200902");
s.getInfo();
System.out.println(s.getInfo());
s.getInfo2();
// System.out.println(s.getInfo2()); // 오류 발생!
// String str = s.getInfo2(); // 오류 발생!
}
}
/*
* Person 클래스 정의
* - 멤버변수 : 이름(name, 문자열), 나이(age, 정수), 주민번호(jumin, 문자열)
* - 생성자 : 이름, 나이, 주민번호를 전달받아 초기화
* - 메서드 : getInfo() 메서드
* => 이름, 나이, 주민번호를 문자열 결합 후 리턴
*
* Student 클래스 정의 => Person 클래스 상속
* - 멤버변수 : 학교명(schoolName, 문자열), 학번(schoolId, 문자열)
* - 생성자 : 이름, 나이, 주민번호, 학교명, 학번을 전달받아 초기화
* - 메서드 : getInfo() 메서드 오버라이딩
* => 이름, 나이, 주민번호, 학교명, 학번을 문자열로 결합 후 리턴
*
*/
class Person {
String name;
int age;
String jumin;
public Person() {}
public Person(String name, int age, String jumin) {
super(); // 슈퍼클래스 Object 의 기본생성자 호출 코드(생략 가능)
this.name = name;
this.age = age;
this.jumin = jumin;
}
// 이름, 나이, 주민번호를 문자열로 결합 후 리턴하는 getInfo() 메서드
public String getInfo() {
return name + ", " + age + ", " + jumin;
}
}
class Student extends Person {
String schoolName;
String schoolId;
// 파라미터 생성자 정의
public Student(String name, int age, String jumin, String schoolName, String schoolId) {
// 슈퍼클래스의 파라미터 생성자 호출하여 부모의 멤버변수를 대신 초기화
super(name, age, jumin);
// 서브클래스의 멤버변수만 직접 초기화
this.schoolName = schoolName;
this.schoolId = schoolId;
}
// getInfo() 메서드 오버라이딩
@Override
public String getInfo() {
// 슈퍼클래스의 getInfo() 메서드 호출을 위해서 super 키워드 사용!
// => 전달받아 자신의 멤버변수(schoolName, schoolId)를 결합하여 리턴
return super.getInfo() + ", " + schoolName + ", " + schoolId;
// super.멤버변수명 또는 this.멤버변수명 또는 멤버변수명을 사용하여
// 슈퍼클래스의 멤버변수를 직접 지정도 가능(효율적이지 않음)
// return name + ", " + age + ", " + jumin + ", " + schoolName + ", " + schoolId;
}
public void getInfo2() {}
}
package ex_super;
public class Test2 {
public static void main(String[] args) {
Child c = new Child();
System.out.println("x = " + c.getX());
// => getX() 메서드는 Parent 클래스에 정의된 것으로
// getX()에서 x는 Parent 클래스의 인스턴스 멤버 x를 의미
}
}
class Parent {
int x = 100;
Parent() {
this(200); // Parent(int x)를 호출
}
Parent(int x) {
// super(); // 슈퍼클래스(Object)의 기본 생성자를 호출하는 코드(자동으로 포함)
this.x = x; // Parent 클래스의 인스턴스 멤버 x -> 200으로 변경
}
int getX() {
return x;
}
}
class Child extends Parent {
int x = 3000;
Child() {
this(1000); // Child(int x)를 호출
}
Child(int x) {
// super(); // 슈퍼클래스의 기본 생성자를 호출하는 코드(자동으로 포함)
this.x = x; // Child 클래스의 인스턴스 멤버의 x -> 1000으로 변경
}
}