" 자바의 Class에 대해 학습하세요. "
객체들간의 상호 작용으로 표현. 클래스 혹은 객체들의 집합으로 프로그램을 작성하는 방식. 현실 세계의 사물을 객체로 보고, 객체의 속성과 기능을 기반으로 프로그래밍하는 기법. (Object Oriented Programming)
메소드 오버로딩: 같은 이름이지만 다르게 작동하는 여러 메소드
메소드 오버라이딩: 슈퍼클래스의 메소드를 서브 클래스마다 다르게 구현
자바의 클래스는 필드, 생성자, 메소드로 구성된다.
// 접근지정자 class(키워드) 클래스이름 { }
public class Circle {
public int radius; // 원의 반지름 필드
public String name; // 원의 이름 필드
public Circle() { } // 생성자 메소드(default 생성자)
// 파라미터를 가진 생성자. 파라미터를 가지고 변수를 초기화함.
public Circle(int radius, String name) {
this.radius = radius;
this.name = name;
}
public double getArea() { // 원의 면적 계산 메소드
return 3.14*radius*radius;
}
}
자바에서는 클래스를 정의하기위해 class 키워드를 사용하며, 외부 클래스가 해당 클래스에 접근하는 범위를 접근 지정자라 하고 이를 통해 접근을 제한 할 수 있다.
접근지정자 | 클래스 내부 | 동일 패키지 | 하위 클래스 | 그 외 영역 |
---|---|---|---|---|
public | o | o | o | o |
protected | o | o | o | x |
default(기본, 생략가능) | o | o | x | x |
private | o | x | x | x |
객체는 반드시 new 키워드를 이용해 생성한다. new 키워드는 객체의 생성자를 호출하는 역할을 하는데, 메모리의 힙 영역에 데이터를 저장할 영역을 할당 받은 후 해당 영역의 주소를 객체에게 반환하여 객체를 사용할 수 있도록 만들어 준다. 이러한 과정을 클래스의 인스턴스화 라고 한다.
// 클래스이름 변수명 = new 클래스이름(생성자 호출)
Circle pizza = new Circle();
Map<String, Integer> map = new HashMap<>();
클래스 내부의 메소드는 접근지정자, 리턴타입, 메소드명, 파라미터로 구성된 정의부와 메소드의 기능을 호출하는 호출부로 구성됨.
// 접근지정자 리턴타입 메소드명(파라미터)
public String getName() {...호출부...}
public void setName(String name) {...}
자바의 객체지향적 특징인 다형성을 이용한 메소드 정의 기법으로 코드의 변경과 확장을 용이하게 해주는 2가지 기법이 있다.
메소드 오버로딩은 파라미터의 개수나 타입이 다르다면, 동일한 이름의 메소드명을 사용해 메소드를 정의할 수 있는 기법이다. 리턴타입은 오버로딩과 관련이 없다.
// 메소드 오버로딩이 성공한 사례
class MethodOverloading {
public int getSum(int i, int j) {
return i + j;
}
public int getSum(int i, int j, int k) {
return i + j + k;
}
public int getSum(int i, double j) {
return i + (int)j;
}
}
// 메소드 오버로딩이 실패한 사례
class MethodOverloadingFail {
public int getSum(int i, int j) {
return i + j;
}
public double getSum(int i, int j) {
return (double)(i + j);
}
}
메소드 오버라이딩은 상위 클래스가 정의한 메소드를 하위 클래스가 가져와 변경하거나 확장하는 재정의 기법이다. 슈퍼클래스 메소드의 이름, 매개변수 타입 및 개수, 리턴 타입 등 모든 것을 동일하게 작성해야 한다. 프로그램 실행시 결정되는 동적 바인딩이 발생한다.
📌 동적 바인딩: 서브 클래스에 오버라이딩 된 메소드가 무조건 실행되는 동적 바인딩
class Person {
public void info() {
System.out.println("사람");
}
}
class Adult extends Person {
@Override
public void info() {
System.out.println("어른");
}
}
class Child extends Person {
@Override
public void info() {
System.out.println("어린이");
}
Person person = new Person();
Adult adult = new Adult();
Child child = new Child();
person.info();
adult.info();
child.info();
클래스를 생성하고 객체를 호출할 때 객체를 초기화 하기 위해 사용되는 메소드가 생성자이다.
class Person() {...} // 기본 생성자 호출
class Person {
// 묵시적 생성자
public Person() {
System.out.println("생성완료");
}
// 명시적 생성자
public Person(String name, int age) {
this.name = name;
this.age = age;
}
}
this 키워드는 클래스가 인스턴스화 되었을 때 자기 자신의 메모리 주소를 가지고 있다. 즉 객체 자신에 대한 레퍼런스이다. 컴파일러에 의해 자동으로 관리되며, this.멤버
형태로 멤버를 사용하면 된다.
public class Circle {
int radius;
public Circle() { radius = 1; }
public Circle(int radius) {
this.radius = radius; // 1)의 경우
}
Boolean compare(Circle c) { return c == this; }
double getArea() {
if (compare(this)) return 0; // 2)의 경우
return 3.14*radius*radius;
}
public Circle getMe() { return this; } // 3)의 경우
}
public class Book {
String title;
String author;
void show() { System.out.println(title + " " + author); }
public Book() {
this("", "");
System.out.println("생성자 호출됨");
}
public Book(String title) {
this(title, "작자미상");
}
public Book(String title, String author) {
this.title = title;
this.author = author;
}
public static void main(String[] args) {
Book littlePrince = new Book("어린왕자", "생택쥐페리");
Book loveStory = new Book("춘향전");
Book emptyBook = new Book();
}
}