본문으로 바로가기

[JAVA] 상속 개념과 예제

category 4. 프로그래밍 기초/4_1 JAVA 2018. 12. 23. 09:50

    

 

상속이란? 기존의 클래스를 재사용해서 새로운 클래스를 작성하는것을 의미한다.

바탕이 되는 클래스 = 슈퍼 클래스
새로운 클래스        = 서브 클래스 

두 클래스는 슈퍼클래스와 서브클래스의 관계로 맺어지며 
서브클래스는 슈퍼클래스로부터 슈퍼클래스의 멤버(변수, 메서드)를 상속 받게된다.

class 서브 클래스 이름 extends 슈퍼 클래스 이름
{
	서브 클래스에 추가하는 멤버 ..
	서브 클래스의 생성자(인수 목록)
	{
		..
	}
}

 

서브 클래스를 선언할 때에는 extends 키워드 뒤에 슈퍼 클래스의 이름을 적는다.

생성자란?
- 인스턴스 변수의 초기화에 사용되는 일종의 메서드이다.
- 모든 클래슨느 반드시 한 개 이상의 생성자가 존재하여야 한다. 지금까지 생성자 없이 작업이 가능했      던 것은 컴파일 시 컴파일러가 자동으로 생성되던 기본 생성자는 사라진다.
- 객체를 생성할 때 쓰인다 하여, 생성자라는 이름이 붙은 것이다. 
  생성자는 객체를 실행 할 때 마다 생성된다.
- 생성자는 메모리를 차지하지 않으며, 인스턴스 변수의 초기화에 도움을 준다.
- 생성자는 오버로딩이 가능하다.

메서드와 생성자의 차이점
생성자는
- static을 붙일 수 없다.
- 리턴타입이 없다.
- 생성자명은 클래스명과 동일하게 작성한다.
- 인스턴스 메서드는 객체 생성 후 참조변수를 통해서만 호출이 되지만,
  생성자는 new를 통해서 객체를 생성할 때만 호출된다.

메서드와 생성자의 공통점
- 매개변수를 가질 수 있다.
- 오버로딩이 가능하다.

캡슐화(데이터 감추기)
데이터를 외부에서 함부로 변경하지 못하도록 외부의 접근을 제한하는 것을 말한다.

캡슐화 방법
1) 변수 앞에 접근 제어자 private를 붙인다.
2) private : 자기 클래스 내에서만 접근 할 수 있는 제어자 ex) private int num;
3) 변수에 값을 넣고, 값을 꺼내 올 수 있는 메서드를 만든다.
ex) public void setNumber(int n)
{
        number = n;
}
public int getNumber()
{
       return number;
}

 

그러면 다시 클래스로 넘어가서 코드를 살펴봅시다.

package practice;

class Car{
	protected int num; //private와는 다르게 서브클래스도 접근 가능.
	protected double gas;
	
	public Car(){
		num = 0;
		gas = 0.0;
		System.out.println("자동차가 생성되었습니다.");
	}
	
	public void setCar(int n, double g){
		num = n;
		gas = g;
		System.out.println("차량번호를 " + num + "으로, 연료양을" + gas + "로 바꾸었습니다.");
	}
	
	public void show(){
		System.out.println("차량번호는 " + num + "입니다.");
		System.out.println("연료양은 " + gas + "입니다.");
	}
	
}

class RacingCar extends Car{
	
	private int course;
	
	public RacingCar(){
		course = 0;
		System.out.println("레이싱카가 생성되었습니다.");
	}
	
	public void setRacingCar(int c){
		course = c;
		System.out.println("코스번호는 " + course + "입니다.");
	}
	
	public void show(){
		System.out.println("차량번호는 " + num + "입니다.");
		System.out.println("연료양은 " + gas + "입니다.");
		System.out.println("코스번호는 " + course + "입니다.");
	}
}
public class Practice04 {

	public static void main(String[] args) {

		Car c1 = new Car();
		c1.setCar(5, 10.3);
		c1.show();
		
	}

}

 

슈퍼클래스에서 protected는 private와는 다르게 서브 클래스가 접근할 수 있다. 


super()메서드
슈퍼클래스의 생성자를 호출 
super()를 사용하면 인수의 형과 개수가 일치하는 생성자가 호출됨.

this()메서드
자기자신을 가리키는 참조변수.
인스턴스변수와 지역변수의 이름이 같을 때 구별 용도로 사용됨.
또한, 그 클래스의 다른 생성자를 호출하는 용도

int num = 10; // 인스턴스 변수
void value(){
int num = 20; // 지역 변수
         System.out.println(num);  // 20
         System.out.println(this.num); // 10
}

 

오버라이딩
메소드의 이름과 인수의 개수 및 형(Type)이 완전히 같은 메소드가 서브 클래스와 슈퍼 클래스에 모두 정의되어 있는 겨우, 서브 클래스에서 새롭게 정의한 메소드가 호출되는 것.

하지만, 슈퍼클래스의 메소드 중에서는 서브 클래스에서 결코 오버라이딩되면 안 되는 메소드가 있을 수 있다. 이런 경우, 슈퍼클래스의 메소드 이름 앞에 final을 붙이면 오버라이딩을 막아줄 수 있다.

class Car
{
      public final void show()
      {
       ....
      }
}

 

final을 붙이면 서브 클래스에서 그 메소드를 오버라이딩 할 수 없게 된다.

final class Car
{ ... }

 

final을 붙인 클래스는 서브 클래스를 만들 수 없다.

class Car
{
    static final int NUM_TIRE = 4;
     ....
}

필드 이름 앞에 fInal을 붙이면 '이 필드의 값을 변경할 수 없음'이라는 뜻이 된다. (상수가 됨)

Object 클래스의 상속
자바에서는 슈퍼클래스를 지정하지 않으면 그 클래스는 Object클래스를 상속받는다.
class Car
{
 ....
}
// 아무것도 상속 받지 않으면 Object 클래스를 상속받는 서브 클래스가 된다.
Object 클래스의 주요 메소드
boolean equals(Object obj) : 해당 객체가 인수로 전달된 객체와 동일한지 여부를 반환
Class getClass()                    : 해당 객체의 클래스를 반환
String toString()                   : 객체를 나타내는 문자열을 반환

public String toString()
{
    String str = "차량번호 : " + num + "연료 양 : " + gas;
    return str;
}

main()
{
    Car c1 = new Car();
    System.out.println(c1); 
} 

 

Object 클래스의 toString() 메소드를 오버라이딩하면 객체를 나타내는 문자열을 변경할 수 있다.

Object 클래스의 equals() 메소드
두 변수가 가리키는 객체가 동일한 경우 true를 반환
두 변수가 가리키는 객체가 서로 다른 경우 false를 반환

		Car c1 = new Car();
		Car c2 = new Car();
		
		Car c3 = c1;
		
		boolean bl1 = c1.equals(c2);
		boolean bl2 = c1.equals(c3);
		
		System.out.println(bl1); //false
		System.out.println(bl2); //true

Object 클래스의 getClass()메소드
객체가 속한 클래스의 정보를 알 수 있다.

강의 요약
● 슈퍼 클래스를 바탕으로 서브 클래스를 확장할 수 있다.
● 서브 클래스는 슈퍼 클래스의 멤버를 상속 받는다.
● 서브 클래스는 슈퍼 클래스의 protected 멤버에 접근 할 수 있다.
● 서브 클래스에서 이름은 물론이거니와 인수의 형과 개수까지 슈퍼 클래스의 메소드와 동일한 메소드를 중복선언(오버라이딩)할 수 있다.
● 슈퍼 클래스를 지정하지 않은 클래스는 Object 클래스를 상속받는다.

 


문제1)
다음 코드의 실행결과를 예상해서 적어보자.

package practice;

class A
{
	A()
	{
		System.out.println("A의 인수 0의 생성자입니다.");
	}
	A(int a)
	{
		System.out.println("A의 인수 1의 생성자입니다.");
	}
}

class B extends A
{
	B()
	{
		System.out.println("B의 인수 0의 생성자입니다.");
	}
	B(int b)
	{
		super(b);
		System.out.println("B의 인수 1의 생성자입니다.");
	}
}

public class Practice06 {

	public static void main(String[] args) {
		B b1 = new B();
		B b2 = new B(10);
		
	}

}

 

문제2)
Car 클래스의 객체가 '차량번호 x 연료 양 y인 자동차' 라는 문구로 표현되도록 만들고 다음과 같이 출력하는 코드도 작성하자.

 

답:

package practice;

class Car
{
	protected int num;
	protected double gas;
	
	public Car()
	{
		num = 0;
		gas = 0.0;
		System.out.println("자동차가 만들어졌습니다.");
	}
	
	public void setCar(int n, double g)
	{
		num = n;
		gas = g;
		System.out.println("차량번호를 " + num + "으로" + ", 연료 양을 " +  gas + "로 바꾸었습니다.");
	}
	public String toString()
	{
		String str = "차량번호 : " + num + "연료 양" + gas + "인 자동차입니다.";
		return str;
	}
}

public class Practice07 {

	public static void main(String[] args) {

		Car c1 = new Car();
		c1.setCar(1234, 20.5);
		System.out.println(c1);

	}

}