국비학원 9일차 : 다형성, 추상클래스, 인터페이스

Digeut·2023년 3월 7일
0

국비학원

목록 보기
9/44

다형성

조상클래스 타입의 참조변수로 자손클래스의 인스턴스를
참조할수 있도록 하는 것, 참조변수의 형변환

A(부모클래스) { a b c }로 생성된 인스턴스는 a b c만 가짐
B(자손클래스) {(a b c) d e} 로 생성된 인스턴스는 a~e까지 가진다
C(자손클래스) {(a b c) 1 2}

일반 데이터 타입의 경우 범위가 작은타입을
범위가 넓은 곳으로 넣을때 자동 형 변환이 된다.
ex) short타입 -> int 타입 /단, short→char은 범위가 달라서 안된다.

클래스 B → 클래스 A로 형변환은 자동으로 형 변환
: B로는 A를 전부 표현(설명)이 가능한지 여부가 중요하다!
클래스 C → A로 형변환은 자동으로 형 변환
B클래스 {(a b c) d e}로 A클래스 { a b c } 설명 가능하다

🔴코드에 포함된 바라보는 범위에 대한 설명

class SuperClass{//부모 클래스
	int number1;
	int number2;
	
	//생성자 만들기
	SuperClass(int number1, int number2){
		this.number1 = number1;
		this.number2 = number2; 
        //인스턴스와 매개변수 이름 같을때 구분 this!
	}
    
	//기본 생성자를 만들었으면 밑에 자손 클래스의 기본생성자를 만들지 않아도 되고
	//기본 생성자 말고 값을 넣는 생성자를 만들었기때문에 밑에 
    //자손 클래스에 오류가 뜨게된다(따로 자손 클래스도 생성자 만들어줘야한다)
	
    //메서드
	void method1() {}
	void method2() {}
}
class SubClass1 extends SuperClass{ //자손 클래스
	int number3;
	
    //생성자
	SubClass1(int number1,int number2, int number3){ 
		super(number1, number2);
		this.number3 = number3;
	}
	
	void method3() {}
}
class SubClass2 extends SuperClass{//자손 클래스2
	int number4;
	
    //생성자
	SubClass2(int number1,int number2){ 
		super(number1, number2);
	} 
    
    //인스턴스(number4)랑 메서드(method4) 선언했는데 
    //아까 수업할때 주석처리하고 지운 다음에 적용을 안한듯..?
	
	void method4() {}
	
	@Override //SuperClass의 method1을 받아와서 수정함.
	void method1() {
		System.out.println("Override!");
	}
}

public class Polymorphism {

	public static void main(String[] args) {
		
        //인스턴스 생성
		SuperClass superClass = new SuperClass/*참조변수?*/(1, 2); 
		SubClass1 subClass1 = new SubClass1(11, 22, 33);
		SubClass2 subClass2 = new SubClass2(111, 222);

		//자손타입 -> 조상타입 (Up casting) : 자동 형변환 가능
		SuperClass super1 = subClass1; 
        //자손이 부모를 다 표현할수 있기때문에 자동 형변환
        //자손클래스의 범위가 넓으므로 다 설명!
        
		//🤔바라볼수 있는 범위가 달라지는거다..????????
		//🔴super1이 subClass1을 바라보게 만들었다.
        
		SuperClass super2 = subClass2;
		//super2가 subClass2을 바라보게 만들었다.
		
		System.out.println(subClass1.number3); //33
		System.out.println(subClass1); //🟡같은 주소
		System.out.println(super1); //🟡같은 주소
		
		
		//참조변수의 형 변환을 한다고 하더라도 
        //인스턴스가 가지고 있는 데이터에는
		//아무런 영향을 미치지 않는다.
		//단지 인스턴스의 사용 '범위'를 조절하는것.
		SubClass1 sub1 = (SubClass1) super1;
		//sub1이 super1(subClass1을 보고있음)을 바라보게 만들었다
		//subClass1, super1, sub1 전부 같은 곳을 바라보고 있다.
        //그래서 모두 number3의 크기가 33이 출력된다.
		
		System.out.println(sub1.number3); //33
		System.out.println(sub1); //🟡같은 주소
		
		super2.method1(); //실제 인스턴스 값이 나온다.?
		//SuperClass의 method1을 SubClass2에서 오버라이드한것을
		//상속받아서 사용한것인데 이 실제 인스턴스 값은 변하지 않았단것을 나타낸다🤔
		
		//조상타입 -> 자손타입 (Down casting) : 자동 형변환 불가능
//		SubClass1 sub1 = superClass; //타입미스매치 오류뜬다
//		SubClass2 sub2 = superClass; //타입미스매치 오류뜬다 
//		SubClass2안의 내용을 다 지워도 상속 받을수 없다(명시적 형변환 해야한다)
		
//		SubClass1 sub1 = (SubClass1)superClass; //명시적 형변환 
//		이거 오류떠서 주석처리함
//		SubClass2 sub2 = (SubClass2)superClass; 
		
		
	}

추상클래스

추상 메서드가 포함되어 있는 클래스
⭐추상클래스로 인스턴스를 생성할 수 없다!

//사용방법:
//abstract class 클래스명 {}
abstract class Abstract{ //추상클래스
	int number1;
	
	//void method1() {}
	//추상메서드 
	//선언부만 작성이 되어있고 구현부는 작성되어 있지 않은 메서드
	//⭐해당 클래스를 상속받은 자손클래스에서 구현을 필수로 요구함
	
	//사용방법:
	//abstract 반환타입 메서드명(매개변수); '{}'쓰지않는다!
	abstract void method1(); //추상메서드로 만들어줌.
}

class SubClass extends Abstract{
	
    @Override //method1
    void method1() { 
		System.out.println("구현!");
	}
}

public class AbstractClass {

	public static void main(String[] args) {
		//Abstract abstract1 = new Abstract(); 
        //인스턴스화 할수 없다고 뜬다.
        //추상클래스는 자체적으로 객체 생성할수 없다!
		
        Abstract abstract1 = new SubClass(); 
        //상속받아서 메서드 구현했기때문에 이제 참조변수로 
        //받아서 사용할수있게됐다.
		//SubClass(자손클래스)은 Abstract(부모클래스)을 
        //상속받아서 참조변수로 받아와 인스턴스 생성이 가능하다
	}

}

인터페이스

추상클래스보다 추상화 정도가 높은 존재
기능을 구현할 적에 인터페이스를 구현해놓고 작성 시스템 설계에 많이 쓰인다.
⭐추상 클래스와 다르게 일반 메서드와 일반 멤버변수를 가질 수 없다!!!
추상클래스 보다 더 추상적으로 기능만을 제공한다
단순히 정의만 해놓은것. 변수를 넣지 못하고 상수만 입력

//사용방법:
//interface 인터페이스명{ }
interface ExampleInterface{
	//변수를 사용할 때는 public static final 형태로만 사용할 수 있다.
	public static final int NUMBER = 10 ; 
    //static변수는 무조건 초기화도 같이 해줘야 한다.
	
	//메서드를 사용 할 때는 public abstract로 선언해야 함
	//인터페이스 내의 메서드는 추상메서드이기때문에 
    //구현부 없이 사용할수 있다! -> 스프링할때 쓰게된다
	1️⃣public abstract void method1();
	2️⃣public void method2(); /*private 은 올 수 없다*/ 
    //메서드의 경우 abstract을 빼도 인식은 된다.
	3️⃣void method3(); //세가지 방식 표현 다 가능
} 

//인터페이스 간의 상속
//인터페이스의 경우 ,를 써서 다중 상속이 가능

//인터페이스는 클래스와 개념자체가 다르다
//구현이 되어있냐 아니냐의 차이에 따라서 상속이 되고 안되고를 
//결정하게 된다.(클래스와 인터페이스의 차이)
//자바에서는 다중상속을 허용하지 않는데 인터페이스에서는 허용한다
//구현이 다른 위치에서 되니까 충돌 할게 없으니 다중상속을 허용한다
//인터페이스는 필드가 포함되어 있지않으므로 상태의 다중상속을 가능하게한다

interface SubExampleInterface extends ExampleInterface{
	
}

//인터페이스 구현
// 인터페이스도 추상 메서드를 포함하고 있기 때문에 
// 해당 메서드를 구현하는 클래스를 통해서 인스턴스를 만들어 줘야한다.
// 인터페이스를 클래스로 구현할 때는 'implements' 키워드를 사용한다
class Implement implements ExampleInterface{ 
//Implement란 클래스로 인터페이스 구현 가능

	//인터페이스는 클래스 내에서 오버라이딩해서 사용
	@Override //Implement빨간줄 떠서 add ~누르면 오버라이드 추가된다
	public void method1() {
		System.out.println("메서드1");
		
	}

	@Override
	public void method2() {
		System.out.println("메서드2");
		
	}

	@Override
	public void method3() {
		System.out.println("메서드3");
		
	}
	
}

public class Interface {

	public static void main(String[] args) {
		//인터페이스 자체로 인스턴스를 생성 할 수 없음
		//ExampleInterface exampleInterface = new ExampleInterface(); 
        //이렇게는 쓸수 없다. implemnets 통해서 클래스 만들어야 구현!
		ExampleInterface exampleInterface = new Implement(); 
        //클래스 만들어서 구현 했으므로 사용가능
	}

클래스와 인터페이스 비교 이해에 참고한 글

https://ryulib.tistory.com/76

응집도와 결합도

모듈화(Modularization) 란 소프트웨어를 각 기능별로 나누는 것을 말한다.
각각의 기능별로 나눠진 모듈화의 결과를 모듈(Module) 이라고 하며 서브루틴(Subroutine), 소프트웨어 내의 프로그램 또는 작업 단위 등의 의미로 사용된다.
여기서 좋은 모듈화는 목적에 맞는 기능만으로 모듈을 나누는 것이다. 각각의 모듈은 주어진 기능만을 독립적으로 수행하며 다른 모듈과 적게 연관돼야 한다.

즉, 독립성이 높은 모듈일수록 좋다. 독립성이 높으면 해당 모듈을 수정하더라도 다른 모듈에 끼치는 영향이 적으며 오류가 발생하더라도 쉽게 문제를 발견하고 해결할 수 있는 장점을 갖는다.

한편 모듈의 독립성은 모듈의 결합도(Coupling)과 응집도(Cohesion)로 측정한다. 결론적으로는 모듈의 독립성을 높이기 위해서는 모듈 간의 상호 의존 정도를 나타내는 결합도를 낮추고(DIP관련) 모듈이 독립적으로 자체 기능만을 수행하도록 응집도(SRP관련)를 높여야 한다.

결합도 : 결합도는 서로 다른 모듈 간에 상호 의존하는 정도 또는 연관된 관계. 결합도가 높은 클래스는 다른 클래스와 연관된 정도가 높다. 따라서 해당 클래스를 변경하면 연관된 클래스도 변경해야 하며, 다른 코드에서 클래스를 재사용하기도 어렵다.

응집도 : 한 모듈 내부의 처리 요소들이 서로 관련되어 있는 정도를 말한다. 즉, 모듈이 독립적인 기능을 수행하는지 또는 하나의 기능을 중심으로 책임이 잘 뭉쳐있는지를 나타내며 모듈이 높은 응집도를 가질수록 좋다.

출처 : https://madplay.github.io/post/coupling-and-cohesion-in-software-engineering

profile
개발자가 될 거야!

0개의 댓글