언어/Java

[Java] this, super, overriding, final, 추상 클래스, 다형성, dynamic binding

차가운오미자 2021. 6. 25. 17:28

System.out.println() 

System: class의 일종 (=java.lang.System)

  • api로 제공되는 것, java.lang라는 패키지 안에 있는 System 이라는 클래스
  • java.lang을 생략한다는 것 = import java.lang.System; 이 생략되어 있다는 얘기 ===> 컴파일러가 삽입해줌

"."은 연산자, 앞에는 class 혹은 instance를 가리키는 reference, 뒤에는 field/method
out: static field (instance가 없기 때문)  

  • System.out 이 . 앞에 있기 때문에 class 혹은 instance이란 걸 알 수 있다. (instance임, 컴파일러가 알아서 만듬)

println()은 System.out이라는 instance 안에 있는 method

 

package myCar;

public abstract class Car {
	
	int cc;
	
	public Car() {
		// TODO Auto-generated constructor stub 
	}

	//method의 선언 (= abstract method)
	public void go();
}

class Sonata extends Car {
	
	String owner;
	int cc; //shadow (상속받아서 cc라는 필드 사용할 수 있는데, 포함 - 같은 공간은 아님)
	
	public Sonata() {
		// TODO Auto-generated constructor stub
		this(100); // 자신의 클래스의 다른 생성자를 호출
	}
	
	public Sonata(int aa) {
		super(); //여기서 Car의 인스턴스까지 만들고 Sonata의 인스턴스를 만듬
		this.owner = "홍길동";
	}
	
	@Override
	public void go(){  //overriding > 상위 클래스가 abstract이면 override를 이클립스가 추천해줌
			System.out.println("소나타가 열심히 전진해요");
	}
	
}


new Sonata(); 를 실행하면, Sonata 생성자 호출 위해 간다. Sonata의 생성자에 보면 this (100); 가 있다. 이를 통해 자신의 클래스의 다른 생성자 호출한다. 
cf) super()은 상위 클래스의 생성자를 불러오지만 this()는 자신의 클래스의 다른 생성자를 호출한다. (위에 가서 자기 상위 생성자 찾아서 인스턴스를 만듦)
   - this랑 super랑 같이 호출 되는 것은 불가능하다.

this, super, this(), super()

**Constructor 디폴트인거 표시하기

class Sonata extends Car {

  String owner;
  int cc; //shadow (상속받아서 cc라는 필드 사용할 수 있는데, 포함 - 같은 공간은 아님)

  public Sonata() {
    // TODO Auto-generated constructor stub
    this(100); // 자신의 클래스의 다른 생성자를 호출
	}

  public Sonata(int aa) {
    super();
    owner = "홍길동";
    super.cc = aa;
  }
}

 

위의 코드에서 owner필드를 쓸 수 있는 것은 인스턴스가 this로 잡혀서 (this가 인스턴스에 대한 이 클래스의 레퍼런스)
this.owner = "홍길동"; 인 거다. 
super.cc: 현재 사용하는 인스턴스에 대한 레퍼런스이지만 상위 타입의 레퍼런스, 따라서 Car클래스의 cc에 저장된다.

 

method overriding

- method를 상속받긴 하는데, 하는 일을 바꿔서 재정의해서 하위 클래스에서 사용하는 것  
- overriding을 알려주는 annotation: @Override
- 이렇게 어노테이션을 해두면 원래 상위 클래스에 있는 메소드랑 이름이 다르면 오류뜬다. 반대로, 노테이션 없으면 오류 안난다. 따라서, 어노테이션 하는게 좋음


final

1. class 앞에 : 해당 클래스가 마지막 클래스
      ===> 이 클래스 이후로부터는 상속이 일어나지 않음
2. field 앞에 : 해당 field의 값이 마지막 값

     ===> 필드의 값을 바꿀 수 없음, 상수 만드는 개념
     ===> 반드시 초기값 지정을 해야함
3. method 앞에 : 해당 method가 마지막 method, 재정의 금지

     ====> overriding 불가


abstract class

// abstract class 선언
public abstract class Car(){
	
    //method의 정의 (method가 하는 일을 모두 명시)
    public void go(){
        System.out.println("열심히 전진해요");
    }

    // abstract method: method의 선언만 있는 것
    public void go();
        // 완성되지 않은 method ===> class도 완성이 안됨
        // 이렇게 추상 method가 하나라도 존재하면 abstract를 붙임
        // 추상 class

    public abstract class Car() {

    }
}

- 추상 클래스는 인스턴스를 만들 수 없다.
- 활용하는 방법은 오직 상속뿐이다. -> 상속을 받으면 하위 클래스도 abstract class됨
- override해주면 완전한 class만들어줄 수 있음. 보통 이클립스가 완성하기를 추천해 준다.

polymorphism (다형성)

인스턴스를 다양한 형태로 사용할 수 있는 것

is-a관계에 의해서 만들어진 instance의 타입을 바꾸어 쓸 수 있음

* getter랑 setter 만들때, 작은 빨간 네모 = private
* 자바에서 배열은 객체이기 때문에 new + type + 칸 수로 선언한다. 


package school;

public class SchoolTest {

    public static void main(String[] args) {
        Student s = new Student();
        Teacher t = new Teacher();
        Staff f = new Staff();

        s.eat();
        //이런식으로 일일이 해야하는데
    }
}




아래처럼 해보면

package school;

public class SchoolTest {

    public static void main(String[] args) {
        Person s = new Student();
        Person t = new Teacher();
        Person f = new Staff();

        int a = 10;
        int b[] = new int[5];
        Person p[] = new Person[3];

        p[0] = s;
        p[1] = t;
        p[2] = f;

        //반복문으로 프린트 가능

    }
}


즉, 각자 다른 클래스의 생성자로 선언하지만, 타입을 같게 해서 배열로 묶어서 반복문으로 프린트 가능하다. 

이게 바로 다형성의 예시이다. 

dynamic binding

 

public class SchoolTest {

    public static void main(String[] args) {
        Student s = new Student();
        s.sleep(); // type이 학생이므로 student class에 있는 method가 실행된다. 
        }
    }
}
        // 결과: 학생이 잠을 쿨쿨자요

 

public class Student2{

        public static void main(String[] args) {
          Person s = new Student();
          s.sleep();
   		}
}
// 잠을 자요 가 떠야하는데 학생이 잠을 쿨쿨자요가 나옴
// overriding된 method이면 저렇게 나온다. 



이게 dynamic binding이다.
s가 Person instance를 가리키지만, 컴파일러가 overriding된 함수를 찾아서 걔를 동적으로 찾아서 연결시켜 호출함



'언어 > Java' 카테고리의 다른 글

[Java] interface, exception, collections  (0) 2021.06.25
[Java] 접근 제어자, 상속, is-a관계  (0) 2021.06.25
[Java] Java란?  (0) 2021.06.25