[Java] 2. Inheritance, AbstractClass, method Overriding

Nam_JU·2022년 7월 12일
0

KaKao Cloud School

목록 보기
7/19
post-thumbnail


복습

JAVA 언어의 특성

  • JVM이 우리 프로그램을 실행시켜 준다
  • JVM + CoreAPI = JRE (Java Runtime Enviroment - 자바실행환경)
  • JRE + Utility(개발용 프로그램들) = JDK (Java Develpment Kit)

자바는 클래스의 집합이다

  • 클래스를 하나만 만들어도 되고 여러개를 만들어도 된다
  • Java Sourse Code 1개에 클래스 1개를 작성한다
    • 클래스 이름으로 파일명을 짓는다
    • 특히 public class의 이름은 무조건 파일명으로 사용한다
    • public class란 해당 클래스를 패키지 제약없이 어디서든 사용한다
  • 전역변수(Global variable)에 대한 개념이 없다
  • application의 entry proto는 main()dlek

Class 구성요소

public class Student {

    1. fileds 변수들 (객체의 속성)

    2. Constructors 생성자들
    
    3. methods 메소드들 (객체의 행위)
   
}
  1. 프로그램을 호출하면 JVM이 가동
  2. JVM이 가지고있는 클래스로더(ClassLoader)가 클래스를 읽는다
  3. 클래스로더가 악성코드가 있는지 검사
  4. main() 호출을 한다
    1. public static void main()
    2. 자바의 모든 클래스는 특정 패키지에 묶여있다
    3. 클래스 로더가 main을 호출하려면 다른 패키지에 있는 클래스 로더에 의해 사용이 될수있도록 지정을 해야한다. 그러기 때문에 main은 public으로 되어있어야만 함!!!
      1. 클래스로더와 우리코드의 패키지는 서로 다름 (클래스로더는 오라클이 만들었기 때문에 다른 패키지에 있다)
      2. main은 리턴값이 없다 void

JVM 메모리구조

  • 어떤 시점에 어떤 데이터가 어디에 들어가는지

  • 총 5가지가 있다.

    • Register : 프로그램의 실행 포인터를 관리 (지금 어디실행중이고 다음은 어디이다)
    • Runtime Construct Pool: 자바가 기본적으로 주는 상수값들 (상수값 사용)
    • Method Area:클래스 자체에 대한 정보, 클래스를 처음 사용하는 시점에 메모리가 올라간다
    • Call Stack:메서드가 호출되면 무조건 stack구조로 저장
    • Heap:new로 생성되는 모든 인스턴스가 저장된다

    3 -> 2 -> 4-> 1-> 5

    public class InstanceTest {
        //feilds - 1
        int a= myCall("1번출력");
        static int b = myCall("2번출력");
        //constructor -2
        public InstanceTest(){
        }
        //method -3
        public static int myCall(String msg){
            System.out.println(msg);
            return 100;
        }
        public void printMsg(String msg){
            int a = 100;
            System.out.println(msg);
        }
    }
    // java Main => 실행
    public class Main {
        public static void main(String[] args) {
            InstanceTest test; //지역변수 선언
            System.out.println("3번");
            int k = InstanceTest.myCall("4번");
            test = new InstanceTest();
            test.printMsg("5번");
        }
    }
  • 이전 예제와 다르게 3번이 먼저 출력된 이유는 Main클래스와 InstanceTest클래스가 따로 생성되어 있기 때문에 JVM이 Main클래스를 먼저 실행했기 때문이다
    (이전 코드들은 Main클래스안에 클래스들이 안에 속해져있었음)

메서드 오버로딩 Method Overloading

  • method의 이름이 같아도 파라미터(인자)에 넘어오는 갯수, 타입에 따라 다른 메서드로 간주한다

접근제어자 Access Modifier

  • public
  • protected
  • package(default)
  • private



수업

Static block

  • main()을 사용하기 직전에 특수한 처리(library loading)을 사용하기 위해 사용

  • 메인메서드가 실행되기 직전에 프로그램에서 필요한 라이브러리같은것들을 로딩할 필요가 있을때 사용한다

    public class MyClass {
        //필드
        int aaa;
        static int bbb = staticCall();
    
        //default 생성자는 꼭 써주기
        public MyClass(){
    
        }
    
        //static block
        //메인메서드가 실행되기 직전에 프로그램에서 필요한 라이브러리같은것들을 로딩할 필요가 있을때 사용한다 
        static{
            System.out.println("static block!");
        }
    
        //메서드
        static int staticCall(){
            System.out.println("staticCall 호출되었어요!");
            return 100;
        }
    
        public static void main(String[] args) {
            System.out.println("main 호출");
        }
    }
    
    1. staticCall 호출되었어요! 
    2. static block! 
    3. main 호출

패키지 Package

  • 자바의 모든 클래스는 특정 패키지안에 들어가 있다
    • (내가 안적어도 default package에 들어가있음)
  • 패키지가 없으면 같은 이름의 클래스를 구별할수가 없다
    • 즉 Class이름이 같아도 package가 다르면 다른 class!
  • 클래스의 유지보수 및 관리를 위해 클래스를 논리적으로 묶어주는 개념이다
    • 패키지이름의 폴더가 생성되고 그안에 클래스를 위치 시킨다
    • 다른 패키지를 사용하기 위한 방법은?
      package로 묶여 있는 class는 사용할 때 pull package명을 써줘야 한다 (import 구문을 사용)
  • 자바에서는 패키지를 이용해서 관련 클래스들을 그룹화 한다
  • 패키지를 사용하면 외부로부터 제공 받는 여러 라이브러리, 프레임워크를 구분해서 사용할 수 있도록 하는게 패키지이다
  • 패키지를 사용하는 가장 중요한 이유는 클래스 이름에 대한 유일성을 보장 할 수 있다.

내가 클래스를 만들어서 사용하는것도 중요하지만 외부의 클래스를 잘 사용하는것도 중요!


상속 Inheritance

  • 부모 Class가 가지는 내용을 확장해서 자식 Class를 만드는 방식
  • 공통적으로 가지고있는 속성
  • 코드가 중복되게되면 변경을 하게될경우 모두 변경을 해줘야한다. 이과정에서 에러가 날 가능성이 높다
  • 어떻게 해야할까? 상위개념을 만들어서 상속을 받고 사용하자
  • 중복되는 코드
class Student {
  String name; //이름  (중복)
  String mobile; //전화번호 (중복)
  String dept; //학과
}
class Teacher {
  String name; //이름 (중복)
  String mobile; //전화번호 (중복)
  String subject; //과목
}
 class Staff {
  String name; //이름 (중복)
  String mobile; //전화번호 (중복)
  String salary; //월급
 }
  1. extends 를 사용하여 상속을 구현한다
  2. 자바는 단일상속만 지원한다
    - extends 뒤에 하나만 온다는 뜻!
    - 왜 단일상속만 허용할까?
    - 2개이상이되면 어디서 상속을 받는지 모호하게된다.
    그래서 다중상속을 하지 않는다
    - 대신 상속의 상속을 받도록은 가능 (상속 계층구조) → 동시에 2개이상
  3. 상속은 항상 옳을까?
    - 객체지향의 축이 되는게 상속임으로 좋다.
    - 그러나 상속관계를 갖게된다면 상위클래스와 하위클래스가 강하게 결합하게 된다

//상위클래스
class Person {
 String name; //이름
 String mobile; //전화번호
}
//person을 확장시켜서 독립적으로 사용한다 
class Student extends Person{
  String dept; //학과
}
 class Teacher extends Person{
  String subject; //과목
}
 class Staff extends Person{
  String salary; //월급
 }
  • Person의 기능하나를 더 추가하고 싶어! 그러면 Person을 수정해야함. 필요할때마다 Person을 건들이게 되면 불필요한 기능이 추가될 수 있다.
  • 기존의 기능을 그대로 유지하면서 새로운 기능을 추가하는 방법.
    이것이 상속
    이다


Constructor가 상속에서 어떻게 동작하나요

  • 생성자(Constructor)는 상속되지 않는다
    • 상속안되는것: 생성자, private(접근제어자) access modfire로 지정된 field, method도 상속되지 않는다

객체가 만들어지는 순서

  • 자바의 모든 class는 무조건 Object Class를 상속하고 있다
    (최상위클래스 = ObjectClass)
  • 자바의 모든 Class는 특정 패키지안에 속해져있다
  • 즉 ObjectClass는 패키지로 묶여져 있다! → 어느패키지에 묶여 있을까? → java.lang.Object
  • Object 클래스가 패키지화 되어서 묶여 있다
import java.lang.*;  //저렇게 안쓰는 이유는 lang*모두 들어있어서 
//상위클래스       //원래는 java.lang.Object 이다
class Person extends Object {
 String name; //이름
 String mobile; //전화번호
}
class Student extends Person{
  String dept; //학과
}
public class Main{
    public static void main(String[] args) {
        //객체가 만들어지는 순서
//        Person p = new Person();
        Student s = new Student();
 }
}


객체를 만들때는 최상위 객체부터 만들어야한다.

  • 최상위인 Object는 생성자를 호출한다
  • Is-a relationship = 서브클래스는 슈퍼클래스와 같다
//상위클래스
class Person {
 String name; //이름
 String mobile; //전화번호
}

class Student extends Person{
  String dept; //학과
}

public class Main{
    public static void main(String[] args) {
        //객체가 만들어지는 순서

//        Person p = new Person();
        Student s = new Student();
        
    }
}

  • 인스턴스가 만들어 지려면 생성자가 반드시 호출되어야 한다
  • 상위에서부터 항위에 생성자가 계속 호출되고 난 뒤 객체가 생성된다
  • 상위클래스의 생성자가 먼저 호출된다
//상위클래스
class Person extends Object {
public Person(){ //default 생성자
       super();
   }
String name; //이름
String mobile; //전화번호
}
class Student extends Person{
   public Student(){ //default 생성자
       super(); //생성자를 안쓰면 최상위의 super()이 나온다 
   }
 String dept; //학과
}

public class Main{
   public static void main(String[] args) {
       //객체가 만들어지는 순서
                   //생성자를 호출하면서 객체를 만듦
       Student s = new Student();

   }
}
  • 만약 매개변수가 들어오는(내가만든) 생성자라면?
    • 형식에 맞춰서 적용시켜야한다
class Person extends Object {
    public Person(String name){ //내가만든 생성자
        this.name = name;
    }
 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();

    }
}

상속관계의 초기화 과정

  • 상속 관계에서 자식 클래스를 인스턴스화하면 부모 클래스의 객체도 인스턴스화가 진행된다.
  • 자식클래스의 객체가 인스턴스화 되기 위해서는 먼저 부모 클래스의 객체가 인스턴스화 되어야 한다
  • 따라서 상속 구조에서 가장 상위의 부모 클래스부터 차례로 인스턴스화가 진행되게 된다.


메소드 재정의 method Overriding

하위클래스가 상위클래스를 재정의하여 사용 가능하다

this.supper

  • this: 현재사용하는 객체에 대한 referrence 참조
  • super : 현재 사용하는 객체에 대한 referrence 참조이지만 타입은 상위클래스의 타입이다
  • super(): 상위클래스의 생성자 호출
  • this(): 자신의 클래스가 가지고 있는 다른 생성자를 호출한다
//상위클래스
    class Supperclass{
    //static Method
        static int staticCall(String msg){
            System.out.println(msg);
        return 100;
        }
        
        //fields
        int a = staticCall("1번 입니다");
        static int b = staticCall("2번 입니다");
        
        //constructor
        public Supperclass(){
            staticCall("3번 입니다");
        }
        
        public Supperclass(int i){
            this();//자신의 다른 생성자 호출(인자가없는)
            staticCall("4번 입니다");
        }
        
        //method
        public void myFunc(){
            System.out.println("5번 입니다");
        }
    
    }
    public class InheritanceTest extends Supperclass{
        //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번 입니다");
            Supperclass obj = new InheritanceTest();
            obj.myFunc();
        }
    }
2번 입니다
7번 입니다
10번 입니다
1번 입니다
3번 입니다
4번 입니다
6번 입니다
8번 입니다
5번 입니다
9번 입니다

  • 슈퍼클래스 정보가 먼저 메모리에 올라간다.
  • static이 호출되어 2번입니다가 출력
  • Inheritacetest class도 메모리에 올라간다
  • static이 호출되어 7번입니다가 출력 (클래스정보 다올라감)
  • main() 실행 → 10번입니다 출력
  • Supperclass obj = new InheritanceTest(); 객체를 생성하기위해 인자가 없는 생성자 호출하러감
  • public InheritanceTest(){
    super(100); → 상위클래스로 호출하러감
    staticCall("8번 입니다");
    super.myFunc();
    }
  • 객체공간이 생성 → 1번 호출
  • 생성자 초기화 → 3번입니다
  • this가 끝나서 → 4번이 호출 (상위가 다 끝남)
  • 상위가 끝났음으로 이제 super(100); 실행. int c = staticCall(6번실행)
  • 그다음 staticCall 8번 실행
  • 내가 가지고 있는 myFuncfh 5번이 찍힘
  • 마지막 생성자가 완료
    상위타입으로 myFunch를 실행함 → 상위의 5번이 다시 찍힐것 같지만 객체에 대한 타입이 상위 타입이라고 해도 만약 오버라딩된 메서드가 하위에 존재한다면 메서드는 오버라딩된 메서드를 사용한다.
  • 이것을 동적 바인딩이라고 한다 → 9번이 찍힌다

오버로딩 VS 오버라이딩?

  • 오버로딩(Overloading)
    하나의 클래스에서 같은 이름을 가진 메소드가 있더라도 매개변수의 개수 또는 타입이 다르면, 같은 이름을 사용해서 메소드를 정의할 수 있다
  • 오버라이딩(Overriding)
    상속관계에서 일어남으로 두개의 클래스에서 일어난다
    부모 클래스의 메소드를 재정의하는 것이므로, 자식 클래스에서는 오버라이딩하고자 하는 메소드의 이름, 매개변수, 리턴 값이 모두 같아야 한다.

객체간 타입 형 변환

  • 상속관계가 성립되어있고 자식 클래스의 인스턴스가 부모 클래스 타입의 변수로 참조되면 실제 인스턴스화 객체가 자식 객체일 경우에도 자식 클래스가 갖고 있는 인스턴스 메소드를 호출 할 수 없다
  • 부모 클래스 타입의 변수로 참조하고 있는 자식 인스턴스 객체의 메소드를 호출하기 위해서는 down-casting이 이루어져야 한다. (클래스타입을 부모가 아닌 자식으로 바꾸는 것)
  • 단 재정의하고 있는 메소드의 경우 up-casting(부모로 바꿔도)상황에서도 자식 클래스의 재정의 메소드가 호출된다

profile
개발기록

0개의 댓글