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 |