클래스(Class)
클래스를 만듦으로서 할 수 있는 3가지
1. 리모콘을 저장할 수 있는 변수를 만들 수 있다.
2. 리모콘을 만들 수 있다.
3. 객체를 만들 수 있다.
클래스의 2가지 용도
1. 객체 만들기
2. 객체를 조종할 수 있는 리모콘 만들기
클래스 내부의 메서드(함수)의 2가지 용도
1. 객체를 만들 때 : 실제 기능
2. 리모콘을 만들 때 : 리모콘 버튼
public class Main {
public static void main(String[] args) {
Car A = new Car();
Car B = new Car();
Car C = new Car();
A.no = 1;
A.speed = 10;
B.no = 2;
B.speed = 20;
C.no = 3;
C.speed = 30;
A.run();
B.run();
C.run();
}
}
class Car {
int no;
int speed;
void run() {
System.out.println(this.no + "번 자동차가 " + this.speed + "의 속력으로 달립니다.");
}
}
상속(Inheritance)
장점
- 객체 지향은 중복 코드를 없애기 위해 존재한다.
- 객체지향적인 구조를 위해서 일부러 중복 코드를 허용하는 경우도 있다.
- 변화에 대한 유연성 및 확장성이 증가한다.
단점
- 메소드 중복 문제가 발생한다.
- 캡슐화를 깨뜨린다. (상위 클래스의 구현이 하위 클래스에게 노출됨으로써 하위 클래스가 상위 클래스에 강하게 결합, 의존하게 되고 강한 결합과 의존은 변화에 유연하게 대처하기 어려워진다.
예제 1)
public class Main {
public static void main(String[] args) {
삼성Tv a삼성Tv = new 삼성Tv();
LGTv aLGTv = new LGTv();
a삼성Tv.켜기();
// 출력 => 삼성Tv 켜집니다.
a삼성Tv.끄기();
// 출력 => 삼성Tv 꺼집니다.
a삼성Tv.ar켜기();
// 출력 => 삼성Tv ar켜기!
aLGTv.켜기();
// 출력 => LGTv 켜집니다.
aLGTv.끄기();
// 출력 => LGTv 꺼집니다.
aLGTv.게임모드전환();
// 출력 => LGTv 게임모드전환!
System.out.println("== 표준Tv 리모콘 들여온 후 ==");
// 표준Tv 리모콘을 만든다.
표준Tv a표준Tv;
// a표준Tv 변수에 삼성Tv 객체를 연결한다.
a표준Tv = a삼성Tv;
a표준Tv.켜기();
// 출력 : 삼성TV 켜집니다.
a표준Tv.끄기();
// 출력 : 삼성TV 꺼집니다.
// a표준Tv 변수에 LGTv 객체를 연결한다.
a표준Tv = aLGTv;
a표준Tv.켜기();
// 출력 : LGTV 켜집니다.
a표준Tv.끄기();
// 출력 : LGTV 꺼집니다.
}
}
class 표준Tv {
void 켜기() { }
void 끄기() { }
}
class 삼성Tv extends 표준Tv {
void 켜기() {
System.out.println("삼성Tv 켜집니다.");
}
void 끄기() {
System.out.println("삼성Tv 꺼집니다.");
}
void ar켜기() {
System.out.println("삼성Tv ar켜기!");
}
}
class LGTv extends 표준Tv {
void 켜기() {
System.out.println("LGTv 켜집니다.");
}
void 끄기() {
System.out.println("LGTv 꺼집니다.");
}
void 게임모드전환() {
System.out.println("LGTv 게임모드전환!");
}
}
예제 2)
// 문제 : 자동차 리모콘이 페라리 객체를 가리키게 한 후 해당 리모콘이 가리키고 있는 객체를
// 다시 페라리 리모콘으로 가리키게(참조하게) 하는 코드를 작성해주세요.
public class Main {
public static void main(String[] args) {
// 수정가능지역 시작
자동차 a자동차 = new 페라리();
페라리 a페라리 = (페라리)a자동차;
// 수정가능지역 끝
}
}
class 자동차 {
void 달리다() {}
void 서다() {}
}
class 페라리 extends 자동차 {
void 뚜껑이_열리다() {}
}
자바는 왜 다중 상속을 지원하지 않을까 ?
다이아몬드 문제
=> 다중 상속을 지원하게 되면 하나의 클래스가 여러 상위 클래스를 상속받게 된다. 이런 특징때문에 다이아몬드 문제가 발생하게 된다. 즉, 메소드 중복이 발생하게 되면 애매한 지점이 생길 수 있다.
자바도 인터페이스는 상속이 되던데??
=> 인터페이스는 구현이 아니라 기능에 대한 선언만 해두기 때문에 다이아몬드상속이 되더라도 전혀 문제되지 않는다.