자바

JAVA STEP 27. Inheritance, Static

IT의 큰손 2023. 2. 20. 20:41
728x90

★ Inheritance

  • 객체 지향 프로그래밍(Object Oriented Programing) 
    • 클래스 > 객체 중심의 프로그래밍 방식
  • 상속 (Inheritance)
    • 부모가 가지는 재산을 자식에게 물려주는 행동
    • 부모(클래스)가 가지는 재산을 자식(클래스)에게 물려주는 행동
  • 상속하는 이유?
    • 비용 절감
    • 코드 재사용
  • 상속관계에 있는 클래스 호칠
    • 부모 클래스 <- 자식 클래스
    • 슈퍼 클래스 <- 서브 클래스
    • 기본 클래스 <- 확장 클래스
    • 기본 클래스 <- 파생 클래스
  • 소스코드
  •  
class Parent {
	
	public int a;
	public int b;
	
	public void ccc() {
		System.out.println("ccc");
	}
}

//클래스 상속(extends Parent)
//- childe > 자식 클래스
//- Parent > 부모 클래스
//- 부모클래스(Parent)가 가지는 모든 멤버를 자식클래스(Child)에게 물려준다.
class Child extends Parent {
	
	public int d;
	public int e;
	
	public void fff() {
		System.out.println("fff");
	}
}
  • 예제 1) 요구사항 : 회원가입 사이트 일반 회원, 관리자 회원
  • 소스코드
  •  
class User {
	
	public String name;
	public String id;
	public String pw;
	public String email;
}

class Administrator {
	public String name;
	public String id;
	public String pw;
	public String level;
}

class Member {
	
	public String name;
	public String id;
	public String pw;
	
}

class User extends Member {
	
	public String email;
}

class Administrator extends Member {

	public String level;
}

class Temp extends Member {
	
	public String exDate;
}

 

★ OBJECT 클래스

  • 개발자가 만드는 모든 클래스는 따로 상속하지 않으면, 자동으로 object클래스를 상속받는다.
  • 모든 클래스들의 근원이 되는 클래스 > Root Class
  • 모든 클래스는 Object 클래스로부터 파생된다.
  • 소스코드
  •  
//상속을 명시하지 않은 클래스 선언은 자동으로(100%) Object 클래스를 상속받는다.
class Test { //extends Object
	
	public int a;
	
}

class Test2 extends Test {
	
	public int b;
}

 

★ Overriding

  • 메소드 오버로딩(Method Overloading)
    • 메소드 이름 동일 x N개 생성
  • 메소드 오버라이딩(Method Overriding)
    • 기각하다, 우선하다
    • 클래스 상속 시에 발생
    • 메소드 재정의 > 상속 받은 메소드를 수정하는 기술
  • 소스코드
  •  
//아빠 + 아들 마주친 상황
		
		OverridingParent hong = new OverridingParent();
		hong.name = "홍길동";
		hong.hello();
		
		OverridingChild jhong = new OverridingChild();
		
		jhong.name="홍철수";
		
	
		
//		jhong.hi();	//자신만의 방식
//		jhong.hello(); //자식 객체의 행동을 모호하게
		
		//- 자식이 선언한 hello()가 호출된다.
		//- 부모가 선언한 hello()는 호출이 불가능하다.
		jhong.hello(); //메소드 다시 만든것처럼 .. > 메소드 재정의
		
		
		//*** 내가 문제;;
		//- 이전에는 같은 핏줄인 홍길동과 홍철수가 모두 hello()를 사용해서 인사
		//	> 같은 상속의 클래스(객체는) > 인사 메소드 > hello()
		//- 지금은 같은 집안이라도 아빠는 hello(), 아들이 hi()
        
        //상황] 동네 사람
//- 아빠
class OverridingParent {
	
	public String name;
	
	public void hello() {
		System.out.printf("안녕하세요. 좋은 아침입니다. 저는 %s 입니다.\n", this.name);
	}
}

//- 아들
class OverridingChild extends OverridingParent {
	
	//4살 꼬맹이 > 시간이 흘러.. > 중 2학년
	
	//아빠의 인사 방식 불만 > 자기 방식대로 인사를 하고 싶다. 
	// > 아빠의 방식을 그대로 사용 이유 > hello()를 상속받았기 때문
	
	//**** 클래스 상속 > 부모가 물려준 멤버를 자식을 상속 거부할 능력이 없다.
	//				> 무조건 100% 상속
	
	//****** 부모로부터 상속받은 메소드가 맘에 안든다고, 아래처럼 동일한 일을 하는 메소드를 따로 구현하면 절대 안된다. 
	//> 나중에 객체 사용시 어떤 메소드가 올바른 메소드인지 구분할 수 가 없다.
//	public void hi() {
//		System.out.printf("Hello~ My name is %s\n", this.name);
//	}
	
	//자식 객체내에는 hello() 메소드가 2개 있다.
	//- 부모로부터 상속받은 hello()
	//- 자신이 선언한 hello()
	
	//부모가 물려준 메소드와 동일한 형식의 메소드를 선언 
	//- 부모의 메소드를 무시하고 자식의 메소드를 사용한다.
	//- 부모의 hello() 더이상 자식에서는 필요가 없다고 판단.
	//- 메소드 덮어쓰기
	public void hello() {
		System.out.printf("Hello~ My name is %s\n", this.name);
	}
	
}

 

★ toString

  • object가 물려준 메소드로, 덤프 전용 메소드이다.
  • 객체를 문자 메소드로 바꿔주는 메소드
  • 소스코드
  •  
Calendar c1 = Calendar.getInstance();
		System.out.println(c1);
		System.out.println(c1.toString());
		
		Date d1 = new Date();
		System.out.println(d1);
		System.out.println(d1.toString());
        
public String toString() {
		return "Time [hour=" + hour + ", min=" + min + "]";
	}

 

★ final 

  • 한번 결정하면 바꿀 수 없다.
  • 1. 변수 적용
    • 지역 변수
    • 멤버 변수
    • 변수값 수정 금지 > 안정성
  • 2. 메소드 적용
    • 상속 + 오버라이딩
    • 오버라이딩 금지 > 안정성
  • 3. 클래스 적용
    • 상속
    • 상속 금지 > 안정성
  • 소스코드
  •  
class Gender {
	
	//남자(1), 여자(2)
	public final int MALE = 1;
	public final int FEMALE = 2;
	
	final public int AAA = 3;
	//final 이랑 접근지정자 이름이 바뀌어도 된다
	
	public Gender() {
		
		//this.MALE = 3;
		
	}
}

class FinalParent {
	
	//부모 클래스 설계 중..
	//- test() 메소드 > 나중에 이 클래스를 상속받는 클래스가 test() 메소드를 재정의하면 문제가 발생할거 같음
	
	public void test() {
		System.out.println("부모가 만든 메소드");
		System.out.println(num()); //100출력
	}
	
	public final int num() {
		return 100;
	}
	
}

class FinalChild extends FinalParent {
	
	//이클립스 > 오버라이딩
//	@Override
//	public void test() {
//		
//		System.out.println("자식이 재정의한 메소드");
//		System.out.println(num()); //200 출력
//	}
	
	//Cannot override the final method from FinalParent
//	public int num() {
//		return 200;
//	}

 

★ Static

  • 클래스 로딩, Class Loading
    • 프로그램을 실행하기 전에, 프로젝트 내의 모든 클래스의 정의를 미리 읽어서, 메모리에 올려놓는 작업
    • 설계도를 미리 읽어서 언제든지 사용가능하게 메모리에 올려놓는 작업
    • 클래스 로딩 과정 중에 클래스 내부에 있는 모든 static 키워드 검색
  • Static 키워드
    • 멤버 변수, 멤버 메소드, 클래스
    • 정적 메소드
    • 정적 메소드(static)안에서는 this를 사용할 수 없음.
    • 정적 메소드 내에서는 static 변수만 접근 할 수 있다.
    • 소스코드
    •  
class Student {
	
	//객체 멤버 변수
	private String name;
	private int age;
	
	//private String school;
	
	//정적 멤버 변수, 공용 멤버 변수, (클래스 멤버 변수)
	//모두 동일 한 값을 중복되어 주려고 할 때, static을 사용
	private static String school;
	
	
	//*********************************
	
	
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}

	//*********************************
		
	public int getAge() {
		return age;
	}
	public void setAge(int age) {
		this.age = age;
	}

	//*********************************
		
//	public String getSchool() {
//		return school;
//	}
//	public void setSchool(String school) {
//		this.school = school;
//	}
	public static String getSchool() {
		return school;
	}
	public static void setSchool(String school) {
		Student.school = school;
	}

	//*********************************
		
	@Override
	public String toString() {
		return "Student [name=" + name + ""
				+ ", age=" + age + ""
				+ ", school=" + school + "]";
	}
  • 예제2 )
  • 소스코드
  •  
package com.test.obj.inheritance;

public class Ex56_static {

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		StaticStudent.setSchool("역삼 중학교");
		StaticStudent s1 = new StaticStudent();
		s1.setName("홍길동");
		
		StaticStudent s2 = new StaticStudent();
		s2.setName("아무개");
		
		//hello() 앞에 s1이 적혀있다.
		// > s1이라는 학생이 인사를 합니다. > 개인이 하는 행동
		//s1.hello(); //안됨.
		
		//hello() 앞에 Student가 적혀있다.
		// > 학생(Student) 전체가 인사를 합니다. > 집단이 하는 행동
		StaticStudent.hello(); //됨
	}

}

class StaticStudent {
	
	private String name; 			//개인 데이터
	private static String school; 	//공용 데이터
	
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public static String getSchool() {
		return school;
	}
	public static void setSchool(String school) {
		StaticStudent.school = school;
	}
	
	//학생에게 인사하는 메소드
	// 집합 전체를 대표하는 데이터나 메서드 > static
	public static void hello() {
	
		//System.out.printf("안녕하세요. 저는 %s입니다.\n", name); //개인 데이터
		System.out.println("안녕하세요. 역삼중학교에 오신 것을 환영합니다.");
		
	}
	
	public void hello2() {
		
		System.out.printf("안녕하세요. 저는 %s입니다.\n", this.name); 	//개인 데이터
		//System.out.println("안녕하세요. 역삼중학교에 오신 것을 환영합니다.");
		System.out.printf("저는 %s에 다녀요.\n", StaticStudent.school); //공용 데이터
		
	}
}

 

728x90