728x90
반응형
SMALL
상속이 없다면
- 상속이 없다면 서로 연관성이 있는 INSTANCE 두개를 선언해 주어야한다. 이는 코드의 재사용성이 전혀 없는 코드가 된다.
- 예제
public class Inherit01Main {
public static void main(String[] args) {
BasicTV tv1 = new BasicTV();
tv1.isPowerOn = true;
tv1.volume = 10;
tv1.channel = 5;
tv1.displayInfo();
SmartTV tv2 = new SmartTV();
tv2.isPowerOn = true;
tv2.channel = 123;
tv2.volume = 12;
tv2.ip = "192.168.0.111";
tv2.displayInfo();
System.out.println("\n프로그램 종료");
} // end main()
} // end class
- 위 예시를 보면 BasicTV 클래스와 SmartTV 는 함께 공유 될 수 있는 멤버 변수가 있고 연관성도 있지만 상속이 없다면 이러한 코드가 작성이 될 것이다.
상속
- 상속이란 상위클래스에서 하위클래스를 정의 하는 방법
- [class] 하위 클래스 extends 상위클래스 + 자바에서는 하나의 클래스만 상속받을 수 있음
- 상속의 이점은 기존의 객체를 그래도 사용하면서 새로운 객체에서 추가 및 변경 되는 부분만 작성함으로 소프트웨어 개발 효율을 높일 수 있다.
- 예제
public class BasicTV {
// 멤버 변수
boolean isPowerOn;
int channel;
int volume;
// 메소드
public void displayInfo() {
System.out.println("--- TV 현재 상태 ---");
System.out.println("전원: " + isPowerOn);
System.out.println("채널: " + channel);
System.out.println("볼륨: " + volume);
} // end displayInfo()
} // class BasicTV
public class SmartTV extends BasicTV{
String ip;
public void displayInfo(){
super.displayInfo(); // 부모(super) 의 displayInfo() 를 먼저 실행하고
System.out.println("IP 주소: " + ip);
}
}
// 구문
BasicTV tv1 = new BasicTV();
tv1.displayInfo();
System.out.println();
// SmartTV 클래스의 인스턴스 생성
SmartTV tv2 = new SmartTV();
tv2.isPowerOn = true;
tv2.channel = 123;
tv2.volume = 12;
tv2.ip = "192.169.0.110";
tv2.displayInfo();
- 실제 돌아가는 코드는 아님.
- displayInfo() 함수는 BasicTV에만 있었으나 SmartTV 가 BasicTV클래스로부터 상속 받고 있기 때문에 함수 사용 가능
상속과 생성자
- 자식 클래스의 생성자에서 명시적으로 부모클래스가 호출되어있지않으면 자동으로 부모클래스의 디폴트 생성자가 호출됨
- 이러한 이유로 자식 클래스의 생성자에서 명시적으로 부모 클래스의 생성자를 호출 하기도 함
- super([paramter]) 키워드를 사용하여 부모 클래스의 생성자를 호출
- super 함수는 항상 제일 처음에 호출 되어야함
- 부모 클래스에 디폴트 생성자가 없을 경우, 다른 생성자를 반드시 명시적으로 호출해줘야한다.
- 어떤 경우에 상속으로 객체를 설계 해야하는지 HONEY TIP
- HAS - A 관계 : 클래스 멤버로 설계
- car tire 가 있다면
- car has a tire
- IS - A 관계 : 상속으로 설계
- vehicle, car, hybrid car 가 있다면
- car is a vehicle
- hybrid car is a car
- vehicle, car, hybrid car 가 있다면
- HAS - A 관계 : 클래스 멤버로 설계
- 예제
public class Vehicle {
int speed;
public Vehicle(){
System.out.println("Vehicle() 생성");
}
public Vehicle(int speed) {
this.speed = speed;
System.out.println("Vehicle(int) 생성: speed = " + speed);
}
}
public class Car extends Vehicle{
int oil;
public Car(){
System.out.println("Car() 생성");
}
public Car(int oil){
// 명시적으로 부모 생성자 호출
super(54);
this.oil = oil;
System.out.println("Car(int) 생성 : oil = " + oil);
}
public Car(int speed, int oil){
super(speed);
this.oil = oil;
System.out.println("Car(int,int) 생성: speed=" + speed
+ "oil=" + oil);
}
}
public class HybridCar extends Car {
int electricity;
public HybridCar(){
System.out.println("HybridCar() 생성");
}
}
// Vehicle 클래스의 인스턴스 생성
Vehicle v1 = new Vehicle();
Vehicle v2 = new Vehicle(100);
System.out.println();
// Car 클래스의 인스턴스 생성
Car car1 = new Car();
System.out.println("speed: " + car1.speed);
System.out.println("oil: " + car1.oil);
Car car2 = new Car(400);
System.out.println();
// HybridCar 클래스의 인스턴스 생성
HybridCar car3 = new HybridCar();
상속과 접근 권한
- private : 자기 클래스에서만
- default : 자기 클래스 + 같은 패키지 안에서
- protected : 자기 클래스 + 같은 패키지 + 상속 관계 일 때
- public : 어디에서나
- 저번에 포스팅 했던 Modifier 참고하면 이해가 쉬울 것 같습니다.
- private < default < protected < public 을 순서로 더 큰 범위를 커버가 가능하고 이를 지키지 않고 상속했을 시 컴파일 에러가 나올 수 있습니다!
상속에서 메소드 재정의 (Overriding)
- 상속 관계에서 부모 클래스에 있던 메소드를 재정의 하는 것
- 부모 클래스에 있는 메소드와 매개변수 리스트가 동일 해야함
- 부모 클래스에 있는 메소드의 접근 권한 수식어가 동일할 필요는 없지만 범위를 축소시켜서는 안됨
- final : 더 이상의 오버라이딩 및 상속 불가 하게 만드는 Modifier
- 예제
public class Person {
// 멤버 변수
private String name;
// getter & setter
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
// 메소드
protected void showInfo() {
System.out.println("이름: " + name);
}
public final void whoAreYou(){
System.out.println("이름: " + name);
}
}
public class BusinessPerson extends Person {
private String company;
// getter & setter
public String getCompany() {
return company;
}
public void setCompany(String company) {
this.company = company;
}
// @Override
// protected void showInfo(){
// super.showInfo();
// System.out.println("회사: " + company);
// }
@Override
// void showInfo() { // (불가)
// private showInfo() { // (불가)
// protected void showInfo() { // (가능)
public void showInfo() { // (쌉가능)
super.showInfo();
System.out.println("회사: " + company);
}
public void showInfo(int id){ // 오버로딩!
}
@Override
public String toString() {
return String.format("[BusinessPerson: name=%s, company=%s]", getName(), company);
}
// @Override
// public void whoAreYou() {
// super.whoAreYou();
// }
}
Person p1 = new Person();
p1.setName("abc");
p1.showInfo();
System.out.println();
// BusinessPerson 클래스의 인스턴스를 생성
BusinessPerson p2 = new BusinessPerson();
p2.setName("이몽룡");
p2.setCompany("(주)조선");
p2.showInfo(); // BusinessPerson 에서 overriding 한 메소드 실행
System.out.println(p2); // p2.toString()
위 예제를 통해 Modifier (접근 제어자)가 더 좁은 범위에 있는 것들을 주석 처리 하였다 (이유는 컴파일 에러)
위 코드를 실행 시키면 Person 일 때, BussinessPerson 일 때, 같은 메소드를 사용하지만 다른 결과값을 가질 수 있다.
728x90
반응형
LIST
'프로그래밍 > 자바' 카테고리의 다른 글
[자바/기본] 예외처리 Exception (0) | 2023.10.13 |
---|---|
[자바/기본] 인터페이스 Interface + 추상 클래스 Abstract + 다형성 Polymorphism (0) | 2023.10.12 |
[자바/기본] Modifier 제어자 (0) | 2023.10.10 |
[자바 / 기본] Class란? (1) | 2023.10.07 |
[자바] 정올 189 ~ 194 && 215, 216, 237 : 문자열2 - 형성평가 1 ~ 9 (1) | 2023.10.04 |