
객체지향 언어의 특징: OOP is A P.I.E
Abstraction(추상화): 현실의 객체를 추상화 해서 클래스를 구성한다.
Polymorphism(다형성): 하나의 객체를 여러 가지 타입으로 참조할 수 있다.
Inheritance(상속): 부모 클래스의 자산을 물려받아 자식을 정의함으로 코드의 재사용이 가능
Encapsulation(데이터 은닉과 보호): 데이터를 외부에 직접 노출시키지 않고 메서드를 이용해 보호
public class Person{
String name;
void eat(){}
void jump(){}
}
public class SpiderMan extends Person{
boolean isSpider;
void fireWeb(){}
}
상속의 관계는 is a 관계라고 한다. Person is a Object, SpiderMan is a Person
자바는 단일 상속만 지원한다 → 대신 interface와 포함 관계(has a)로 단점 극복 (아래 코드 예시 참고)
포함 관계 : 상속 이외에 클래스를 재활용 하는 방법
메서드 오버라이딩( overriding): 조상 클래스에 정의된 메서드를 자식 클래스에서 적합하게 수정하는 것
선조클래스와 후손클래스에 같은 이름의 함수가 존재하는경우
선조클래스로부터 상속받은 메서드의 내용을 변경하는것을 오버라이딩(재정의)이라고함
public class Person {
void jump(){
System.out.println("두 다리로 점프");
}
}
public class Spider{
void jump(){
System.out.println("엄청난 점프");
}
}
public class SpiderMan2 extends Person{
Spider spider = new Spider(); //포함 관계 Spider 클래스를 멤버변수로 가지고 있는다.
boolean isSpider;
void fireweb(){}
void jump(){
if(isSpider){
//포함 관계 이용해서 상위 클래스 메서드. 같은 메서드 이름이지만 overriding 된 것
spider.jump();
}else{
//System.out.println("두 다리로 점프");
//but 이 코드는 Person에서 정의한 메서드에 이미 있는 내용이다.
super.jump(); //이렇게 조상이 가지고 있는 메서드를 실행할 수 있다.
}
}
}
Person이 가지고 있는 jump( )은 성능이 좋지 않다 → Spider가 가지고 있는 jump( )를 이용


class Test1{
public void view1() { System.out.println("view1 method"); }
public void view3() { System.out.println("view3 method"); }
}
class Test2 extends Test1{
public void view1() { System.out.println("view11 method"); }
public void view2() { System.out.println("view22 method"); }
}
public class OverrideEx {
public static void main(String[] args) {
//부모 클래스는 자식 클래스를 알지 못한다 -> 메서드 오버라이딩을 통해 알 수 있음
Test1 ob=new Test2(); //부모 클래스 참조변수로 자식 객체 생성
ob.view1(); // view11 자식도 가지고 있으니 자식 클래스의 메서드를 가져온다
// ob.view2(); // error
ob.view3(); // view3 자식이 안 가지고 있으니 자신의 메서드 실행
//자식 클래스는 부모 클래스가 뭔지 아니까 접근해서 가져오기 가능
Test2 ob=new Test2();
ob.view1(); // view11
ob.view2(); // view22
ob.view3(); // view3 자기가 안 가지고 있으니 부모 클래스에 메서드가 있는지 확인
}
}
Test1 ob=new Test2( ); 로 쓰는 이유는 부모 클래스에서 자식 클래스에 있는 메서드를 사용하고 싶을 때 사용한다. 코드의 절약 & 다형성 활용할려고 사용
ex) Fruit( )라는 부모 클래스와 Peach, Banana와 같은 자식 클래스가 있을 때
Fruit peach = new Peach( ); Fruit banana = new Banana( ); 와 같이 사용이 가능하다.
Annotation: 사전적 의미 주석, 컴파일러,JVM,프레임워크 등이 보는 주석
ex) @Deprecated, @Override, @SuppressWarinings
toString 메서드: 객체를 문자열로 변경하는 메서드
public String toString(){
return getClass().getName() + "@: + Integer.toHexString(hashcode());
}
사실 필요한 건 주소값이 아니라 안에 있는 내용이다.
@Override
public String toString(){
return "SpiderMan [isSpider=" +isSpider + ", name="+name+"]";
}
이런 식으로 오버라이드해서 메서드 재정의
equals 메서드: 두 객체가 같은지를 비교하는 메서드
public boolean equals(Object obj){
return(this == obj);
}
기본적으론 객체의 주소값이 같은지 비교하는 대상이 같은 객체인지 확인하는 메서드
-> 보통 equals는 값이 같은지 다른지 비교하는 경우가 많다 -> override필요
public boolean equals(Object obj){
return(this.phone_number == obj.phone_nuber);
}
super 키워드 : this를 통해 멤버에 접근했듯이 super 를 통해 조상 클래스 멤버 접근
class Parent{
String x = "parent";
}
class Child extends Parent{
String x = "child";
void method(){
String x = "method";
System.out.println("x: "+x);
System.out.println("this.x: "+this.x);
System.out.println("super.x: "+super.x);
}
1. 현재상태: method ,child, parent
2. method의 x 주석처리: child, child, parent
3. child의 x 주석처리: parent, parent, parent
}
class Branch {
public Branch() {
System.out.println("Default Branch Constructor");
}
public Branch(String str, int n) {
this();
System.out.println(str+" "+ n +" "+ "Constructor");
}
}
class Leaf extends Branch{
public Leaf() {
this("ABC");
System.out.println("Default Leaf Constructor");
}
public Leaf(String str) {
super(str,10);
System.out.println(str+ " Leaf Constructor");
}
}
public class InheritanceEX3 {
public static void main(String[] args) {
new Leaf();
}
}
실행값
default Branch Constructor //부모 객체 먼저 생성된다
ABC 10 Branch Constructor
ABC Leaf Constructor
default Leaf Constructor
################ Emp.java ################
//default, 인자 2개, toString
public class Emp {
private String name;
private String phone;
public Emp() {}
public Emp(String name, String phone) {
this.name = name;
this.phone = phone;
}
@Override
public String toString() {
return "나의 이름은 " + name + "이고 연락처는 " +
phone + "입니다";
}
}
################ EmpScore.java ################
public class EmpScore extends Emp {
private double score;
private char grade;
public EmpScore() {
super();
}
public EmpScore(String name, String phone, double score,char grade) {
super(name, phone); //2개는 부모만 처리할 수 있으니까 부모 생성자로 보낸다
this.score = score; //나머지는 자식 생성자에서 처리
this.grade = grade;
}
@Override
public String toString() {
return super.toString() + "\n나의 점수는 " + score
+ "점이고 학점은 " + grade + "입니다";
}
}
################ EmpMain.java ################
public class EmpMain {
public static void main(String[] args) {
// TODO Auto-generated method stub
Emp ob1 = new Emp("이순신","010-1111-1111");
System.out.println(ob1);
EmpScore ob2 = new EmpScore("이순신","010-1111-1111",75.3,'C');
System.out.println(ob2);
}
}
출력 값
나의 이름은 이순신이고 연락처는 010-1111-1111입니다
나의 이름은 이순신이고 연락처는 010-1111-1111입니다
나의 점수는 75.3점이고 학점은 C입니다
Static method는 상속이 될까? ⇒ X
class Parent2{
static void method(){
System.out.println("parent mode")
}
}
class Child2 extends Parent2{
static void method(){
System.out.println("parent mode")
}
}
@Override
class Child2 extends Parent2{
static void method(){ //hiding => static method는 상속되지 않는다.
System.out.println("parent mode")
}
}