11. 새로운 클래스
11-1. 상속
이미 설계된 class를 바탕으로, 새로운 class를 만들 수 있도록!
- “class를 확장한다” (extend)
- 기존 class의 멤버를 “물려받아”, “새로운 필요한 성질/기능”을 추가한다!
용어
- 슈퍼 클래스 : 바탕이 되는 클래스
- 서브 클래스 : 새로운 클래스
클래스 확장하기
- 슈퍼 클래스 : Car
- 서브 클래스 : RacingCar
- 굳이 물려받은 멤버 따로 작성 필요 X
- Car에 없는 고유한 멤버만 추가하면 됨
- 아래의 ex) course 필드 & setCourse() 메소드
class RacingCar extends Car
{
// 추가되는 고유의 필드
private int course;
// 서브클래스의 생성자
public RacingCar()
{
course=0;
System.out.println("레이싱카 생성");
}
// 추가되는 고유의 메소드
public void setCourse(int c)
{
course = c;
System.out.println("코스 번호를"+course+"로 설정")
}
}
서브 클래스의 객체 생성
- 객체 생성 방식은 동일!
new
사용
class Sample1
{
public static void main(String[] args)
{
RacingCar rccar1;
rccar1 = new RacingCar();
rccar1.setCar(1234,10.5); // 상속받은 메소드
rccar1.setCourse(5); // 고유한 메소드
}
}
클래스의 기능
Java의 클래스가 가진 3가지 강점
- 상속
- 캡슐화
- 다형성
슈퍼 클래스의 생성자 호출
순서
- 1) 슈퍼 클래스의 생성자 호출
- 2) 서브 클래스의 생성자 호출
슈퍼클래스의 생성자는, 서브 클래스에게 상속 X.
( 대신, 슈퍼클래스의 “인수 없는” 생성자가 자동으로 호출됨 )
슈퍼 클래스의 생성자 지정 .. super()
BUT, 슈퍼 클래스가 “여러 개의 생성자”를 가질 수 있음
- 명시적으로 지정하기 위해서는?
super()
사용하기!
example)
class Car
{
public Car()
{
//중략
}
public Car(int n, double g)
{
//중략
}
}
class RacingCar extends Car
{
// [ 생성자 1 ]
public RacingCar()
{
course=0;
System.out.println("레이싱카 생성");
}
// [ 생성자 2 ]
public RacingCar(int n, double g, int c)
{
super(n,g); // 슈퍼클래스의 여러 생성자 중, 인자를 2개 받는 생성자 호출!
course = c;
System.out.println("코스번호가 "+cousre+"인 레이싱카 생성");
}
// 중략
}
class Sample
{
public static void main(String[] args)
{
// 서브 클래스의 여러 생성자 중, 인자를 3개 받는 생성자 호출!
RacingCar rccar1 = new RacingCar(1234,20.5,5);
}
}
this vs super
this
: 그 클래스의 다른 생성자 호출super
: 슈퍼 클래스의 생성자 호출
11-2. 멤버에 접근하기
서브 클래스 안에서 접근하기
클래스를 상속 받았을 때, 캡슐화가 어떻게 구현? ( private )
“서브 클래스 조차도” 접근 불가
접근하기 위해선, private 대신 protected 사용해야!
class Car
{
protected int num;
protected double gas;
// 생략
}
11-3. 오버라이딩
‘메소드’를 오버라이딩하기
슈퍼클래스와 “완전히 동일한 메소드”도 선언할 수 있음!
- 덮어쓰기! (overriding)
example
class Car
{
// 중략
// 슈퍼 클래스의 show() 메소드
public void show()
{
System.out.println("차량 번호는" +num);
System.out.println("연료 양은"+gas);
}
}
class RacingCar extends Car
{
// 중략
// 서브 클래스의 show() 메소드
public void show()
{
System.out.println("레이싱카 차량 변호는 "+num);
System.out.println("연료 양은"+gas);
System.out.println("코스 번호는"+course);
}
}
위와 같은 상황에서, show()
메소드를 호출하면
- “서브 클래스”의 show() 메소드가 호출된다
슈퍼 클래스의 변수로 객체 다루기
아래와 같이도 가능하다!
( 서브 클래스 객체가, 슈퍼 클래스의 객체이기도 하므로 )
Car car1;
car1 = new RacingCar();
위와 같은 상황에서, show()
메소드를 호출하면
-
마찬가지로 “서브 클래스”의 show() 메소드가 호출된다
( 객체를 가리키는 변수의 클래스와 상관 없이, 객체 자신의 클래스에 따라 적절한 메소드 수행! )
-
다만,
setCourse()
와 같은 서브 클래스의 고유 메소드는 이용 X
오버라이딩의 중요성
슈퍼 클래스의 배열 이용하기
class Sample6
{
public static void main(String[] args)
{
// 슈퍼클래스 array 생성
Car[] cars;
cars = new Car[2];
// (1) 슈퍼 클래스 객체 생성
cars[0] = new Car();
cars[0].setCar(1234,20.5);
// (2) 서브 클래스 객체 생성
cars[1] = new RacingCar();
cars[1].setCar(4567,30.5);
// (1),(2) 모두 동일한 슈퍼클래스 배열로 다룰 수 있다!
for(int i=0; i<cars.length; i++){
// (1)은 슈퍼 클래스의 show()메소드
// (2)는 서브 클래스의 show()메소드
cars[i].show();
}
}
}
오버라이딩 vs 오버로딩
오바리이딩
- 서브 클래스에서 이름/인수의 형/인수의 개수까지 모두 같은 슈퍼클래스의 메소드와 “동일한 메소드”를 정의해서 덮어쓰기
오버로딩
- 메소드의 이름은 같지만, 인수의형/인수의 개수가 다른 메소드를 정의하는 것
슈퍼 클래스와 같은 이름의 멤버 사용
- 앞에
super.
를 붙인 뒤 호출하면, 슈퍼클래스의 메소드를 호출! - 메소드 뿐만 아니라, 필드 앞에도 OK
메소드 ex)
class RacingCar extends Car
{
public void show()
{
// (선) 슈퍼 클래스의 show()
super.show();
// (후) 서브 클래스의 show()
System.out.println("코스 번호는"+course);
}
}
필드 ex)
class Car
{
int x;
...
}
class RacingCar extends Car
{
int x;
//...
public void show()
{
x=10; // 서브 클래스의 필드
super.x=20; // 슈퍼 클래스의 필드
}
}
final
메소드 이름 앞에 final
을 붙일 경우, 오버라이딩 불가
class Car
{
public final void show(){
// final을 붙였다
}
}
class RacingCar extends Car
{
// overriding 불가능!
//--------------------------------
/*public final void show()
{
}*/
//--------------------------------
}
서브 클래스 자체를 만들 수 없는 클래스를 설계해야 할 때!
final class Car
{
}
메소드, 클래스 뿐만 아니라, 필드 앞에 붙일수도 있다!
( = 상수(constant) )
class Car
{
static final int NUM_TIRE=4;
}
11-4. Object 클래스의 상속
-
Object = 모든 클래스의 근원이 되는 class
-
슈퍼 클래스 - 서브 클래스 - 서브 서브 클래스 - ….
-
하나의 클래스가 여러 슈퍼 클래스로부터 상속 받을 수 X
( then how…? “인터페이스” 사용하기! )
Object 클래스의 원리 이해하기
슈퍼 클래스를 지정하지 않으면, default로 Object class상속 받음
Object class의 주요 메소드
equals(Object obj)
getClass()
toString()
a) toString()
메소드
의미 : “객체를 나타내는 문자열을 반환”
- 객체의 내용 출력시, 이 메소드가 호출됨!
System.out.println(car1)
;- car1 출력 시, toString() 메소드가 호출됨
toString()
오버라이딩하기
class Car
{
// 중략
public String toString()
{
String str="차량 변호:"+num+"연료 양:"+gas;
return str;
}
}
class Sample
{
public static void main(String[] args)
{
Car car1=new Car();
car1.setCar(1234,20.5);
System.out.println(car1);
}
}
System.out.println(car1)
에서 반환되는 값
- Object의 toString()에 따라 ~ (X)
- Car의 toString()에 따라 ~ (O)
b) equals()
메소드
의미 : 두 변수가 가리키는 객체가 동일하면 True
- 여러 변수가 동일한 객체를 가리키는지 확인할 경우 유용
class Sample
{
public static void main(String[] args)
{
Car car1=new Car();
Car car2=new Car();
Car car3;
car3 = car1;
boolean b11=car1.equals(car2);
boolean b12=car1.equals(car3);
}
}
c) getClass()
메소드
의미 : 객체가 속한 클래스의 정보 반환
요약
- 슈버클래스를 바탕으로, “서브클래스를 확장 가능”
- 서브클래스는 슈퍼클래스의 멤버를 “상속받음”
- 서브 클래스는 슈퍼클래스의 “protected 멤버”에 접근 가능
- 오버라이딩 기능
- 아무 슈퍼클래스 지정 X 시, Object 클래스 상속