1.익명객체, anony


익명객체란 클래스의 객체화 할 때 메소드를 임시로 생성하는 것이다.


실체가 없다고도 하며 한 두번 쓰이고 말 때에 작성한다. 그리고 일반적으로 static 영역에 만들어지지만


익명 개체는 heap영역에 올라간다. 클래스의 특징인 재사용을 할 필요가 없다면 익명객체가 좀 더 효율적이라고 볼 수 있다.



package chap06.exam06.anony;

import chap06.exam05.poly.Common;
import chap06.exam05.poly.CommonImpl;

public class Main {

	public static void main(String[] args) {
		
		// 익명 개체
		// 일반적인 객체 메서드 사용
		CommonImpl impl = new CommonImpl();
		impl.test1();
		
		// 익명 = 이름이 없다. = 실체가 없다. -> 한번만 쓰고 버리는 경우
		// 클래스는 static 메모리에 만들어지는데 익명 개체는 heap영역에 올려짐
		Common com = new Common() {
			
			@Override
			public void test2() {
				System.out.println("TEST 2");
			}
			
			@Override
			public void test1() {
				System.out.println("TEST 1");
			}
		};
		
		// 익명객체 = 단일클래스에서 한번 쓸 경우
		// 여러 클래스에서 객체를 원할 경우는 비효율적이다.
		com.test1();
		com.test2();
	}

}




2.결합도, Coupling


결합도란 클래스가 얼마나 똘똘 뭉쳐있냐라고 할 수 있다.


클래스의 중요한, 기능들을 공유하는 특징을 여러 클래스를 만들어 분산하였다면 결합도가 낮은것이고


한 두개의 적은 클래스 파일에 많은 기능을 집어 넣었다면 결합도가 높은것이다.


결합도가 낮은 코딩이 재사용, 객체지향의 특징을 더욱 살렸다고 보며 상황에 따라 다를 수도 있지만 더 잘 코딩했다고 한다.


특히 결합도가 낮으면 클래스 하나하나가 복잡하지 않고 보기 쉬울것이며


그러한 이유로 유지보수에 좀 더 효율적이라 볼 수 있다.

'개념 및 코딩 > 05.상속' 카테고리의 다른 글

[JAVA]05-05.추상클래스, 인터페이스  (0) 2018.08.30
[JAVA]05-04.다형성 배열, 활용  (0) 2018.08.29
[JAVA]05-03.다형성  (0) 2018.08.29
[JAVA]05-02.오버라이드  (0) 2018.08.27
[JAVA]05-01.상속  (0) 2018.08.24

1.추상 클래스, Abstract


추상 클래스는 클래스나 메소드 선언시에 접근제한자 뒤에 abstract를 입력하여 표시하고 다른 클래스에서 객체화를 할 수 없다.


추상 메소드는 바디를 가지지 않고 다음과 같이 사용한다. public abstract int abcde ( );


{ } -> 바디를 사용하지 않으며 [접근제한자] [abstract] [리턴타입] [함수이름] [매개변수];로 이루어진다.


하지만 모든 변수와 메소드에 추상화를 하지 않아도 된다.


추상 메소드는 바디가 없기 때문에 사용하기 위해서는 오버라이드를 통해서 기능을 설정해야 하고


다른 클래스와 같이 메소드를 선언하여 사용하는것도 가능하다. 이것이 인터페이스와 차이점 중 하나이다.


추상 클래스는 다형성을 통해 선언은 가능하지만 객체화는 불가능하므로 자식 클래스로 객체화 해 주어야 한다.


그리고 상속관계가 있어야 사용이 가능하다.


추상 클래스는 부모클래스로 사용하여 많은 자식클래스들의 공통 될 메소드를 예측하고 틀을 만들어두어 


오버라이드 해서 사용하는 경우가 많고 초기화는 자식 클래스의 객체화시 사용되는 생성자를 통해서 해야한다.


다음 예제를 통해 확인해보자.



먼저 추상 클래스인 세탁기이다. 기본 세탁기 기능을 선언

package chap06.exam02.absmethod;

public abstract class Laundry {
	// 무조건 만들어야 하는 기능들
	public abstract void 세탁하기();
	public abstract void 헹구기();
	public abstract void 탈수();
	
	public void 건조하기() {
		System.out.println("건조 시킵니다.");
	}
}


다음은 세탁기를 상속받는 드럼세탁기 클래스, Alt + Shift + S를 누르면 오버라이드를 자동으로 잡아주는 기능으로 간편하게 할 수 있다.


package chap06.exam02.absmethod;

public class DrumLaundry extends Laundry {
	// 추상 클래스 상속하여 자동 생성된 추상 메서드들
	@Override
	public void 세탁하기() {
		// TODO Auto-generated method stub
		System.out.println("세탁하기");
	}

	@Override
	public void 헹구기() {
		// TODO Auto-generated method stub
		System.out.println("헹구기");
	}

	@Override
	public void 탈수() {
		// TODO Auto-generated method stub
		System.out.println("탈수");
	}

}


마지막으로 메인 클래스


package chap06.exam02.absmethod;

public class Main {

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		DrumLaundry drum = new DrumLaundry(); // Laundry로 다형성으로 생성해도 되지만 새로운걸 추가 할 수 없으므로 왠만하면 자식 클래스를 쓰는게 좋음
		drum.세탁하기();
		drum.탈수();
		drum.헹구기();
		// 추상 클래스의 일반 메서드 호출
		drum.건조하기();
	}

}



2.인터페이스, Interface


추상 클래스가 추상메소드를 선언하고 싶다면 하고 안하고 싶으면 안하는데


인터페이스는 안에 작성된 메소드가 전부 추상화가 된다.


인터페이스의 큰 장점은 상속의 경우 다중 상속이 불가능하여 클래스 하나만 상속이 가능한데


인터페이스를 사용하면 Implements를 사용하여 불러오고 콤마(, )를 사용하여 여러개의 인터페이스를 불러올 수 있다.


자손 클래스에서 인터페이스를 사용하면 인터페이스에 명시한 메소드들을 구현해 두어야 한다.


추상 클래스와 매우 유사한데 다음 표와 예제를 보고 숙지하자.


표는 작성중...



클릭 이벤트 인터페이스 (실제로 클릭 이벤트 담당이 아닌 인터페이스 예를 위한 예제)


package chap06.exam03.inter;

public interface MouseEvent { // 인터페이스
	// 인터페이스에서는 추상메서드에 abstract를 붙이지 않는다.
	public void click(int btn);
	public void dblClick(int btn);
	public double[] move();
	// 인터페이스에서는 일반 메서드를 사용 할 수 없었다.
	// 인터페이스는 jdk 1.8부터 사용가능
	
//	public void wheel(int i) {  //  default/static을 사용하지 않으면 오류발생
//		
//	}
	
	public default void wheel(int i) {   // default를 사용하지 않으면 오류발생
		if(i==1) {
			System.out.println("윗 방향으로 스크롤");
		}else {
			System.out.println("아랫방향으로 스크롤");
		}
	}
	
	public static void setDpi(int dpi) {
		System.out.println("감도 조절 : " + dpi);
	}
}


마우스 이벤트를 받는 Window


package chap06.exam03.inter;
// implements == 구현이라고 부름, 인터페이스만 대상으로 한다.
public class Window implements MouseEvent {

	@Override
	public void click(int btn) {
		System.out.println(btn + "번 버튼 클릭");
	}

	@Override
	public void dblClick(int btn) {
		System.out.println(btn + "번 버튼 더블 클릭");
	}

	@Override
	public double[] move() {
		return null;
	}

}


메인에서 Window를 사용


package chap06.exam03.inter;

public class Main {

	public static void main(String[] args) {
		Window click = new Window();

		click.dblClick(3);
		click.click(1);

		Linux click2 = new Linux();

		click.dblClick(5);
		click.click(4);


		Mac click3 = new Mac();

		click.dblClick(2);
		click.click(8);
		
		// static 사용
		MouseEvent.setDpi(11);
		// 일반(디폴트) 메서드 
		click.wheel(3);


		// 다형성을 이용한 호출 (chap06.exam04.impl)
		MouseEvent aaa;
		aaa = new Window();
		aaa.dblClick(2222);
		aaa = new Linux();
		aaa.dblClick(13);
		aaa = new Mac();
		aaa.wheel(3);
	}

}



'개념 및 코딩 > 05.상속' 카테고리의 다른 글

[JAVA]05-06.익명객체, 결합도  (0) 2018.08.30
[JAVA]05-04.다형성 배열, 활용  (0) 2018.08.29
[JAVA]05-03.다형성  (0) 2018.08.29
[JAVA]05-02.오버라이드  (0) 2018.08.27
[JAVA]05-01.상속  (0) 2018.08.24

1.다형성 배열


일반 변수방(int, String, double 등)에 배열 선언[]을 할 때의 방식처럼


클래스 선언시에도 이용이 가능하다.


배열은 특징이 유사하니 별도의 설명 없이 예제를 보자.


마법사가 3가지의 주문을 외우는 코드로 예를 든다.


주문 클래스

package Chap05.exam08.field;

public class Spell {

	public String casting() {
		return "주문을 외운다.";
	}

}

주문 클래스를 상속받는 마법들

package Chap05.exam08.field;

public class Fire extends Spell {

	@Override
	public String casting() {
		// TODO Auto-generated method stub
		return "화염 " + super.casting();
	}

}




package Chap05.exam08.field;

public class Ice extends Spell {

	@Override
	public String casting() {
		// TODO Auto-generated method stub
		return "얼음 " + super.casting();
	}

}




package Chap05.exam08.field;

public class Light extends Spell {

	@Override
	public String casting() {
		// TODO Auto-generated method stub
		return "빛 " + super.casting();
	}

}


스펠을 배열방식으로 객체화하여 사용


package Chap05.exam08.field;

public class MacroMage {

	public static void main(String[] args) {
		// 한번 실행하면 무조건 세개의 주문이 나가도록 (for문 이용)
		// 배열로 생성해서 객체 생성
		Spell[] mage = new Spell[3];
		
		mage[0] = new Fire();
		mage[1] = new Light();
		mage[2] = new Ice();
		
		for(int i = 0; i < 3; i++) {
			System.out.println(mage[i].casting());
		}
		for(Spell spell : mage) {
			System.out.println(spell.casting());
		}
		
		
//		for(int i = 0; i < 5; i++) {
//			mage = new Light();
//			System.out.println(mage.casting());
//			mage = new Fire();
//			System.out.println(mage.casting());
//			mage = new Ice();
//			System.out.println(mage.casting());
//		}

	}

}


2.활용, 메소드 매개변수에 클래스를 타입으로  설정하기


예전에 설명했듯이 변수 타입 역시 클래스와 같이 구현되고 메소드의 매개변수에 이용할 변수들을 따로 선언해주었다.


그러면 클래스를 직접 선언하고 나서 매개변수에 선언하여 활용 할 수 없을까?


가능하다. 다음 예제를 통해 눈에 익히자.


자동차와 그것을 상속받는 페라리와 마세라티

package Chap05.exam09.refer;

public class Car {
	public void run() {
		
		System.out.println("자동차가 달린다.");
	}
}


package Chap05.exam09.refer;

public class Ferrari extends Car {

	@Override
	public void run() {
		System.out.println("페라리가 달린다.");
}

}



package Chap05.exam09.refer;

public class Maserati extends Car {

	@Override
	public void run() {
		System.out.println("마세라티가 달린다.");
	}

}


운전자 클래스


package Chap05.exam09.refer;

public class Racer {
//	public void drive(Car car) {
//		//Car 형태면 Car가 부모클래스이기 때문에 어떠한 객체라도 다 받을 수 있다.
//		car.run();
//	}
	
	// 다형성을 사용 하지 않을 경우?
	// 각 형태별 메서드를 만들어야 한다.
	// 오버로드를 사용하면 사용자 입자에서는 동일
	
	public void drive(Maserati car) {
		// 다형성을 사용하지 않아 고유의 멤버 사용이 가능
		car.run();
	}
	public void drive(Ferrari car) {
		car.run();
	}
	public void drive(McLarren car) {
		car.run();
	}
}


레이서 클래스를 불러오는 메인 클래스


package Chap05.exam09.refer;

public class Main {

	public static void main(String[] args) {
		// 레이서를 부른다
		Racer man = new Racer();
		Car car1 = null; // 차를 가져온다.
		car1 = new Maserati();
//		man.drive(car1);

		man.drive(new McLarren());
		man.drive(new Ferrari());
	}

}


'개념 및 코딩 > 05.상속' 카테고리의 다른 글

[JAVA]05-06.익명객체, 결합도  (0) 2018.08.30
[JAVA]05-05.추상클래스, 인터페이스  (0) 2018.08.30
[JAVA]05-03.다형성  (0) 2018.08.29
[JAVA]05-02.오버라이드  (0) 2018.08.27
[JAVA]05-01.상속  (0) 2018.08.24

1.다형성


다형성이란 단순하게 부모클래스로 선언하여 자식클래스로 객체화하거나 그 반대를 의미한다.


특징으로는 자식클래스의 기능을 간편하게 이용할 수 있다는게 가장 큰 장점이고 


단점으로는 겹치는 기능들만 사용하도록 기능이 축소되는것이다.


부모클래스로 선언하여 자식클래스로 객체화에는 따로 작업이 필요 없고 (묵시적 형변환, Promotion)


자식클래스에서 부모클래스로 이용을 할 때에는 따로 형변환을 적어줘야 한다. (Casting)


다형성을 사용하면 공간을 효율적으로 사용하고 객체 방을 새로 선언할 수고를 덜어준다.


아래 두가지 예제를 살펴보자



1. 포유류와 조류의 관계에 대한 다형성 예제


package Chap05.exam06.promotion;

/************************************************************
 			-  상속 관계  - 
 		 		Vertebrate
  				l			l
  			Birds			Mamal
 			/ 	l				/  l
 Chicken 	Ducks  Dog    Cat
 
 ************************************************************/

class Vertebrate{}


class Birds extends Vertebrate {}	// 조류
class Mamal extends Vertebrate {}	//포유류


class Chicken extends Birds {}		// 닭
class Duck extends Birds {}			// 오리 

class Dog extends Mamal {}			// 개
class Cat extends Mamal {}			// 고양이

/************************************************************/

public class Promotion {

	public static void main(String[] args) {
		// Promotion : 작은거 -> 큰거
		Vertebrate 척추동물;
		척추동물 = new Dog();
		척추동물 = new Cat();
		척추동물 = new Duck();
		척추동물 = new Chicken();
		
		Mamal 포유류;
		포유류 = new Dog();
		포유류 = new Cat();
		// 닭은 포유류를 상속 받지 않았기 때문에 Promotion 불가
		// 포유류 = new Chicken();  // 오류 발생
	}

}










2. Mamal클래스를 상속받은 Cat, Dog 클래스에 대한 Casting 예제


포유류

package Chap05.exam07.cast;

public class Mamal {

	public void birth() {
		System.out.println("새끼를 낳다.");
	}
	public void eat() {
		System.out.println("젖을 먹이다.");
	}
	
}

고양이

package Chap05.exam07.cast;

public class Cat extends Mamal {

	@Override  // 부모로부터 온 것이기 때문에 Promotion시 유지된다.
	public void birth() {
		System.out.println("4마리를 낳는다.");
	}

	// 원래 내 것은 Promotion시 사용하지 못 한다.
	public void mew() {
		System.out.println("냥");
	}
	
}


package Chap05.exam07.cast;

public class Dog extends Mamal {

	@Override  // 부모로부터 온 것이기 때문에 Promotion시 유지된다.
	public void birth() {
		System.out.println("5마리를 낳는다.");
	}

	// 원래 내 것은 Promotion시 사용하지 못 한다.
	public void bark() {
		System.out.println("멍멍 짖는다.");
	}
	
}

Casing 예

package Chap05.exam07.cast;

public class Cast {

	public static void main(String[] args) {


		// Promotion
		Mamal mamal = new Dog();
		mamal.birth();
		mamal.eat();
		//mamal.bark(); // Promotion 했기 때문에 자기것은 사용 불
		
		// bark나 mew를 사용하고 싶을 경우 Casting 사용
		Dog 댕댕이 = (Dog) mamal;
		댕댕이.bark();
		
		mamal = new Cat(); // 다시 Promotion을 해주어 바꿔야 오류가 나지 않음
		Cat 나비 = (Cat) mamal;
		나비.mew();
		
		// 상속받은 객체가 많은 경우 누가 누군지 헷갈리게 된다.
		// instanceof (bool값 반환) 를 사용하면 본래 객체를 확인 할 수 있다.
		if(mamal instanceof Cat) {
			나비 = (Cat) mamal;
			나비.mew();
		} else {
			System.out.println("고양이 객체가 아니에요");
			댕댕이 = (Dog) mamal;
			댕댕이.bark();
		}
		
	}

}


'개념 및 코딩 > 05.상속' 카테고리의 다른 글

[JAVA]05-06.익명객체, 결합도  (0) 2018.08.30
[JAVA]05-05.추상클래스, 인터페이스  (0) 2018.08.30
[JAVA]05-04.다형성 배열, 활용  (0) 2018.08.29
[JAVA]05-02.오버라이드  (0) 2018.08.27
[JAVA]05-01.상속  (0) 2018.08.24

1.오버라이드, Override


흔히들 비교를 많이하는 오버로딩의 친구 오버라이드는


오버로딩이 클래스 내부에서 같은 이름의 메소드를 여러개 선언한다면


오버라이드는 상속받은 메소드의 이름을 같게 하여 새로 튜닝한다고 이해하면 된다.


그리고 final로 선언된 메소드는 전에 설명한것과 같이 상속 받을 수 없고 오버라이드 또한 불가능하다.


다음 예제를 확인해보자



package Chap05.exam04.tune;

public class ParentCar {
	public void Start() {
		System.out.println("시동");
	}
	public void run() {
		System.out.println("시속 50km/h으로 달립니다.");
	}
	public void Stop() {
		System.out.println("정지");
	}
	public final void test() {
		System.out.println("자체 점검");
	}
}
package Chap05.exam04.tune;

public class MyCar extends ParentCar {
	
	boolean sw = false;
	
	// 오버라이드 (ctrl + shift + s의 Override로 내용을 완전히 바꿈)
	@Override
	public void run() {
		// super.run();
		System.out.println("시속 30km/h으로 달립니다.");
	}

	
	// 오버라이드 (상황에 따라)
	@Override
	public void Stop() {
		// super.Stop();
		if(sw) {
			System.out.println("정지 후 자동 주차");
		}else{
			super.Stop();
		}
		
	}

}
package Chap05.exam04.tune;

public class Main {

	public static void main(String[] args) {
		MyCar k3 = new MyCar();
		k3.Start(); // 부모 클래스 
		k3.run(); // 자식 클래스에서 오버라이드 한 내용
		k3.Stop(); // 부모 클래스
		k3.sw = true;
		k3.Stop(); // 자식이 바꾼 내용
	}

}


'개념 및 코딩 > 05.상속' 카테고리의 다른 글

[JAVA]05-06.익명객체, 결합도  (0) 2018.08.30
[JAVA]05-05.추상클래스, 인터페이스  (0) 2018.08.30
[JAVA]05-04.다형성 배열, 활용  (0) 2018.08.29
[JAVA]05-03.다형성  (0) 2018.08.29
[JAVA]05-01.상속  (0) 2018.08.24

1.상속, Inheritance


상속은 단어 그대로의 의미는 부모의 유산을 자녀가 상속하다. 라고 할 때 쓰이는데


Java에서는 다른 클래스의 기능을 그대로 이어받는, 변수와 메소드들을 그대로 사용 가능한 것을 말한다. 부모클래스의 선언 없이 메소드와 


변수를 자식 클래스에서 사용 할 수 있다. 다른 말로는 일반화라고 하기도 한다.


상속을 사용하는 이유는 다른 사람의 코드를 가져다 쓰기 쉽고 코드의 중복을 피하기 쉽고


다른 사람의 코드를 가져다 쓴다면 내가 생각하지 못한 기술들을 활용할 수 있다.


하지만 앞에서 설명했던 접근제한자를 보면 private로 선언하게 되면 상속받아도 사용할 수 없게끔 할 수 있다.


그리고 C++에선 다중상속이 허용되지만 Java에서는 사용할 수 없다. 사용하기 위해선 클래스마다 하나씩 하나씩 상속하는 방법밖에 없다.


만약 자식클래스를 호출한다면 컴파일러는 우선 부모클래스를 호출 하고나서 자식 클래스를 호출하고 부모 클래스의 생성자는 생략한다.


그러므로 자식 클래스에서 부모 클래스의 생성자를 이용하기 위해 따로 명시를 해두어야 한다.


이제부터는 클래스 다이어그램도 예제와 같이 올리는데


꼭 클래스 다이어그램을 통해 클래스의 구조를 파악하는 방법을 확인하고 나서 예제를 살펴보자





예제는 다음과 같다.



package Chap05.exam03.superCtr;

public class Parent {
	
	public String attr1;
	public int attr2;
	
	public Parent(String attr1, int attr2) {
		this.attr1 = attr1;
		this.attr2 = attr2;
	}

}


package Chap05.exam03.superCtr;

public class Child extends Parent {
	public String field;
	public Child(String attr1, int attr2, String field) {
		super(attr1, attr2); // 상속해준 부모 클래스에 생성자 인자값 전달
		this.field = field;
		
	}

}


package Chap05.exam03.superCtr;

public class Main {

	public static void main(String[] args) {
		Child kid = new Child("널", 2147483647, null);
		System.out.println(kid.attr1);
		System.out.println(kid.attr2);
		System.out.println(kid.field);
	}
}


'개념 및 코딩 > 05.상속' 카테고리의 다른 글

[JAVA]05-06.익명객체, 결합도  (0) 2018.08.30
[JAVA]05-05.추상클래스, 인터페이스  (0) 2018.08.30
[JAVA]05-04.다형성 배열, 활용  (0) 2018.08.29
[JAVA]05-03.다형성  (0) 2018.08.29
[JAVA]05-02.오버라이드  (0) 2018.08.27

+ Recent posts