냥코딩쟝
1. [static 키워드]에 대해서 설명하세요. 
   - 키워드와 식별자
   - 사용할 수 있는 곳 : 클래스, 메서드, 필드
       ㄴ  1)중첩 클래스에서만 사용할 수 있다. X
       ㄴ  2) static 변수 == 클래스 변수 == 정적 변수 == 공유(shared) 변수
                  변수 3가지 종류
                  ㄱ. 지역변수
                  ㄴ. 인스턴스 변수
                  ㄷ. 클래스변수
                  - 필드를 선언할 때 왜 사용하는 가 ? static 필드 로 선언한다. 
                      - Save 클래스의 rate 필드를 왜 static 변수로 선언했는지 생각을 해 보시면 될거 같아요.
                      모든 Save의 객체(인스턴스)가 공유되는  이자율을 필드로 가지고 있을 필요가 없어요. 
                      생성되는 객체 마다 8바이트 이자율 기억공간을 가지고 있을 필요가 없어요. 
                  - 선언 형식
                       public [static] double rate;
                   - 생성시기/ 소멸시기
                   프로그램 시작될 때  클래스 (Save) 가 로딩되고 그 때 인스턴스를 생성하지 않아도 
                   자동으로 static 필드는 메모리에 할당 된다. 
                   프로그램 종료될 때.... 
                  
       ㄴ  3). static 메서드
                  - static 메서드는 왜 필요한가 ?
                    1)  static 필드를 사용하기 위해서.
                          private static double rate;
                         public static getter, setter
                     2) 인스턴스를 생성하지 않고도 클래스명으로 간편히 사용할 수 있도록 메서드를 선언하기 위해서.
                         자주 사용되는 메서드 .  인스턴스 변수를 사용하지 않는 메서드 라면 
                         static 메서드로 선언을 한다.
                         Math 클래스 안의 모든 메서드는 static 메서드 이다..  
                         Math.abs();
                         Math.random();
                   - static 메서드 선언 형식
                       public static void getXXX(){
                          
                       } 
                    -  생성시기 / 소멸시기           
                    -  클래스명.static메서드()
                    -  지역변수 O,
                        인스턴스변수 X    
  
  ㄷ. 클래스 변수에 접근하는 방법
                *** 클래스명.static필드명 ***
                
                객체명.static필드명  - 가능
                만약에 private 로 선언되어 있다면 
                getter, setter 선언- static 메서드로 선언
                클래스명.static 메서드() 호출.
                
  ㄹ. 기타

10:10 수업 시작~ 
2.  "가변인자와 오버로딩"에 대해서 설명하세요.
    1) 오버로딩
    int sum(int a, int b);
    int sum(int a, int b, int c);
    int sum(int a, int b, int c, int d );
    5정수, 6정수, 7정수 ....
    오버라이딩 X
    => 
    int sum( int [] m )  선언
    
    2) JDK 1.5  가변인자 추가.
                     자료형...매개변수
    int sum(  int... args         ){
    }   
    
    내부적으로  int[] 로 처리.
    효율적 X
    주의할 점 )  선언 위치.
    String a, String... args  제일 끝에 가변인자 1번 선언

3. 필드(멤버변수)를 초기화 하는 방법 및 우선 처리 순위에 대해서 설명하세요
    - 초기화 ?  변수을 값을 처음으로 할당하는 것.
    int a = 10;  // 초기화    
    int b ;
    b = 20;  // 초기화
    
    - 지역변수는 초기화를 하지 않으면 에러발생.
    - 필드는 초기화를 하지 않으면 각 자료형의 기본값으로 설정. ( 초기화 X )
    
    1) 명시적 초기화
    2) 초기화 블럭
        인스턴스 초기화 블럭
        클래스 초기화 블럭
    3) 생성자
    
    초기화 순서 
    
4. 클래스 간의 관계에 대해서 설명하세요 .
    1)  has - a  관계 
         -    Car 클래스와 Engine 클래스 간의 관계..
         class Car{
            Engine engine ;   // = new Engine(); // 좋은 코딩 X
            왜? 결합성이 높은 코딩은 좋은 코딩이 안니다. 
            예) 십자 드라이버   +  ( 일체형 )        
            Car( Engine engine){
               this.engine = engine;
            }  
            
            public void setEngine( Engine engine){
               this.engine = engine;
            }
         }
         - 의존성 주입( DI )
           1)  생성자
           2)  setter
        
    2)  is -a 관계( 상속 관계)

5. 상속(inheritance)에 대해서 설명하세요 
  ㄱ. 정의 :  기존클래스 -> 재사용 -> 새로운 클래스 .
                    Super                            Sub  ***
                    this 키워드    = 클래스(객체, 인스턴스) 자기 자신의 주소값을 가지는 참조변수
                    super 키워드 = 클래스(객체, 인스턴스) 부모의 주소값을 가지는 참조변수
                    
                    부모                                자식
                    기초                               파생
                    상위                               하위
  ㄴ. 장점 :  코드량 , 재사용 -> 생산성,  유지,보수 용이 등등
  ㄷ. 선언형식 :  extends Super클래스{
  }
  
6. 모든 클래스의 최상위 부모클래스는 ?  java.lang.Object

       class Ex04{
          // 필드 x
          // 메서드 X
       }
       
       Ex04 obj = new Ex04();
       obj.9개의 메서드 멤버로 보여요..      - Object
       자바 컴파일러가 자동으로 extends Object를 추가해서 컴파일 한다. 

7. 오버로딩(overload)과 오버라이딩(override)에 대해서 설명하세요 .
    1) 오버로딩
        함수명동일하고    매개변수 타입이나 갯수가 다른 중복선언된 함수..
        중복함수
        리턴자료형 X
        
    2) 오버라이딩
       부모클래스로 부터 상속받은 메서드를 재정의하는 함수
       재정의 함수
         Shape 도형
         void draw(){
             syso [color='black]
          }
          class Circle  extends Shape      
         @Override 애노테이션 위에 붙였어요..
         void draw(){
             syso  [center, radius]
         }


-- 이전 복습 --
8. this 키워드에 대해서 설명하세요 
   ㄱ. 정의 
   ㄴ. 용도 3가지

9. 생성자(constructor)에 대해서 설명하세요    

10. 클래스 앞과 멤버 앞에 붙는 접근지정자에 대해서 설명하세요. 

11. 객체에 멤버를 접근하는 방법
   

 

 

// [사원클래스]
// 사원이라면 공통적으로 있어야할 멤버(필드, 메서드)를 구현한 클래스
// getPay() X   왜 선언하지 않았을까요 ? 

// 추상 메서드를 하나라도 가지고 있으면 반드시 객체를 생성할 수 없는 추상 클래스로 선언해야 된다.

// 추상 클래스
// 불완전한 클래스 이기 때문에 객체를 생성할 수 없는 클래스
public abstract class Employee {  //  extends Object
   // 필드
   private String name; // 사원명
   private String addr;   // 사원주소
   private String tel ;      // 사원연락처
   private String hiredate; // 입사일자

   // 생성자
   public Employee() {
      super();  // 
      System.out.println("> Employee 디폴트 생성자 호출됨.");
   }
   
   public Employee(String name, String addr, String tel, String hiredate) {
      super();  // 
      this.name = naddr;
      this.tel = tame;
      this.addr = el;
      this.hiredate = hiredate;
      System.out.println("> Employee 4 생성자 호출됨.");
   }



   // getter, setter
   public String getName() {
      return name;
   }
   
   public void setName(String name) {
      this.name = name;
   }
   public String getAddr() {
      return addr;
   }
   public void setAddr(String addr) {
      this.addr = addr;
   }
   public String getTel() {
      return tel;
   }
   public void setTel(String tel) {
      this.tel = tel;
   }
   public String getHiredate() {
      return hiredate;
   }
   public void setHiredate(String hiredate) {
      this.hiredate = hiredate;
   }
    
   // 메서드
   // 사원 정보를 출력하는 메서드 
   public void dispEmpInfo() {
      System.out.printf("사원명:%s, 주소:%s, 연락처:%s, 입사일자:%s\n"
            ,this.name, this.addr, this.tel, this.hiredate );
   }
   
   
   // 급여 계산해서 반환하는 메서드 
   // 가상(Virtual) 메서드
   /*
   public int getPay() {
      return 0;  // 의미 X -> R/S/T  새로 재정의 할 수 밖에 없어요.. 
   }
   */
   
   // 추상 메서드
   // 몸체가 구현이 안된 불완전한 메서드 
   // 클래스 설계할 때   추상 메서드를 왜 만듭니까? 
   public abstract int getPay();  //  몸체 (body) { }  구현 X
   
} // class
public static void main(String[] args) {
      // 9:35 제출
      // 10:33~ 
      //  왜? 자바는 다중 상속을 지원하지 않는가 ? 
      //     ㄴ 서로 다른 ( B, C) 클래스로부터 상속 받은 멤버(필드) 간의 이름이 같은 경우 
      //                 어떻게 구별할 수 있는 방법이 없다. ( 단점, 문제점 ) 
      //      ㄴ c++           다중 상속 가능
      
      //   [ -> 인터페이스를 사용해서 다중 상속을 대신한다.. ]
      

   } // main

} // class


class TV{
   // TV 필드, 생성자, 메서드 
}

class VCR{
   // VCR 필드, 생성자, 메서드    
}

// 단일 상속
/*
class TVCR extends TV{
   // TV 필드,  메서드 
   
}
*/

// 다중 상속 - 문법 에러  => 자바는 다중 상속을 지원하지 않는다. 
/*
class TVCR extends TV,  VCR{
   
}
*/

//인자 == 인수
// 가변인자, 가변인수
// 실인자(실인수), 가인자(가인수)
/*
 * int result = sum( 10, 20);  // 메서드 호출  실인수
 * 
 * 메서드 선언부분 
 * public int sum( int a, int b){  // 가인수 
 *   return a+b;
 * }
 * 
 * */

 

public class Ex02 {

   public static void main(String[] args) {
      // 질문) void draw() 코딩이 왜 에러 발생했을까요 ?
      //         ㄴ 같은 접근지정자가 없어서 그런가요 ?  80점  X
      /*
       * 1.  메서드명 동일
       * 2. 매개변수 타입+갯수  동일
       * 3. 리턴자료형 동일
       * 4. 접근지정자는 부모 보다 같거나 범위가 큰 접근지정자를 사용할 수 있다.
       *     public    -> public 
       *     default -> default, protected, public  
       *  5. 예외는 부모의 예외보다 많을 수 없다. ?   
       *  6. 인스턴스메서드 <-> static 메서드 변경 X
       * */

   }

}

// 도형클래스 
class Shape{ 
   public String color = "black";   
    public void draw() throws IOException{
      System.out.printf("[color=%s]\n", color);
   }
}

class Point{ 
   int x;
   int y; 
   Point(int x, int y){
      this.x = x;
      this.y = y;
   }
   Point(){
      this(0,0);  
   } 
   String getXY() {
      return String.format("(%d, %d)", this.x, this.y);
   }
}

class Circle extends Shape{   
   // 필드  
   Point center ;  
   int r;   
   Circle(){
      this(  new Point(0, 0)  ,0);
   }   
   Circle( Point center , int r){
      this.center = center;
      this.r = r;
   } 
   
   @Override
    // public void draw() throws IOException, SQLException{
   public void draw() throws IOException{
      System.out.printf("[color=%s, center=(%d, %d)]\n", color, this.center.x, this.center.y);
   }
   
}
public static void main(String[] args) {
      // 11:18 수업시작~ 
      Child c = new Child();
      
      c.dispChild();
      
      //c.x = 10;
      //System.out.println( c.x );
      
      /*
       * 자식 객체 c를 생성하는 데...
       *    ㄴ Parent 생성자 호출
       *    ㄴ Child    생성자 호출
       *    
       *  [생성자 호출되는 순서]
       *  1. 부모 생성자 먼저 호출되고 자식 생성자 호출된다.   
       *      부모 객체 생성                       자식 객체 생성
       *      
       *  [키워드 설명]
       *  this     :  클래스(객체)의 자기자신의 주소값을 갖는  참조변수
       *     this 3가지 용도
       *     1) 멤버를 가릴킬 때 this
       *     2) 생성자에서 또 다른 생성자를 호출할 때의 this
       *     3) 단독으로 사용될 때의 this :  리턴값, 매개변수
       *     
       *  super :  자식클래스에서 부모클래스의 멤버를 참조하는 데 사용되는   참조변수
       *     super 3가지 용도
       *     1) 부모의 멤버를 가릴킬 때 super
       *     2) 생성자에서 또 부모의 생성자를 호출할 때의 super()
       *     3) X
       * */

   } // main

} // class


class Parent{
   // 필드
   int x = 10;  // 명시적 초기화
   
   Parent(){
      System.out.println("> Parent 디폴트 생성자 호출됨.");
   }
   
    void dispParent() {
       
    }
}

class Child extends Parent{
   // 부모클래스 상속받은  int x = 10; 
   int y;
   int x = 20;

   public Child() {
      // 생성자는 상속이 안된다 했는데  호출은 가능한 건가요? 네... 
      super(); // 부모의 디폴트 생성자 호출
      System.out.println(">  Child 디폴트 생성자 호출됨.");
   } 
   
   void dispChild() {
      System.out.println("> Parent.x = " + this.x );  // > Parent.x = 20
      System.out.println("> Parent.x = " + super.x );  // > Parent.x = 10
   }
}

/*
1. 강사님
    this나 super가 주소가 담긴 참조변수라면,
     얘네도 stack에 따로 저장되어있는 변수인건가요??
      아니면 인스턴스 변수인데 주소값을 담고 있는건가요...? 
      
2. int x중복선언  오류는 안나는 건가요? 네 
      
*/ 
public class Ex04 {

   public static void main(String[] args) {
      /*
       * 1. 사원 클래스                     - Employee 클래스 추가 - 사원이라면 공통적으로 가지고 있어야할 멤버를 선언
       * 2. 정규직 사원 클래스 추가  - Regular extends Employee + 정규직 멤버 선언
       * 3. 영업직 사원 클래스 추가 - SalesMan extends Regular + 영업직 멤버 선언
       * 4. 임시직 사원 클래스 추가 - Temp extends Employee     + 임시직 멤버 선언
       * 
       * [개념설명]
       * 1. 상속성
       * 2. 다형성
       * 3. 업캐스팅/다운캐스팅
       * 4. 오버로딩/오버라이딩
       * 5. 추상화 ( 추상메서드, 추상클래스 )
       * 6. this, super 키워드 
       * 7. 인터페이스 
       * 등등
       * */ 
      
      /*
      // 1. 사원(Employee) 객체 생성 후 메서드 호출
      Employee emp1 = new Employee("김동현", "서울 강남구", "010-1111-2222", "2021.12.21");
      emp1.dispEmpInfo();
      */
      
      // 2. 정규직(Regular) 객체 생성 
      // [문제점] 생성자의 매개변수들은  필드 초기화 - super(name, addr, tel, hiredate) 부모필드 초기화 가능
      // [문제점] 사원 정보를 출력하는 메서드 + ( 기본급 출력 X ) - 
       //  1)  오버로딩( 새로운 출력 메서드 선언 )
      //   2)  오버라이딩( 재정의 함수 ) *** 왜? 다형성 때문에... 
      
      // [ 생성자 호출 순서 ] 
      /*
      Regular  emp2 = new Regular("박진용", "서울 양천구", "010-1212-1212", "2020.01.24", 300000 );
      emp2.dispEmpInfo();
      */
      
      // 3. 영업직(SalesMan) 객체 생성
      /*
      SalesMan emp3 = new SalesMan("윤재민", "경기도 남양주", "010-7887-9878", "2000.03.29", 500000, 20, 150000);
      emp3.dispEmpInfo();
      */
      
      // 4. 임시직(Temp) 객체 생성
      /*
      Temp emp4  = new Temp("설경인", "서울 강북", "010-4334-3894", "2022.02.12", 15, 200000);
       emp4.dispEmpInfo();
       */
      
      // [문제제시]
      // 사원이 할 수 있는 일(기능) 중에 제일 중요한 일이 뭘까요?  (월급받는 일) 
      // getPay() 급여 메서드 추가 선언
      // Regular.getPay() 추가
      
       // 자식(Regular) 객체를 생성해서 부모(Employee)클래스에 참조
      //    업캐스팅( UpCasting )
      //           클래스들간의 자동 형변환이 되었다.
      //  E(자료형)         =          R(자료형)
      /*
        Employee  emp2 = new Regular("박진용", "서울 양천구", "010-1212-1212", "2020.01.24", 3000000 );
      
        emp2.dispEmpInfo(); // 이름,주소,연락처,입사일 ,  실제 참조된 객체가 Regular익때문에 + 기본급  
        System.out.println( emp2.getPay() ) ;
        */
        // R 생 ->  E 업캐스팅
        //               emp2.dispEmpInfo() -> Employee.dispEmpInfo() X
        //                                                          Regular.dispEmpInfo() O  사실도 확인.
      
      
      // System.out.println("월급 : " + emp2.getPay() );
      // [첫번째 질문]    Regular emp =  new Regular()
      //                    왜 ? Employee emp =  new Regular()        
      //                    답 :   다형성 때문에~    업캐스팅하는  좋은 이유... 
      // [문제발생]  R 생성해서        E 클래스 업캐스팅하고 나니 
      //                    getPay()O           getPay()X
      //                                                  emp2.getPay() 호출 X
        
        // 3:10 수업 시작~
        
        // 질문)  그럼 상속받은 클래스들은 객체 생성 가능한건가요?
        //   자식클래스에서 추상메서드를 재정의하면 그 자식클래스는 객체 생성할 수 있다. 
      
      // 월) OOP 특징- 구체적인 내용까지 상세하게 설명...
      // 클래스 특징 == OOP 특징 :     캡슐화, (은닉화), (상속성), (추상화),(다형성)
      // [ 다형성 ( polymorphism ) ]
      // 1. 상속 관계
      // 2. 다양한 성질
      // 3. 여러 가지 형태를 가질 수 있는 능력
      //       Employee emp = new Regular();
      //       Employee emp = new SalesMan();
      //       Regular emp = new SalesMan();
      //       Employee emp = new Temp();
      // 4. 조상클래스 타입의 참조변수로 자손클래스의 인스턴스를 참조할 수 있도록 한 것.
      // 5. 업캐스팅(UpCasting)
      
      // 4:05 수업시작~ 
      // 왜? ***
      // 정규직객체, 영업직객체,임시직객체
      
      // 여러 타입의 사원들이 있습니다.
      /*
      Employee  emp2 = new Regular("박진용", "서울 양천구", "010-1212-1212", "2020.01.24", 300000 );
      Employee emp3 = new SalesMan("윤재민", "경기도 남양주", "010-7887-9878", "2000.03.29", 500000, 20, 150000);
      Employee emp4  = new Temp("설경인", "서울 강북", "010-4334-3894", "2022.02.12", 15, 200000);
      */
      //Employee emp5 = new Temp02();
      
      // 클래스 배열 ( 객체 배열 ) 초기화 + 다형성 + UpCasting
      Employee [] emps = {
            new Regular("박진용", "서울 양천구", "010-1212-1212", "2020.01.24", 300000 ), 
            new SalesMan("윤재민", "경기도 남양주", "010-7887-9878", "2000.03.29", 500000, 20, 150000),
            new Temp("설경인", "서울 강북", "010-4334-3894", "2022.02.12", 15, 200000)
      };
      
      // 각 사원들의 급여를 계산해서 출력하는 메서드
      /*
      regularPay(emp2);
      salesManPay(emp3);
      tempPay(emp4);
      */
      // 50 개의 사원 타입(종류)
      //employeePay(emp2);  // 정규직
      //employeePay(emp3);  // 영업직
      //employeePay(emp4);  // 임시직
      //employeePay(emp5);  // 임시직
      /*
      for (int i = 0; i < emps.length; i++) {
         employeePay(   emps[i] );
      }
      */
      employeePay( emps[1] );  // SalesMan 영업직 사원

   } // main
                                       //                  매개변수 다형성
   public static void employeePay( Employee emp ) {
      
      // 매개변수 Employee emp 가 실제 어떤 객체가 매개변수 넘어오지 확인...       :   instanceOf 연산자.
      // ( 주의할 점) instanceof 연산자를 사용할 때 반드시 자식클래스 부터 체크한다. 
      if (   emp instanceof SalesMan ) {   // true
         System.out.println(" 매개변수 emp는  SalesMan 타입  객체입니다. ");
         SalesMan sm = (SalesMan) emp;  // 다운캐스팅 
      } else if (   emp instanceof Regular ) {   // true
         System.out.println(" 매개변수 emp는  Regualr 타입  객체입니다. ");
         Regular rm = (Regular) emp;  // 다운캐스팅 
      }else if (   emp instanceof Temp ) {   // true
         System.out.println(" 매개변수 emp는  Temp 타입  객체입니다. ");
         Temp rm = (Temp) emp;  // 다운캐스팅 
      }
      
      
       System.out.println( emp.getPay() );
   }
   
   /*
   public static void regularPay( Regular emp ) {
       System.out.println( emp.getPay() );
   }
   
   public static void salesManPay( SalesMan emp ) {
       System.out.println( emp.getPay() );
   }
   
   public static void tempPay( Temp emp ) {
       System.out.println( emp.getPay() );
   }
   */

} // class

public class Ex05 {

   public static void main(String[] args) {
      /*
       * [ final 키워드 ]  ( 시험 ) final 키워드에 대해서 설명하세요~
       * 1. 변수 앞에         선언할 때   -   상수
       *     지역변수
       *     매개변수
       *      
       *     인스턴스 변수
       *     클래스 변수
       *      
       * 2. 메서드 앞에    선언할 때 
       * 3. 클래스 앞에     선언할 때 
       * */
      
      // System.out.println( Sample.PI );
      
      Sample s = new Sample(100);
      s.plus(100);
      System.out.println( s.m );  // 110

   }

}

class Sample{
   // 인스턴스 변수
   // double pi = 3.141592;
   // final double PI = 3.141592;  // 상수
   
   // 클래스 변수
   // static final double PI = 3.141592;  // 상수
   // public final static  double PI = 3.141592;  // 상수
   
    final int MAX_VALUE ;  // 명시적 초기화
   // 생성자
   public Sample(  int maxValue ) {
      this.MAX_VALUE = maxValue;
   }
   
   void disp() {
      // 지역변수
      final int COUNT = 10;  // 상수
   }
   
   int m = 10;
   void plus( final int n ) {  // 여기서 final 의미 ?  지역변수 앞에 final
      // n = 30;
      m += n;
   }
}



 

 

public class Ex05_02 {

   public static void main(String[] args) {
      

   }

}

//subclass(자식클래스)를 가질 수 없는 마지막(최종) 클래스
final class P{
   
   // final 메서드 앞에 붙이면 자식 클래스에서 
   // 오버라이딩(재정의)을 할 수 없다.
   final void draw() {
      System.out.println("P.draw() 호출됨.");
   }
   
}

// The type C cannot subclass the final class P
// 
//class C extends P{
    
   // Cannot override the final method from P
   /*
   @Override
   void draw() {
      System.out.println("C.draw() 오버라이딩(재정의) 호출됨.");
   }
   */
   
//}

public class Ex06 {

   public static void main(String[] args) {
      // 왜 ? 질문
      // A obj =  new A();
      // B obj =  new B();
      // C obj =  new C();
      // 답 : 다형성..
      
      /*
      A obj = new A();
      obj.disp();
      */
      
      /* (질문)
      Regular 객체를 생성해서 basePay는 출력이 되지만 
      Employee 클래스에는 basePay라는 변수가 없는데
      basePay라는 값은 어디에 저장이 되는건가요 ?
      
      실제 객체( Regular)의 dispEmpInfo() 메서드가 호출이 되어져서 그렇습니다. 
      
      */
      
      // 클래스 간의 형변환 (A,B)
      // 1. 조건 :  상속 관계
      // 2. 업캐스팅 =  자동으로 형변환이 된다.
      
      // A - B - C 상속 계층구조
      A  obj =  new C();  // 업캐스팅
      
      // 다운캐스팅 - 자동되지 않아요.  강제형변환 - cast 연산자
      C  c1 = (C) obj;
      obj.disp();

   }  // main

} //  class

abstract class A{
   abstract void disp() ;
   //{
   // System.out.println("A");
   //}
}

class B extends A{
   // 부모의 추상 메서드를 오버라이딩(재정의)해서 추상메서드를 구현하면 객체는 생성할 수 있다.
   @Override
   void disp() {
      System.out.println("B - 재정의");
   }
}

class C extends B{
   @Override
   void disp() {
      System.out.println("C - 재정의");
   }
}


 

public class Ex07 {

   public static void main(String[] args) {
      // ArrayList 클래스
      // ArrayList   list = new ArrayList();
      
      // 업캐스팅, 다형성
       // List  list = new ArrayList();
      
      test( new ArrayList() );

   } // main
   
   //                               매개변수 다형성
   public static void test( List list)   {
      
   }
   

} // class
public class Ex08 {

   public static void main(String[] args) {

      /*
      Sington s = new Sington();    
      System.out.println(  s );  // 생성된 객체의 정보 :   days17.Sington@5aaa6d82      
        // s = new Sington();
      Sington s2 = s;
      System.out.println(  s2 );  // 생성된 객체의 정보 :   days17.Sington@73a28541
       */

      // 어디에서도 객체를 생성할 수 없다..
      // The constructor Singleton()  [is not visible]
      // Singleton s = new Singleton();
      Singleton s =  Singleton.getInstance();
      System.out.println( s );
      s =  Singleton.getInstance();
      System.out.println( s );
      s =  Singleton.getInstance();
      System.out.println( s );
      s =  Singleton.getInstance();
      System.out.println( s );
   } // main

} // class

// 싱글톤 
class Singleton{

   // public                패키지 내/외 어디서든 객체생성할 수 있다.
   // default            패키지 내에서만 객체를 생성하세요.. ( 제한 )
   // protected                             "                                                     + 상속
   private Singleton() { }

   private static Singleton singleton = null ;  // 필드 선언

   public static Singleton getInstance() {
      // static 메서드 안에서 지역변수       사용가능 ? O
      // static 메서드 안에서 인스턴스변수 사용가능 ? X
      // Cannot make a static reference to the non-static field singleton
      if( singleton == null ) {
         singleton = new Singleton();
      }     
      return singleton;

   }

}

// 정규직 사원 클래스 
// 급여 = 기본급
public class Regular extends Employee{
   // 필드 - name, addr, tel, hiredate 상속
   private int basePay; // 기본급 

   // getter, setter
   public int getBasePay() {
      return basePay;
   }

   public void setBasePay(int basePay) {
      this.basePay = basePay;
   }

   // 생성자
   public Regular() {
      super(); 
      System.out.println("> Regular 디폴트 생성자 호출됨.");
   }
   
   public Regular(String name, String addr, String tel, String hiredate, int basePay) {
      super(name, addr, tel, hiredate);
      
      // 필드 초기화 코딩..
      // The field Employee.name [is not visible] - private 로 선언된 필드 
      // this.name = name;    X
      // super.name = name; X
      
      /*
      this.setName(name);
      this.setAddr(addr);
      this.setTel(tel);
      this.setHiredate(hiredate);
      */
      
      this.basePay = basePay;
      System.out.println("> Regular 5 생성자 호출됨.");
   }

   // 메서드 - dispEmpInfo() 상속 : name, addr, tel, hiredate 만 출력
   // [오버라이딩 조건]
   @Override
   public void dispEmpInfo() {
      System.out.printf("사원명:%s, 주소:%s, 연락처:%s, 입사일자:%s, 기본급=%d\n"
            ,this.getName(), this.getAddr(), this.getTel(), this.getHiredate() , this.basePay);
      /*
      super.dispEmpInfo();
      System.out.printf("기본급=%d\n", this.basePay);
      */    
   }
   
   // 급여 계산해서 반환하는 메서드 
   public int getPay() {
      return this.basePay;      
   }
      
   

} // class
// 영업직 사원클래스
// 급여 = 기본급 + 판매량 * 커미션
public final class SalesMan extends Regular{

   // 필드 : name, addr, tel, hiredate, basepay
   private int sales; // 판매량
   private int comm; // 커미션

   // 생성자
   public SalesMan() {
      super(); 
      System.out.println("> SalesMan 디폴트 생성자 호출됨.");
   }
   public SalesMan(String name, String addr, String tel, String hiredate, int basePay, int sales, int comm) {
      super(name, addr, tel, hiredate, basePay); // Regular 생성자 호출
      this.sales = sales;
      this.comm = comm;
      System.out.println("> SalesMan 7 생성자 호출됨.");
   }

   // 메서드 : dispEmpInfo()
   @Override
   public void dispEmpInfo() {
      /*
      super.dispEmpInfo();  // Regular.dispEmpInfo()
      System.out.printf("판매량=%d, 커미션=%d\n", this.sales, this.comm);
       */

      System.out.printf("사원명:%s, 주소:%s, 연락처:%s, 입사일자:%s, 기본급=%d, 판매량=%d, 커미션=%d\n"
            ,this.getName(), this.getAddr(), this.getTel(), this.getHiredate() , this.getBasePay()
            , this.sales, this.comm );
   }

   // 급여 계산해서 반환하는 메서드 
   @Override
   public int getPay() {
      // return this.getBasePay() + this.sales * this.comm;     
      return  super.getPay()  + this.sales * this.comm;
   }


} // class
// 임시직 사원 클래스
// 급여 = 근무일수 * 하루일당
public class Temp extends Employee{
   
   // 필드 - name, addr, tel, hiredate
   private int days;           // 근무일수
   private int payOfDay; // 하루 일당
   
   // 생성자
   public Temp() {
      super();
      System.out.println("> Temp 디폴트 생성자 호출됨.");
   }
   public Temp(String name, String addr, String tel, String hiredate, int days, int payOfDay) {
      super(name, addr, tel, hiredate);
      this.days = days;
      this.payOfDay = payOfDay;
      System.out.println("> Temp 6 생성자 호출됨.");
   }
   
   // 메서드 - dispEmpInfo()
   @Override
   public void dispEmpInfo() {       
      super.dispEmpInfo();
      System.out.printf("근무일수:%d, 하루일당:%d\n", this.days, this.payOfDay);
   } 
   
   // 급여 계산해서 반환하는 메서드 
   public int getPay() {
      return this.days * this.payOfDay;     
   }  

}

// 5년뒤에 새로운 사원 종류 1개 생겼어요.
/*
class  Temp02 extends Temp{
   
}

class SSEmp extends Employee{
   
}
*/

'-java spring notes-' 카테고리의 다른 글

day 24- 열거자 반복자 로또  (1) 2023.03.19
객체 복습-day15~day18(자바의정석 기초 객체2+참고소스 복습)  (0) 2023.02.22
Day16-객체,메서드  (0) 2023.02.19
day15-객체  (1) 2023.02.18
day12-배열  (0) 2023.02.18
profile

냥코딩쟝

@yejang

포스팅이 좋았다면 "좋아요❤️" 또는 "구독👍🏻" 해주세요!