부모 class가 가지는 내용을 확장해서 자식 class를 만드는 방식을 말한다.
기존 class를 확장해서 새로운 class를 정의하는 것이다.
ex. 학사시스템
아래와 같은 3개의 class가 있다.
- class Teacher
- class Student
- class Staff
package lecture0712; class Person{ String name; // 이름 String mobile; // 전화번호 } //tigthly coupled class Student extends Person{ String dept; // 학과 } class Teacher extends Person{ String subject; // 담당과목 } class Staff extends Person{ int salary; // 월급 }
class Student extends Person, Human {
// Java는 다중상속 X
}
- constructor는 상속되지 않는다.
- 접근제어자 private로 지정된 field, method도 상속되지 않는다.
(해당 클래스 내에서만 사용 가능)
package lecture0712;
// Java에선 Object class가 최상위(Object 생략가능)
class Person extends Object{
String name; // 이름
String mobile; // 전화번호
}
class Student extends Person{
String dept; // 학과
}
public class Main {
public static void main(String[] args) {
Student s = new Student();
}
}
public class Main {
public static void main(String[] args) {
// Person p = new Person();
// Student s = new Student();
// Person s = new Student();
// Object s = new Student();
// is-a relationship
// subclass is a superclass
}
}
/* super을 이용해서 상위 constructor을 호출한다 */
package lecture0712;
// Java에선 Object class가 최상위(Object 생략가능)
class Person extends Object{
public Person(){
super();
}
String name; // 이름
String mobile; // 전화번호
}
class Student extends Person{
public Student() {
super(); // 상위 클래스의 생성자 호출 (자동으로 삽입됨)
}
String dept; // 학과
}
public class Main {
public static void main(String[] args) {
// Person p = new Person();
Student s = new Student();
// Person s = new Student();
// Object s = new Student();
// is-a relationship
// subclass is a superclass
}
}
/* super를 호출할 땐 형태를 일치시켜줘야 한다 */
class Person extends Object{
public Person(String name) {
this.name = name;
}
String name; // 이름
String mobile; // 전화번호
}
class Student extends Person{
public Student() {
super("홍길동"); // 상위 클래스의 생성자 호출, 형태를 맞춰줘야한다.
}
String dept; // 학과
}
package lecture0712;
// Java에선 Object class가 최상위(Object 생략가능)
class Person extends Object{
String name; // 이름
String mobile; // 전화번호
public void printAll() {
System.out.println("모두 출력!!");
}
}
class Student extends Person{
String name; // 필드 재정의 (오버라이딩X) - 일반적이지 않아요!(권장X)
String dept; // 학과
public void printAll() {
System.out.println("오버라이딩");
}
}
public class Main {
public static void main(String[] args) {
Student s = new Student();
}
}
class Student extends Person{
String dept; // 학과
// default constructor
public Student() {
this("홍길동"); // 현재 자신이 가지고 있는 생성자의 다른 생성자 호출
}
public Student(String name) {
this.name = name; // 여기 안으로 들어감
}
}
객체에 대한 type이 상위 타입이라 할지라도
만약 오버라이딩된 메소드가 하위에 존재한다면
메소드는 오버라이딩된 메소드를 사용한다.
package lecture0712;
class Superclass{
// static method
static int staticCall(String msg) {
System.out.println(msg);
return 100;
}
//fields
int a = staticCall("1번입니다.");
static int b = staticCall("2번입니다.");
//constructors
public Superclass() {
staticCall("3번입니다.");
}
public Superclass(int i) {
this();
staticCall("4번입니다.");
}
// method
public void myFunc() {
System.out.println("5번입니다.");
}
}
public class InheritanceTest extends Superclass{
// fields
int c = staticCall("6번입니다.");
static int d = staticCall("7번입니다.");
// constructor
public InheritanceTest() {
super(100);
staticCall("8번입니다.");
super.myFunc();
}
@Override
public void myFunc() {
System.out.println("9번입니다.");
}
public static void main(String[] args) {
System.out.println("10번입니다.");
Superclass obj = new InheritanceTest();
obj.myFunc();
// 객체에 대한 type이 상위 타입이라 할지라도
// 만약 오버라이딩된 메소드가 하위에 존재한다면
// 메소드는 오버라이딩된 메소드를 사용한다
// 동적 바인딩 (dynamic binding)
}
}
순서 : 2 -> 7 -> 10 -> 1 -> 3 -> 4 -> 6 -> 8 -> 5 -> 9
1. public class인 inheritance class를 먼저 시작
2. inheritance class를 method area에 올리기 전에 Superclass가 먼저 method area에 올라가게 된다.
3. static으로 지정된 b가 method area에 공간이 만들어진다.
4. staticCall이 호출되면서 "2번입니다." 출력
5. inheritance에 대한 정보를 method area에 올린다.
6. static으로 지정된 d의 공간이 생기면서 "7번입니다." 출력
7. main method부터 시작된다.
8. "10번입니다." 출력
9. 인자가 없는 생성자를 호출하게 된다.
10. super의 constructor에 인자를 받는 부분을 호출한다.
11. this(); 내가 가지고 있는 다른 constructor 호출한다.
11. 생성자 부분을 호출하기 직전에 인스턴스 variable 객체가 먼저 생성되어야 한다. "1번입니다." 출력
12. 생성자에 대한 초기화 "3번입니다."
13. "4번입니다." 출력
14. IneritanceTest() 생성 전에 필드 호출 "6번입니다."
15. "8번입니다." 출력
16. super.myFunc() "5번입니다." 출력
17. myFunc() "9번입니다." 출력
final int k = 100;
final class A {}
final void kk(){}
기능적인 이름을 통일하기 위해서 사용한다.
기능적으로 추상메서드로 통일하고 하위 클래스에서 메소드를 재정의한다.
package lecture0712;
// 추상클래스(abstract class)
public abstract class UpperClass {
// fields
String name;
int age;
// method
public abstract void printAll(); // abstract method (해당 메소드 앞에 abstract 키워드 붙임)
}
class subClass extends UpperClass{
// 추상 메소드를 사용하기 위해서 재정의하면 된다(오버라이딩)
@Override
public void printAll() {
// TODO Auto-generated method stub
}
}
추상 class의 아주 특별한 형태를 말한다.
- 모든 method가 추상method다.
- 모든 field는 public static final로 구성되어 있다.
안에 들어간 field는 전부 상수이다.- 인터페이스는 다중구현이 가능하다.
package lecture0712;
interface myInterface{
// fields
// public static final은 자동적으로 설정(안써줘도 자동설정)
int kk = 0;
String aa = "Hello";
// methods
public abstract void printAll();
public abstract void myPrint();
}
// 인터페이스를 구현해서 MyClass2를 정의한다는 뜻 (상위 클래스 개념으로 사용함)
// 내가 구현할 해당 인터페이스들을 모두 오버라이딩 해줘야 한다.
public class MyClass2 implements myInterface {
@Override
public void printAll() {
// TODO Auto-generated method stub
}
@Override
public void myPrint() {
// TODO Auto-generated method stub
}
}
package lecture0713;
class Human{
}
interface MyInterface{
}
interface Animal{
int weight = 10; // public static final 생략됨
public static final int age = 20;
public void printName(); // abstract 안붙여도 알아서 붙여줌
public abstract void printAge();
}
// abstract MyClass implements Animal{ // 오버라이딩하지 않으면 이 class 또한 추상화된다
// }
//Human 클래스에서 상속받고, Animal 인터페이스를 구현
// 클래스는 단일 상속만 가능하고, 인터페이스는 다중 구현이 가능
class MyClass extends Human implements Animal, MyInterface {
@Override
public void printName() {
// TODO Auto-generated method stub
}
@Override
public void printAge() {
// TODO Auto-generated method stub
}
}
public class Main {
}