JAVA/개념

[JAVA] 06. OOP2(객체 지향 언어)

밍글링글링 2017. 8. 1.
728x90

1. 상속

1.1 상속(ingeritance)의 정의와 장점

▶ 상속이란?

- 기존의 클래스를 재사용해서 새로운 클래스를 작성하는 것.

- 두 클래스를 부모와 자식으로 관계를 맺어주는 것.

- 자식은 부모의 모든 멤버를 상속받는다.(생성자, 초기화블럭 제외)

- 자식의 멤버개수는 부모보다 적을 수 없다.(같거나 많다)

class 자식클래스 extends 부모클래스{
    //...
}

ex)
class Point{
    int x;
    int y;
}

class Point3D{
    int x;
    int y;
    int z;
}
            ▼  
class Point3D extends Point{
    int z;
}

 

 

1.2 클래스 간의 관계 - 상속 관계(ingeritance)

- 공통부분은 부모에서 관리하고 개별부분은 자식에서 관리한다.

- 부모의 변경은 자식에 영향을 미치지만, 자식의 변경은 부모에 아무런 영향을 미치지않는다.

class Parent {}
class Child extends Parent {}
class Child2 extends Parent {}
class GrandChild extends Child {}
 

 

1.2 클래스 간의 관계 - 포함관계(composite)

▶ 포함(composite)이란?

- 한 클래스의 멤버변수로 다른 클래스를 선언하는 것

- 작은 단위의 클래스를 먼저 만들고, 이 들을 조합해서 하나의 커다란 클래스를 만든다.

class Circle {
    int x; //원점의 x좌표
    int y; //원점의 y좌표
    int r; //반지름(radius)
}
                  ▼
class Circle {
    Point c = new Point(); //원점
    int r; //반지름(radius)
}

class Car{
    Engine e = new Engine(); //엔진
    Door[] d= new Door[4]; //문, 문의 개수를 넷으로 가정하고 배열로 처리햇다.
}
 

 

1.3 클래스 간의 관계 결정하기 - 상속 vs 포함

- 가능한 한 많은 관계를 맺어주어 재사용성을 높이고 관리하기 쉽게 한다.

- 'is-a'와 'has-a'를 가지고 문장을 만들어 본다.

원(Circle)은 점(Point)이다. - Circle is a Point.

원(Circle)은 점(Point)을 가지고 있다. - Circle has a Point.

 

상속 관계 - '~은 ~이다. (is-a)'

포함 관계 - '~은 ~을 가지고 있다.(has-a)'

class Circle extends Point{
    int r; //반지름(radius)
}
                   ▼
class Circle{
    Point c = new Point(); //원점
    int r; //반지름(radius)
}
 

 

1.3 클래스 간의 관계 결정하기 - 예제 설명

- 원(Circle)은 도형(Shape)이다.(A Circle is a Shape.) : 상속관계

- 원(Circle)은 점(Point)를 가지고 있다.(A Circle has a Point.) : 포함관계

class Shape{
    String color = "blue";
    void draw(){
        //도형을 그린다.
    }
}

class Point{
    int x;
    int y;
    
    Point(){
        this(0,0);
    }

    Point(int x, int y){
        this.x=x;
        this.y=y;
    }
}

class Circle extends Shape{
    Point cneter;
    int x;

    Circle(){
        this(new Point(0,0),100);
    }
    Circle(Point center, int r){
        this.center = center;
        this.r = r;
    }
}

class Triangle extends Shape{
    Point[] p;
    
    Triangle(Point[] p){
        this.p = p;
    }

    Triangle(Point p1, Point p2, Point p3){
        p = new Point[]{p1,p2,p3};
    }
}

Circle c1 = new Circle();
Circle c2 = new Circle(new Point(150,150),50);

Point[] p = {new Point(100,100),
                new Point(140,50),
                new Point(200,100)
            };
Triangle t1 = new Triangle(p);
 

 

1.3 클래스 간의 관계 결정하기 - 예제 설명2

class Deck{
    final int CARD_NUM = 52; //카드의 개수
    Card c[] = new Card[CARD_NUM];

    Deck(){ //Deck의 카드를 초기화한다.
        int i=0;

        for(int k=Card.KIND_MAX; k>-; k--){
            for(int n=1; n<Card.NUM_MAX+1; n++){        
                c[i++] = new Card(k, n);
            }
        }
    }
}
Card pick(int index){ //지정된 위치(index)에 있는 카드 하나를 선택한다.
    return c[index%CARD_NUM];
}

Card pick(){ //Deck에서 카드 하나를 선택한다.
    int index = (int)(Math.random() * CARD_NUM);
    return pick(index);
}

void shuffle(){ //카드의 순서를 섞는다.
    for(int n=0; n<1000; n++){
        int i = (int)(Math.random() * CARD_NUM);
        Card temp = c[0];
        c[0] = c[i];
        c[i] = temp;
    }
} //Deck클래스의 끝

public static void main(String[] args){
    Deck d = new Deck();
    Card c = new Card();
    
    d.shuffle();
    Card c2 = d.pick(55);
}
 

1.4 단일 상속(single ingeritance)

- Java는 단일상속만을 허용한다.(C++은 다중상속 허용)

class TVCR extends Tv, VCR{  //이와 같은 표현은 허용하지 않는다.
    //...
}
 

- 비중이 높은 클래스 하나만 상속관계로, 나머지는 포함관계로 한다.

class Tv{
    boolean power; //전원상태(on/off)
    int channel; //채널

    void power() { power = !power;l ]
    void channelup() { ++channel }
    void channelDown() { --channel }
}
class VCR{
    boolean power; //전원상태(on/off)
    int counter = 0;
    void power() { power = !power; }
    void play(){ /*내용 생략*/ }
    void stop(){ /*내용 생략*/ }
    void rew(){ /*내용 생략*/ }
    void ff(){ /*내용 생략*/ }
}

class TVCR extends TV{
    VCR vcr = new VCR();
    int counter = vcr.counter;

    void play(){
        vcr.play();
    }

    void stop(){
        vcr.stop();
    }

    void rew(){
        vcr.rew();
    }

    void ff(){
        vcr.ff();
    }
}
 

 

1.5 Object 클래스 - 모든 클래스의 최고 부모

- 부모가 정의 안된 클래스는 자동적으로 Object클래스를 상속받게 된다.

- 상속계층도의 최상위에는 Object 클래스가 위치한다.

- 모든 클래스는 Object클래스에 정의된 11개의 메서드를 상속받는다.

toString(), equals(Object obj), hashCode(), ...

class Tv{
    //...
}
class CaptionTv extends Tv{
    //...
}
                     ▼
class Tv extends Object{
    //...
}
class CaptionTv extends Tv{
    //...
}
 

 

2. 오버라이딩(overriding)

2.1 오버라이딩이란?(overriding)

"부모클래스로부터 상속받은 메서드의 내용을 상속받는 클래스에 맞게 변경하는 것을 오버라이딩이라고 한다."

*override - vt. '~위에 덮어쓰다(overwrite).', '~에 우선한다.'

class Point{
    int x;
    int y;

    String getLocation(){
        return "x :"+x+", y:"+y;
    }
}

class Point3D extends Point{
    int z;
    String getLocation(){
        return "x:"+x+", y:"+y+", z:"+z
    }
}
 

2.3 오버로딩 vs 오버라이딩

오버로딩(over loading) - 기존에 없는 새로운 메서드를 정의하는 것(new)

오버라이딩(overriding) - 상속받은 메서드의 내용을 변경하는 것(change, modify)

class Parent{
    void parentMethod() {}
}

class Child extends Parent{
    void parentMethod() {} //오버라이딩
    void parentMethod(int i){} //오버로딩

    void childMethod() {}
    void childMethod(int i){} //오버로딩
    void childMethod() {} //에러!!! 중복정의임
}
 

 

2.4 super - 참조변수

▶ this - 인스턴스 자신을 가르키는 참조변수, 인스턴스의 주소가 저장되어있음

           모든 인스턴스 메서드에 지역변수로 숨겨진 채로 존재

▶ super - this와 같음. 부모의 멤버와 자신의 멤버를 구별하는데 사용.

class Parent{
    int x=10;
}
class Child extends Parent{
    int x=20;
    void method(){
        System.out.println("x=" +x);
        System.out.println("this.x="+this.x);
        System.out.println("super.x="+super.x);
    }
}

class Parent{
    int x=10;
}
class Child extends Parent{
    void method(){
        System.out.println("x="+x);    
        System.out.println("this.x="+this.x);
        System.out.println("super.x="+super.x);
    }
}

 

2.5 super() - 부모의 생성자(1/2)

- 자식클래스의 인스턴스를 생성하면, 자식의 멤버와 부모의 멤버가 합쳐진 하나의 인스턴스가 생성된다.

- 부모의 멤버들도 초기화되어야 하기 떄문에 자식 생성자의 첫 문장에서 부모의 생성자를 호출해야한다.

 

Object클래스를 제외한 모든 클래스의 생성자 첫 줄에는 생성자(같은 클래스의 다른 생성자 또는 조상의 생성자)를 호출해야한다.

그렇지 않으면 컴파일러가 자동적으로 'super();'를 생성자의 첫 줄에 삽입한다.

class Point{
    int x;
    int y;
    
    Point(){
        this(0,0);
    }

    Point(int x, int y){
        this.x = x;
        this.y = y;
    }
}
             ▼
class Point extends Object{
    int x;
    int y;

    Point(){
        this.(0,0);
    }

    Point(int x, int y){
        super(); //Object();
        this.x=x;
        this.y=y;
    }
}
 

2.5 super() - 부모의 생성자(2/2)

Point3D(int x, int y, int z){
    this.x=x;
    this.y=y;
    this.z=z;
}
                  ▼
Point3D(int x, int y, int z){
    super(); //Point()를 호출
    this.x = x;
    this.y=y;
    this.z=z;
}
        or
Point3D(int x, int y, int z){
    //조상의 생성자 Point(int x, int y)를 호출
    super(x, y);
    this.z=z;
}

 

3 package 와 import

3.1 패키지(package)

- 서로 관련된 클래스와 인터페이스의 묶음.

- 클래스가 물리적으로 클래스파일(*.class)인 것처럼, 패키지는 물리적으로 폴더이다.

패키지는 서브패키지를 가질 수 있으며, '.'으로 구분한다.

- 클래스의 실제 이름(full name)은 패키지명이 포함된 것이다.

(String클래스의 full name은 java.lang.String)

-rt.jar는 Java API의 기본 클래스들을 압축한 파일

(JDK설치경로\jre\lib에 위치)

 

3.2 패키지의 선언

- 패키지는 소스파일에 첫 번째 문장(주석 제외)으로 단 한번 선언한다.

- 하나의 소스파일에 둘 이상의 클래스가 포함된 경우, 모두 같은 패키지에 속하게 된다.(하나의 소스파일에 단 하나의 public클래스만 허용한다.)

- 모든 클래스는 하나의 패키지에 속하며, 패키지가 선언되지 않은 클래스는 자동적으로 이름없는(unnamed) 패키지에 속하게 된다.

package com.javachobo.book;

public class Packagetest{
    public static void main(String[] args){
        System.out.println("Hello World!");
    }
}

public class Packagedtest2 {}
 

 

3.3 import문

- 사용할 클래스가 속한 패키지를 지정하는데 사용.

- import문을 사용하면 클래스를 사용할 때 패키지명을 생략할 수 있다.

class importTest{
    java.util.Date today = new java.util.Date();
}
                     ▼
import java.util.*;

class ImportTest{
    Date today = new Date();
}
 

 

- java.lang 패키지의 클래스는 import하지 않고도 사용할 수 있다.

String, Object, System, Thread

public static void main(java.lang.String[] args){
    java.lang.System.out.println("Hello World");
}
 

 

3.3 import문의 선언

- import문은 패키지문과 클래스선언의 사이에 선언한다.

일반적인 소스파일(*.java)의 구성은 다음의 순서로 되어 있다.

① package문

② import문

③ 클래스 선언

 

- import문을 선언하는 방법은 다음과 같다.

import 패키지명.클래스명;

 또는

import 패키지명.*;

package com.javachobo.book;

import java.text.SimpleDateFormat;
import java.util.*;

public class PackageTest{
    public static void main(String[] args){
        //java.util.Date today = new java.util.Date();
        Date today = new Date();
        SimpleDateFormat date = new SimpleDateFormat("yyyy/MM/dd");
    }
}

 

3.3 import문의 선언예

- import문은 컴파일 시에 처리되므로 프로그램의 성능에 아무런 영향을 미치지 않는다.

import java.util.Calendar;
import java.util.Date;
import java.util.ArrayList;
                 ▼
import java.util.*;
 

 

- 다음의 두 코드는 서로 의미가 다르다.

import java.util.*;
import java.text.*;
            ▼
import java.*;
 

 

- 이름이 같은 클래스가 속한 두 패키지를 import할 때는 클래스 앞에 패키지명을 붙여줘야 한다.

import java.sql.*; //java.sql.Date
import java.util.*; //java.util.Date

public class ImportTest{
    public static void main(String[] args){
        java.util.Date today = new java.util.Date();
    }
}
 
 
4. 제어자(modifies)
4.1 제어자(modified)란?
- 클래스, 변수, 메서드의 선언부에 사용되어 부가적인 의미를 부여한다.
- 제어자는 크게 접근 제어자와 그 외의 제어자로 나뉜다.
- 하나의 대상에 여러 개의 제어자를 조합해서 사용할 수 있으나, 접근제어자느 단 하나만 사용할 수 있다.
 
접근 제어자 - public, protected, default, private
그     외  - static, final, abstract, native, transient, synchronized, volatile, strictfp
 
4.2 static - 클래스의, 공통적인
static이 사용될 수 있는 곳 - 멤버변수, 메서드, 초기화 블럭
 
제어자 대상 의 미
static 멤버변수 -모든 인스턴스에 공통적으로 사용되는 클래스변수가 된다.
클래스변수는 인스턴스를 생성하지 않고 사용 가능하다.
클래스가 메모리에 로드될 때 생성된다.
메서드 -인스턴스를 생성하지 않고도 호출이 가능한 static메서드가 된다.
static메서드 내에서는 인스턴스멤버들을 직접 사용할 수 없다.

 

class Statictest{
    static int width = 200;
    static int height = 120;

    static { //클래스 초기화 블럭
        //static변수의 복잡한 초기화 수행
    }
    static int max(int a, int b){
        return a > b ? a : b;
    }
}
 
 
 
4.3 final - 마지막의, 변경될 수 없는
- final이 사용될 수 있는 곳 - 클래스, 메서드, 멤버변수, 지역변수
 
제어자 대상 의 미
final 클래스 변경될 수 없는 클래스, 확장될 수 없는 클래스가 된다.
메서드 변경될 수 없는 메서드, final로 지정된 메서드는 오버라이딩을 통해 재정의 될 수 없다.
멤버변수 변수 앞에 final이 없으면, 값을 변경할 수 없는 상수가 된다.
지역변수
final class FinalTest{
    final int MAX_SIZE = 10; //멤버변수

    final void getMaxSize(){
        final LV = MAX_SIZE; //지역변수
        return MAX_SIZE;
    }
}

class Child extends FinalTest{
    void getMaxSize() {} //오버라이딩
}
 
 
4.4 생성자를 이용한 final 멤버변수 초기화
- final이 붙은 변수는 상수이므로 보통은 선언과 초기화를 동시에 하지만, 인스턴스 변수의 경우 생성자에서 초기화할 수 있다.
public static void main(String[] args){
    Card c = new Card("HEART", 10);
// c.NUMBER =5; //에러!!!
    System.out.println(c.KIND);
    System.out.println(c.NUMBER);
}
 

 

 
4.5 abstract - 추상의, 무완성의
abstract가 사용될 수 있는 곳 - 클래스 ,메서드
제어자 대상 의 미
abstract 클래스 클래스 내에 추상메서드가 선언되어 있음을 의미한다.
메서드 선언부만 작성하고 구현부는 작성하지 않은 추상메서드임을 알린다.

[참고] 추상메서드가 없는 클래스도 abstract를 붙여서 추상클래스로 선언하는 것이 가능하기는 하지만 그렇게 해야 할 이유는 없다.

abstract class AbstractTest{ //추상클래스
    abstract void move(); //추상메서드
}
 

 

4.6 접근 제어자(access modifier)

- 맴버 또는 클래스에 사용되어, 외부로부터의 접근을 제한한다.

 

접근 제어자가 사용될 수 있는 곳 - 클래스, 멤버변수, 메서드, 생성자

 

private - 같은 클래스 내에서만 접근이 가능하다.

default - 같은 패키지 내에서만 접근이 가능하다.

protected - 같은 패키지 내에서, 그리고 다른 패키지의 자손클래스에서 접근이 가능하다.

public - 접근 제한이 전혀 없다.

 

4.7 접근 제어자를 이용한 캡슐화

접근 제어자를 사용하는 이유

- 외부로부터 데이터를 보호하기 위해서

- 외부에는 불필요한, 내부적으로만 사용되는, 부분을 감추기 위해서

public static void main(String[] args){
    Time t = new Time(12, 35, 30);
    //System.out.println(t.toString());
    System.out.println(t);
    // t.hour = 13; 에러!!!

    //현재시간보다 1시간 후로 변경한다.
    t.setHour(t.Hour()+1);
    System.out.println(t);
}
 

728x90

'JAVA > 개념' 카테고리의 다른 글

[JAVA] 05. OOP 1(객체 지향 언어)  (0) 2017.08.01
[JAVA] 04. Array (배열)  (0) 2017.07.31
[JAVA] 03. 조건문, 반복문 (Control Statement)  (0) 2017.07.30
[JAVA] 02. 연산자(Operator)  (0) 2017.07.28
[JAVA] 01. 변수(Variable)  (1) 2017.07.28

댓글