extends 키워드를 사용하여 두 개 이상의 클래스 간 상속 관계를 정의할 수 있다.super 와 super() 의 차이를 설명할 수 있다.기존의 클래스를 재활용해서 새로운 클래스를 작성하는 자바의 문법
이때 상속 관계에 있는 두 클래스를 상위 클래스, 하위 클래스라고 말한다.
하위 클래스는 상위 클래스가 가진 모든 멤버(필드, 메서드, 이너 클래스)를 상속 받는다.
따라서 하위 클래스의 멤버 개수는 상위 클래스보다 많거나 같고, "상위 클래스로부터 확장되었다!" 라는 표현을 쓴다.
extends 키워드를 사용
하위 클래스는 상위 클래스가 가진 모든 멤버(필드, 메서드, 이너 클래스)를 상속 받는다.
(하지만 상위 클래스의 생성자는 상속되지 않는다.)
하위 클래스의 멤버 개수는 항상 상위 클래스보다 많거나 같다.
단일 상속만을 허용 (다중 상속은 불가!)
=> 하지만 인터페이스를 통해서 다중 상속과 비슷한 효과가 일어나긴 한다.
상위 클래스의 접근 제어가 private이나 default로 설정된 멤버는 하위 클래스에서 상속받지만 접근할 수는 없습니다.
코드의 중복을 제거❓ 다형적 표현이란?
💁♀️ 하나의 객체가 여러 모양으로 표현될 수 있다는 것을 다형성이라고 한다.
클래스의 멤버로 다른 클래스의 참조 변수를 선언하는 것
(내부 클래스가 아닌 경우도 O)
public class Employee {
int id;
String name;
Address address;
public Employee(int id, String name, Address address) {
this.id = id;
this.name = name;
this.address = address;
}
void showInfo() {
System.out.println(id + " " + name);
System.out.println(address.city+ " " + address.country);
}
public static void main(String[] args) {
Address address1 = new Address("서울", "한국");
Address address2 = new Address("도쿄", "일본");
Employee e = new Employee(1, "김코딩", address1);
Employee e2 = new Employee(2, "박해커", address2);
e.showInfo();
e2.showInfo();
}
}
class Address {
String city, country;
public Address(String city, String country) {
this.city = city;
this.country = country;
}
}
Employee 클래스의 멤버로, Address 클래스의 참조변수가 존재한다.
상속: ~은 ~이다(IS-A) 포함: ~은 ~을 가지고 있다.(HAS-A)
상위 클래스로부터 상속받은 메서드를 재정의 하는 것
** Override = "덮어쓰다"
(2,3번은 몰랐던 내용이라 추가 학습이 필요할 것 같다!)
상위 클래스로부터 상속받은 메서드를 다른 방식으로 사용하기 위해서
ex) toString()
public class Main {
public static void main(String[] args) {
Bike bike = new Bike(); // 각각의 타입으로 선언 + 각각의 타입으로 객체 생성
Car car = new Car();
MotorBike motorBike = new MotorBike();
bike.run();
car.run();
motorBike.run();
Vehicle bike2 = new Bike(); // 상위 클래스 타입으로 선언 + 각각 타입으로 객체 생성
Vehicle car2 = new Car();
Vehicle motorBike2 = new MotorBike();
bike2.run();
car2.run();
motorBike2.run();
}
}
class Vehicle {
void run() {
System.out.println("Vehicle is running");
}
}
class Bike extends Vehicle {
void run() {
System.out.println("Bike is running");
}
}
class Car extends Vehicle {
void run() {
System.out.println("Car is running");
}
}
class MotorBike extends Vehicle {
void run() {
System.out.println("MotorBike is running");
}
}
// 출력값
Bike is running
Car is running
MotorBike is running
Bike is running
Car is running
MotorBike is running
아래 코드와 같이, 각 하위 클래스 객체를 상위 클래스 타입으로 선언하고 오버라이딩된 메서드를 호출하면 원본 메서드가 아닌, 각 하위 클래스에 재정의된 오버라이딩 메서드들이 호출된다.
Vehicle bike2 = new Bike(); // 상위 클래스 타입으로 선언 + 각각 타입으로 객체 생성
Vehicle car2 = new Car();
Vehicle motorBike2 = new MotorBike();
bike2.run();
car2.run();
motorBike2.run();
// 출력
Bike is running
Car is running
MotorBike is running
그러므로 여러 하위 클래스들의 객체를 모두 상위 클래스타입의 배열로 선언하면, 간편하게 이들을 관리할 수 있다.
Vehicle[] vehicles = new Vehicle[] { new Bike(), new Car(), new MotorBike()};
for (Vehicle vehicle : vehicles) {
vehicle.run();
}
super/super()의 관계는 이전에 배웠던 this/this()의 관계와 비슷하다.
this: 자신의 객체를 가리킴
this(): 자신의 생성자를 호출
super: 상위 클래스의 객체를 가리킴
super(): 상위 클래스의 생성자를 호출
public class Main {
public static void main(String[] args) {
Lower l = new Lower();
l.callNum();
}
}
class Upper {
int count = 20; // super.count
}
class Lower extends Upper {
int count = 15; // this.count
void callNum() {
System.out.println("count = " + count); // (this.)count
System.out.println("this.count = " + this.count);
System.out.println("super.count = " + super.count);
}
}
// 출력값
count = 15
this.count = 15
super.count = 20
✅
super나this키워드를 붙이지 않으면, 자신의 속한 인스턴스 객체의 멤버를 먼저 참조한다!
public class Main {
public static void main(String[] args) {
Student s = new Student();
}
}
class Human {
Human() {
System.out.println("휴먼 클래스 생성자");
}
}
class Student extends Human { // Human 클래스로부터 상속
Student() {
super(); // Human 클래스의 생성자 호출
System.out.println("학생 클래스 생성자");
}
}
super는 반드시 생성자 안에서만 사용 가능하다.this() 또는 super()가 선언되어야 한다.super()가 없는 경우에는, 컴파일러 생성자의 첫 줄에 자동으로 super()를 삽입한다.✅ 클래스를 만들 때는 기본 생성자를 생성하는 것을 꼭 습관화 하자!
자바의 최상위 클래스
➡️ 모든 클래스는 Object 클래스를 상속받는다.