본문 바로가기

IT

11-1. 자바 - 상속, 오버라이딩, 오버로딩

객체지향 프로그램(OOP)의 핵심 3가지

- 은닉 Encapsulation

- 상속 Inheritance

- 다형성 polymorphism

 

상속(Inheritance) : extends

  •  OOP에서 상속은 기존의 클래스를 확장하여 새로운 클래스를 이끌어내는 것을 의미한다.
  •  상속 관계는 is a 관계를 만족한느 관계이다.   ex) 돌고래 is a 포유류 --> 돌고래는 포유류의 속성을 가지고 있다.
  •  상속은 기존의 코드를 재사용함으로써 불필요한 코드를 재작성하는 번거로움을 없앨 수 있고, 새로운 클래스를 만드는 시간과 노력을 줄일 수 있다.
  •  자바에서는 C++에서 사용했던 다중상속의 문제점(데이터 꼬임이 발생됨)때문에 단일상속만을 지원합니다 (부모가 둘(x), 하나의 부모가 여러자식(O)).
  •  어떤 클래스가 다른 클래스로부터 상속을 받아 만들어지면 새롭게 만들어진 클래스를 자식(child or sub)클래스라고 부르며, 멤버변수와 메서드를 물려준 클래스는 부모(parent or super) 클래스라고 부른다.
  •  상속을 하면 부모클래스의 멤버변수와 메서드가 자식클래스에 상속이 된다. 그러나 부모클래스의 생성자는 상속이 되지 않는다.
  •  상속을 사용하는 키워드는 extends이다.
  • 상속을 하더라도 부모 클래스에서 private 접근제한을 갖는 멤버변수와 메스드는 상속대상에서 제외된다.
  • -자바의 모든 클래스는 Obtect클래스를 상속받고있다. Obtect클래스는 자바의 취상의 클래스다.

 


Superclass를 통해 상속 extends를 바로 삽입할 수 있다.






 


상속 실습

 

부모 클래스 Person.java

package inherit.goodcase;

/*
 * 데이터를 다른 클래스에게 물려주는 클래스를 부모클래스라고 합니다.
 * 상속을 사용할 시 데이터를 물려받는 클래스에게 부모클래스의 멤버변수, 메서드가 상속됩니다.
 * 단, 생성자는 상속되는 않습니다. 
 */
public class Person {
	
	String name;
	int age;
	
	String info() {
		return "이름: " + name + ", 나이: " + age;
	}
}

 

자식 클래스1. Employee.java

package inherit.goodcase;

public class Employee extends Person{	
	String department;	
}

자식 클래스2. student.java

package inherit.goodcase;
/*
 * 다른 클래스로부터 멤버변수와 메서드 물려받는 클래스는 자식클래스라고 부른다. 
 * 자식 클래스의 이름 뒤에 extends라는 키워드를 쓰고 물려받으 클래스의 이름을 써준다.
 * 
 */
public class student extends Person {
	String stuID;
}

 

MainClass.java

package inherit.goodcase;

public class MainClass {

	public static void main(String[] args) {
		
		Person hong = new Person();
		hong.name = "홍길동";
		hong.age = 45;
		System.out.println(hong.info());
		
		student lee = new student();
		lee.stuID = "2018110033";
		lee.name = "이순신";
		lee.age = 23;
		System.out.println(lee.info());
		
		Employee shin = new Employee();
		shin.department = "구매부";
		shin.age = 33;
		shin.name = "신사임당";
		System.out.println(shin.info());
		
	}
}
---------------결과---------------
이름: 홍길동, 나이: 45
이름: 이순신, 나이: 23
이름: 신사임당, 나이: 33

Person.java의 클래스를 상속받은   Employee.java  student.java의 클래스는 변수를 가지고 있지 않아도 MainClass.java에서 잘 출력됨을 확인할 수 있다.

 


* 메서드 재정의(오버라이딩_Overriding) 

  • 메서드 재정의(오버라이딩)란 부모클래스로부터 상속받은 메서드를 자식클래스에서 행위를 바꾸거나 보완하기 위해 다시 정의해서 사용하는 것을 말한다.
  • 이는 부모클래스에서 특별한 용도로 사용하던 메서드를 자식 클래스에서 다른 용도로 사용할 때 필요하다.
  • 부모클래스의 모든 메서드가 자식클래스에 맞게 설계되어 있다면 가장 이상적인 상속이지만, 특정 메서드는 자식 클래스가 사용하기에 적합하지 않을 수도 있다.
  • 메서드가 자식클래스에서 재정의되었다면 자식객체를 통해 메서드를 호출했을 때 새롭게 재정의된 메서드가 호출된다.

 메서드 재정의 규칙

  1. 반드시 상속을 전제로 해야한다.
  2. 반드시 반환 유형이 같아야한다.
  3. 메서드 이름이 같아야한다.
  4. 매개 변수 선언이 정확히 일치해야 한다.
  5. 접근제한자는 같거나 더 제한이 없어야한다. (more public)

Parrent.java 부모클래스

package overriding.basic;

public class Parrent {
	
	void method1() {
		System.out.println("부모의 1번 메서드 호출!");
	}	
	void method2() {
		System.out.println("부모의 2번 메서드 호출!");	
	}
}

Chile.java  자식클래스

package overriding.basic;

public class Child extends Parrent {
	/*
	 * 메서드 재정의(overriding)
	 * 부모클래스가 물려준 메서드를 자식 클래스에서 블록 내부만 바꿔서 사용하는것.
	 */
	void method2() { //접근제한자란 public이다.
		System.out.println("재정의된 자식의 2번 메서드 호출!");
	}
	
	void method3() {
		System.out.println("자식의 3번 메서드 호출!");
	}
}

MainClass.java

package overriding.basic;

public class MainClass {

	public static void main(String[] args) {
		
		Parrent p = new Parrent();
		p.method1();
		p.method2();
		
		System.out.println("-------------------");
		Child c = new Child();
		c.method1(); 
		c.method2(); // 메서드 재정의로 인해 Parrent의 2가 아닌 chile의 2가 출력된다.
		c.method3();
	}
}
----------------결과 ----------------
부모의 1번 메서드 호출!
부모의 2번 메서드 호출!
-------------------
부모의 1번 메서드 호출!
재정의된 자식의 2번 메서드 호출!
자식의 3번 메서드 호출!

* 중복 (오버로딩_Overloading)

자바는 메서드와 생성자의 중복 선언을 허용한다.

중복은 메서드 또는 생성자를 선언할 때 이름은 같지만 매개 변수의 유형이나 개수를 다르게 선언해 놓는 것을 의미한다.

 

Basic.java

package overloading.basic;

/*
 * 오버로딩(중복)
 * 하나의 클래스 내부에 같은 이름을 가진 메서드를 여러 개 선언할 수 있게 하는 문법
 * 1. 매개 변수의 데이터 타입이 달라야한다.
 * 2. 매개 변수의 순서가 달라야 함.
 * 3. 매개 변수의 개수가 달라야 함.
 * 
 * 
 *******오버로딩 되는지 않되는치 확인법.********
 *input(String): 메서드이름, 매개변수 타입을 썻을때 적용이 안되면 오버로딩이 안되는거다
 */
public class Basic {

	void input(int a) {
		System.out.println("정수 1개가 입력됨.");
	}
	 	
	//void input(int i) {  애러 발생 오버로딩 불가능
	//	System.out.println("정수 1개가 입력됨.");
		
	//input(int, int) // 매개변수개수가 달라서 오버로딩 가능 
		void input(int a, int b) {
			System.out.println("정수 2개가 입력됨");
		}
	//input(String, double)
		void input(String s, double d) { //데이터타입과 개수가 달라서 가능
			System.out.println("문자열 1개와 실수 1개가 입력됨.");		
	}
		
		void input(double x, String y) { //매개변수 순서가 달라서 가능
			System.out.println("실수 1개와 문자열 1개가 입력됨.");
		}	
}

 

MainClass.java

package overloading.basic;

public class MainClass {

	public static void main(String[] args) {
		
		Basic b = new Basic();
		b.input(5);  //정수 1개가 입력됨.
		b.input(5,10);  //정수 2개가 입력됨
		b.input(3.14, "허허"); //실수 1개와 문자열 1개가 입력됨.
	}
}