자바의 특징이라고하면 객체지향 프로그래밍이다.

교수님 말씀에 따르면

"집을 지을 때 위에서부터 아래로 지으면 C언어고, 밑에서부터 위로 쌓아 올라가면 자바다" 라는데

이게 무슨말인가 싶다.


좀 더 쉽게 설명하자면, 사람을 비유했을 때 C언어는 모든 신체는 사람의 것인 반면 ,

자바는 눈 따로 코 따로 입 따로 팔 따로 다리 따로 몸통 따로 구현을 한 후에 어울려 사람이 되는 것이다. 



■ 객체지향 4대 특징


추상화(Abstract), 상속(Inheritance), 다형성(Polymorphism), 캡슐화(Encapsulation)




■ 추상화(Abstract)




여기서 빨간색 네모는 추상클래스를 나타내고, 나머지는 일반 클래스는 나타낸다.

여기서 추상클래스와 일반클래스의 차이점은 클래스를 객체화 할 수 있느냐 없느냐의 차이이다.


객체는 상태와 행동을 가지고 있어야 하는데, 여기서 동물과 고양이과와 개과라는 것에 대해

세부화는 할 수 있어도, 상태와 행동을 뚜렷이 정의할 수가 없다.


따라서 추상클래스는 선언만 있고 구현 내용이 없거나, 일부만 구현한 미완성 클래스라고 할 수 있다.

추상메소드가 아닌 메소드를 포함할 수도 있고, 상수가 아닌 데이터 선언도 포함할 수 있다.


추상메소드를 포함하거나, 추상클래스로 선언한 것이 추상클래스다.


사용법은 동물, 고양이과, 개과에서 추상화 한 후에,

사자, 고양이, 호랑이, 늑대, 개, 하마에서 extends(상속, 확장)을 받아 사용할 수 있다.


이때, 추상클래스내에 추상메소드가 있을 경우 상속받는 클래스는 반드시 추상메소드를 구현해야 한다.

그래서 필수적으로 구현해야 할 메소드가 있을 때 추상클래스를 사용한다.



※ 주의할점은 추상클래스를 final이나 static으로 선언할 수 없다. 이는 모순이다.

static은 객체 선언 없이 호출이 될 수 있어야 하며, final은 자식클래스에서 재정의될 수 없기 때문이다.




■ 상속(Inheritance)


상속은 기존의 클래스로 부터 새로운 클래스는 유도하는 과정이다.

쉽게 말해서 부모 클래스를 extends로 상속받아 자식 클래스에서 내 것처럼 사용할 수 있다.


시스템을 설게하다보면, 공통된 부분으로 인하여 중복되는 것들이 계속적으로 나올 수 있다.

이럴 때 상속을 이용하여 비슷한 객체끼리 하나의 묶음으로 묶어주고, 공통된 부분을 뽑아서

상위 개념의 부모클래스를 생성한다.


이 객체들이 부모 객체를 상속하면 중복이 제거되며, 공통된 방식으로 설계 할 수 있다.

또한 상속 받는 과정에서 다형성(오버로딩, 오버라이딩)을 사용하여 자유롭게 변형할 수 있다.



■ 인터페이스(Interface)


자바는 다중상속을 할 수 없는데 이를 보완한 방법이 Interface 다.

Interface는 "무엇을 할 수 있는" 으로 표현이 되는데,

그 예로 Serializable, Cloneable, Comparable, Runnable 이 있다.




위의 관계도를 보면서 인터페이스에 대한 예시를 보자.



동물 클래스

 // 동물.java

package inheritance02;
 
public class 동물{
    String myClass;
    
    동물(){
        myClass = "동물";  
    }
    void showMe(){
        System.out.println(myClass);  
    }
}

 

 인터페이스

 // 날수있는.java

package inheritance02;
 
public interface 날수있는{
    void fly();
}

 // 헤엄칠수있는.java

package inheritance02;
 
public interface 헤엄칠수있는{
    void swim();
}

 동물 클래스를 상속받은 클래스

 // 포유류.java

package inheritance02;
 
public class 포유류 extends 동물{
    포유류(){
        myClass = "포유류";  
    }
}

 // 조류.java

package inheritance02;
 
public class 조류 extends 동물{
    조류(){
        myClass = "조류";
    }
}

 포유류 클래스를

상속받고


인터페이스를

구현한


고래,박쥐

클래스

 // 고래.java

package inheritance02;
 
public class 고래 extends 포유류 
implements 헤엄칠 수 있는{
    고래(){
        myClass = "고래";  
    } 
    
    @Override
    public void swim(){
        System.out.println(myClass + "수영 중 어프!! 어프!!");
    } 
}

 // 박쥐.java

package inheritance02;
 
public class 박쥐 extends 포유류 
implements 날 수 있는{
    박쥐(){
        myClass = "박쥐";  
    } 
    
    @Override
    public void fly(){
        System.out.println(myClass + "날고 있다..슈융");
    } 
}



고래를 예시로 들어보자.


포유류 클래스는 동물 클래스를 상속 받았기 때문에, "myClass"라는 변수와,

"shoMe"라는 함수를 사용할 수 있게 되었다.


고래 클래스는 "포유류"클래스를 상속받고 "헤엄칠 수 있는"을 구현 하였다.

따라서 myClass변수와 showMe함수를 사용할 수 있고, swim이라는 함수를 사용할 수 있다.



■ 인터페이스와 추상클래스의 비교


이렇게 보면 인터페이스와 추상클래스의 용도가 얼추 비슷한 것 같아 보인다.



인터페이스와 추상클래스의 공통점

 abstract class(추상 클래스)와 interface 는 선언만 있고 구현 내용이 없는 클래스이다.


그래서 자기 자신이 new를 해서 객체를 생성할 수 없으며,
추상클래스를 extends 받거나, interface를 implements  자식만이 객체를 생성할 수 있다.
상속받은 자식이 구현을 반드시 하도록 해야할 때 사용한다.


 인터페이스와 추상클래스의 차이점

 인터페이스

 추상클래스

● interface라고 선언


● 구현이 전혀 되어있지 않고, 메소드 선언만 되어있다.


● implement를 통해 다중상속의 효과를 낼 수 있다.

● abstract라고 선언


● 일부는 구현이 되어있을 수도 있다.

(abstract 메소드는 구현X)


● extends를 통해 한 번 밖에 상속받지 못한다.



정리를 하면, 인터페이스는 다형성 즉, 행위의 다양함(메소드)을 구현할 때 사용한다.

추상클래스는 부모의 속성을 자식이 그대로 가져가야할 때 사용한다.




■ 다형성(Polymorphism)


객체지향 개념에서 다형성이란, "여러 가지 형태를 가질 수 있는 능력", "사용편의성"을 말하고

오버라이딩(Overriding), 오버로딩(Overloading)이 있다.


오버라이딩은, 말 그대로 덮어 쓴다는 말이다. 상위 클래스로부터 상속받은 메소드를 재정의해서 사용한다.

오버로딩은, 상위 클래스로부터 상속받은 메서드의 이름은 같으나, 인자의 개수가 달라 중복을 허용한다.


예시를 보자.


// Animal.java
package polymorphism01;
 
public class Animal{
    public String name;
     
    public void showName(){
        System.out.printf("안녕 나는 %s야. 반가워 \n", name); 
    
}
 
// Penguin.java
package polymorphism01;
 
public class Penguin extends Animal{
    public String habitat;
     
    public void showHabitat(){
        System.out.printf("%s는 %s에 살아\n", name, habitat);
    }
     
    // 오버 라이딩 - 재 정의 : 같은 메서드 이름, 같은 인자 리스트
    public void showName(){
        System.out.println("어머 내 이름은 알아서 뭐하게요?"); 
    }
    // 오버 로딩 - 중복 정의 : 같은 메서드 이름, 다른 인자 리스트
    public void showName(String yourName){
        System.out.printf("%s 안녕, 나는 %s라고 해 \n", yourName, name); 
    }

} 



※ 재정의를 해서 사용하게 되면, 오버라이딩한 메소드가 호출 된다.

    만약 상위 클래스의 메소드를 호출하고 싶을 경우에는 super.methodName(); 을 하면 된다.



■ 캡슐화(Encapsulation)

 

관련있는 변수와 메소드를 하나의 클래스로 묶어 주고,

접근 제어 지시자를 사용해 외부로부터 정보를 접근할 수 없게 하는 방법이다.

get,set 메소드를 만들어 정보의 은닉, 유지보수를 할 수 있다.


 

Public - 모두가 접근 가능


Protect - 상속받은 클래스, 같은 패키지 내의 클래스에서 접근 가능


default[기본 값] - 같은 패키지 내의 클래스에서 접근 가능


Private - 본인만 접근 가능





■ 출처


http://hyeonstorage.tistory.com/180

http://itewbm.tistory.com/

http://marobiana.tistory.com/58

http://slenderankle.tistory.com/154


+ Recent posts