본문 바로가기

programming/Gukbi

국비 교육 17일차 - 상속, 포함

728x90
반응형

객체지향을 계속 이어서 배우는 중이다. 

우선 가장 중요한거는 접근지정어들의 의미와 사용범위, 또 실제 프로그램에서는 어떻게 쓰이는지를 배우고 있다. 

 

아 그리고 지금부터는 패키지를 만들어서 폴더를 관리하고 클래스들을 모으고 있다. 

 

 

조금 이따가 다시 따로 포스팅 하겠지만 프로젝트를 만들때 이런식으로 관리를 해주는 중이다

main 패키지, manager 패키지 따로 생성하여 관리 한다. 

 

 

우선 객체 지향 정리부터 먼저 하겠다.

package com.sist.main;
/*
 *    객체지향 프로그램 : 유지보수가 가능하게 만드는 프로그램 
 *                    ======
 *                    1) 데이터 보호 : 캡슐화 
 *                       => 멤버변수는 private으로 은닉화 
 *                       => 접속 => getter/setter
 *                       => 멤버변수는 감추고 메소드를 통해서 접근하는 방식 
 *                          멤버변수 : private 
 *                          멤버베소드 : public 
 *                          생성자 : 모든 클래스에서 접속이 가능 : public 
 *                          ** 상속이 있는 경우에는 멤버변수는 protected 
 *                             === 사용이 가능 (public , protected,default)
 *                             === 라이브러리를 변경 
 *                    2) 기존의 클래스를 재사용 : is-a(상속), has-a(포함):웹에서 주로 사용
 *                         상속 : 상속을 내리는 클래스(상위 클래스)의 모든 내용이 내려간다 
 *                               예외) 생성자 , static (사용이 가능하게 만들어 준다)
 *                               => 키워드 : extends (확장) 
 *                               기존의 클래스를 확장해서 새로운 클래스를 만들어서 사용
 *                         class A
 *                         {
 *                            내용(멤버변수,멤버메소드)
 *                         } 
 *                         class B extends A
 *                         {
 *                             A가 가지고 있는 모든 내용을 받는다 (소스코드에서 보이지 않는다):중복을 제거,
 *                                                          소스를 간결
 *                             추가 , 변경 => 사용이 가능 
 *                         }
 *                         포함 : 기존의 클래스의 기능을 그대로 사용  
 *                         class A
 *                         {
 *                         }
 *                         class B
 *                         {
 *                             A a=new A();
 *                         }
 *                         
 *                         예) 
 *                              윈도우 , (버튼 , 텍스트필드 , 라디오버튼 ....)
 *                              ===== 윈도우 약간의 변경사항이 존재 
 *                              ===== 자바에서 상속 단일 상속 (가장 큰것을 받아서 사용)
 *                              ===== 상속 : 윈도우프로그램 , 쓰레드 
 *                                    POJO (스프링 2.5이상) : 독립클래스 (컴포넌트) => 컨테이너
 *                    3) 변경 , 추가 (다형성) 
 *                      ====  ====오버로딩
 *                      오버라이딩 
 *                      
 *                      =========================================================
 *                                   오버로딩          오버라이딩
 *                      =========================================================
 *                       상속여부    자신의 클래스         상속 (기존의 클래스의 기능을 변경)
 *                      =========================================================
 *                       메소드명       동일              동일 
 *                      =========================================================
 *                       매개변수    갯수나 데이터형이       매개변수가 동일
 *                                 다르다
 *                      =========================================================
 *                       리턴형      상관없다              동일 
 *                                                   * 접속지정어의 확장이 가능
 *                                                   ==========
 *                                                   private < default < protected < public
 *                                                   private : 자신의 클래스안에서만 접근
 *                                                   default : private
 *                                                             같은 패키지안에서만 접근이 가능
 *                                                   protected : default
 *                                                             다른 패키지에서 접근이 가능
 *                                                             단 상속을 받은 경우에만 가능 
 *                                                   public : 모든 클래승에서 접근이 가능 
 *                                                   
 *                      =========================================================
 *                      
 *    1. 캡슐화 : 접근지정어  , 2. 상속 => 오버라이딩 
 *    2. 자신의 클래스를 지정하는 키워드 : this
 *       상위 클래스를 지정하는 키워드 : super
 *       => 자신의 생성자 호출  : this()
 *       => 상위 클래스의 생성자 호출 : super()
 *    3. 메소드 정의 
 *       static : static메소드,static변수는 언제든지 사용이 가능 
 *                instance를 호출시에는 반드시 객체를 생성하고 접근 
 *                class A
 *                {
 *                    private int x;
 *                    public static void display()
 *                    {
 *                       System.out.println("x="+x);  ==> 에러 
 *                       
 *                       A a=new A();
 *                       System.out.println("a.x="+a.x);
 *                    }
 *                }
 *       instance : 모든 데이터나 메소드 호출이 가능 
 *       
 *          1. 자바의 클래스와 객체에 대한 설명 중 틀린 것은?
 
				1. 클래스 바깥에 전역 변수는 선언할 수 없다. : 자바에서는 모든 소스(메소드,변수) => 클래스내에 존재
				   
				   class A
				   {
				      ========
				       변수 
				      ========
				       메소드
				      ========
				       생성자
				      ========
				   }
				   
				2. 클래스는 객체를 생성하기 위한 틀이다.: 클래스 (설계도,틀)
				3. 클래스의 멤버 변수를 필드라고 부르며, 클래스는 필드와 메소드로 이루어진다..
				***4. 필드는 클래스 내에서 private 보다 public으로 선언하는 것이 바람직하다. 
				      멤버변수는 private , 메소드,생성자 : public 
	 
 
 
			2. 생성자에 대한 설명 중 틀린 것은?
			 
				1. 생성자가 작성되어 있지 않으면, 컴파일러가 자동으로 기본 생성자를 추가해준다.
				2. 생성자의 이름은 클래스의 이름과 반드시 같아야 한다.
				3. this()는 생성자 내에서 다른 생성자를 호출하는 코드이다.
				***4. 생성자에서는 아무 값도 리턴하지 않기 때문에 return문을 사용할 수 없다. (return)
 
                   모든 메소드의 종료시점 : return (생성자에서도 return사용이 가능)
 */
/*
 *    생성자 : 여러개를 만들 수 있다 (사용자로부터 멤버변수의 초기값을 받아서 사용)
 *           => 오버로딩을 지원한다 
 *           => 초기화를 담당한다 
 *           => 리턴형이 없다(return은 사용이 가능) 
 *           => 클래스명과 동일 (대소문자 구분)
 *           => 존재하지 않는 경우에 컴파일러가 자동으로 디폴트생성자(매개변수아 없는 생성자) 추가 
 *           예) 네트워크,데이터베이스에서 주로 사용 (시작과 동시에 연결)
 *              *** 모든 클래스의 시작은 생성자(가장 먼저 호출이 된다)
 *              *** 객체 생성시에 호출된다 
 *              *** 생성자를 호출시에는 반드시 new 생성자명();
 *           class A
 *           {
 *               public A(){}
 *               public A(int a){}
 *               *****public A(int b){} => 오류   ==> A(int)
 *               *****public void A(int a){} ==> 생성자가 아니다 
 *               public A(int a,int b){}  => A(int,int)
 *               public A(String name){}
 *           }
 *           
 *           ***
 *           클래스 
 *           ======
 *             1. 일반 클래스 
 *                public class MainClass 
 *             2. 추상 클래스 (설계) =================> 보완 (인터페이스)
 *                public abstract class MainClass
 *             3. 종단 클래스 
 *                public final class MainClass : 확장이 불가능한 클래스 
 *                =====> String , Math , System 
 *             4. 내부 클래스 
 *                class A
 *                {
 *                   class B => 쓰레드 , 네트워크 
 *                   {
 *                   }
 *                }
 *                class A
 *                {
 *                    B b=new B(){
 *                       public void display(){} // 익명의 클래스 
 *                    }
 *                }
 *                class B
 *                {
 *                   public void display(){}
 *                }
 */
// 기존의 클래스 상속 => this() : 자신의 생성자를 호출이 가능 
/*
 *    상속
 *    ===
 *      상속을 내리는 클래스(슈퍼클래스) => 서브클래스를 제어 할 수 없다 
 *      상속을 받는 클래스(서브클래스) ==> 슈퍼클래스의 데이터나 메소드 호출이 가능 
 */
import javax.swing.*;
/*
 *    1. 상위 클래스를 제어 할때 : super,super()
 *    2. 자신 클래스를 제어 할때 : this,this()
 *                           ======
 *                           객체가 생성이 될때 존재 (자신의 객체)
 *                           MainClass m=new MainClass();
 *                           this=m; ==> 컴파일러가 생성된 클래스 객체의 주소를 기억 
 *                           
 *     다음 클래스에는 컴파일 오류가 있다. 오류 부분을 지적하고 오류를 수정할 수 있는 방법을 모두 제시하라. 
 *     그리고 그 중 객체 지향 프로그래밍에 가장 적합한 방법을 설명하라.
 
		class Person {
		    private int age;
		    public Person(int age)
		    {
		       this.age=age;
		    }
		    public void setAge(int age)
		    {
		       this.age=age;
		    }
		    public void display(int age)
		    {
		        this.age=age;
		    }
		    
		    // 생성자나 메소드는 private을 사용하게 되면 다른 클래스와 통신 할 수 없다 : public 
		    // 객체지향 프로그램 
		       객체와 객체의 통신을 통해서 연결 
		                 ============
		                 메세지 => 메소드 : 모바일 (서비스)
		       Tv   ====   사람
		            메세지
		            결과값 받기 ======> 메소드 호출 
		}
		public class Example {
		    public static void main (String args[]) {
		        Person aPerson = new Person(17);
		        //aPerson.age = 17;
		        aPerson.setAge(17);
		        aPerson.display(17);
		    }
		}
 */
public class MainClass extends JFrame{
	
    public MainClass()
    {
    	super("Hello"); // JFrame의 생성자 함수 => 상위 클래스(상속을 내리는 클래스)의 생성자를 호출
    	setSize(640,480);// 윈도우 크기 
    	setVisible(true);// 윈도우 보여주기 
    }
    public MainClass(int width,int height)
    {
    	//this(); // 생성자를 호출할때 반드시 첫번째줄에 코딩
    	setSize(width,height);// 윈도우 크기 
    	setVisible(true);// 윈도우 보여주기 
    }
	public static void main(String[] args) {
		// TODO Auto-generated method stub
        // 생성자만 호출 
		new MainClass(800,600);
	}

}
/*
 *  public static Image getImage(ImageIcon ii,int w,int h)
    {
    	Image dimg = ii.getImage().getScaledInstance(w, h,
    	        Image.SCALE_SMOOTH);
    	return dimg;
    }
 */

캡슐화, 다형성, 수정등은 유지보수가 쉽도록 만들어 주는 객체지향 프로그래밍의 가장 큰 특징이라고 할 수 있다. 

 

아래는 생성자, 포함 상속 등을 더 구체적으로 연습해본 예제들이다. 

package com.sist.main;
// this()메소드 => 자신의 생성자를 호출 할 때 사용 
class Member
{
	private int no;//0
	private String name;//null
	private String sex;//null
	
	public Member()
	{
		sex="남자";//this.sex (지역,매개변수에 존재하지 않는 경우는 this를 생략할 수 있다)
		// 지역(매개)변수 => 멤버변수에서 찾는다 
	}
	public Member(int no,String name)
	{
		this();// 자신의 생성자 호출이 가능하다 
		this.no=no;
		this.name=name;
		// this(1,"")
	}
	public Member(int no,String name,String sex)
	{
		// this(1,"","")
		this.no=no;
		this.name=name;
		this.sex=sex;
	}
	public void print()
	{
		System.out.println("번호:"+no);
		System.out.println("이름:"+name);
		System.out.println("성별:"+sex);
	}
	
}
public class MainClass2 {

	public static void main(String[] args) {
		// TODO Auto-generated method stub
        Member m1=new Member();
        m1.print();
        Member m2=new Member(1,"홍길동");
        m2.print();
        Member m3=new Member(1,"심청이","여자");
        m3.print();
        
	}

}

이름은 같은 Member 메소드를 여러개 만들었지만, 매개변수의 갯수와 타입이 다 다르다. 

이걸 오버로딩이라고 부른다. 

 

아래 생성자를 이용해서 각각 다른 초기값들을 입력해줬지만 print를 통해 출력한 값이 전부 같은것을 확인 할 수 있다. 

 

 

package com.sist.main;
// 오버라이딩 (재정의)
// 모든 클래스는 Object로부터 상속을 받는다
// 모든 클래스(데이터형)은 Object로 통합해서 사용이 가능
/*
 * 	Object o=10;
 * 	Object 0=10.5;
 * 	Object o="Hello";
 * 	Object o=true;
 * 	Object o=new A();
 * 	===> 자바에서 지원하는 라이브러리는 리턴형이 Object => 필요시마다 형변환을 시킨다
 * 												================== 제네릭스
 * 												List<String>
 * 			Object
 * 			  |
 * 			MainClass3
 * 
 * 			class A
 * 			{
 * 			}
 * 			class B extends A
 * 			{
 * 			}
 * 				Object
 * 				  |
 * 				  A ==> Object
 * 				  |
 * 				  B ==> A, Object
 */
public class MainClass3 {
		// Object가 가지고 있는 메소드를 재정의
	private String name, addr, tel;
	// 시작할때 사용자로부터 값을 받아서 멤버변수에 초기화
	public MainClass3(String n, String a, String t)
	{
		this.name=n;
		addr=a;
		tel=t;
	}
	public String toString()
	{
		return "이름:"+name+",주소:"+addr+",전화:"+tel;
		// 모든 인스턴스메소드는 모든 멤버변수, 메소드를 호출이 가능
	}
	public static void main(String[] args) {
		
		Object m=new MainClass3("황인준", "길림", "010-0000-0000");
		MainClass3 m2=(MainClass3)m;
		
		String result=m.toString();
		System.out.println(result);
	}
	

}

클래스의 형변환 예제

단순 변수만 형변환이 필요한게 아니라, 상속받는 클래스가 더 작다면 이때 역시 형변환을 해주어야 한다. 

 

모든 클래스의 상위 클래스는 Object 클래스이기 때문에 Object를 상속받고 그 내부에 있는 메소드를 사용하기 위해서는 형변환을 꼭 해주어야 한다. 앞으로 나오는 프로그램들에서는 Object 클래스를 상속받는 클래스들이 많을 예정이라

class의 형변환에 익숙해져야 한다. 

 

그 다음은 접근 지정어 

package com.sist.main;
/*
 *    제어자 (page 344)
 *    ================
 *    접근 지정어 : public , protected , default , private 
 *    클래스 
 *    =====
 *      클래스 : public , default 
 *      멤버변수 : public , protected , default , private 
 *      ===============================================
 *      메소드 : public , protected , default , private 
 *      생성자 : public , protected , default , private 
 *      ============================================== 다른 클래스와 연결 => public 
 *      
 *    final , static , abstract , synchronized
 *    =====
 *    마지막 => 상속을 할 수 없는 클래스 , 상수
 *    static : 공통적인 
 *    abstract : 추상적인 => 구현 하지 않고 사용 
 *    synchronized : 동기화,비동기화 
 *                   =====
 *                   메소드는 기본적으로 동기화 
 *                   
 *    class A
 *    {
 *        public void aaa(){}
 *        public void bbb(){}
 *        public void ccc(){}
 *        public void ddd(){무한루프}
 *        public void eee(){}
 *    }
 *    class B
 *    {
 *        public static void main(String[] args)
 *        {
 *            A a=new A();
 *            a.aaa();
 *            a.bbb();
 *            a.ccc();
 *            a.ddd();
 *            a.eee();
 *        }
 *    }
 *    
 *    =====================
 *    
 *    =====================
 *        eee()
 *    =====================
 *        ddd()
 *    =====================
 *        ccc()
 *    =====================
 *        bbb()
 *    =====================
 *        aaa()   => 종료    
 *    =====================
 *       Call Stack
 *       
 *       =========  ========  =========  =-=======   =======
 *          aaa()    bbb()      ccc()      ddd()      eee()   ==> 쓰레드 
 *       =========  ========  =========  =========   =======
 *       
 *       
 *       사용방법 (page 353)
 *       클래스 
 *       접근지정어 옵션   class  className
 *                [final,abstract]
 *       [public,default]
 *       
 *       public final class String
 *       public abstract class String
 *       final class String
 *       abstract class String
 *       =============================
 *       
 *       메소드 
 *       접근지정어 옵션 리턴형 메소드명()
 *       ======= === [final|abstract|static]
 *       [public|private|default|protected]
 *       
 *       멤버변수 
 *       접근지정어 옵션 데이터형 변수명 
 *       ======= ===[final | static]
 *       [public|private|default|protected]
 *       
 *       => 접근지정어 옵션 
 *          public static
 *       => 옵션 접근지정어 
 *          static public 
 */
class Student
{
	private int hakbun;
	public String name;
	protected String sex;
	int kor=100;
	public void aaa() {
		final int a=10;
		// only final 
	}
	private void bbb() {
		
	}
	void ccc() {}
	protected void ddd() {}
	
	public Student() {}
	private Student(int a) {}
	Student(int a,int b){}
	protected Student(int a,int b,int c) {}
}
class Student2 extends Student{
	int kor=200;
	public Student2()
	{
		//this.kor=200;
		//super.kor=300;
		this.kor=10000;
		super.kor=20000;
		System.out.println("super.kor:"+super.kor);
		System.out.println("this.kor:"+this.kor);
	}
}
public class MainClass5 {

	public static void main(String[] args) {
		// TODO Auto-generated method stub
        Student s=new Student();
        Object o=new Student();
        Student s1=(Student)o;
        System.out.println(s1.kor=100);
        s=new Student2();
        Student2 s2=(Student2)s;
        System.out.println(s2.kor=1000);
        /*Student2 s2=new Student2();
        s2=(Student2)s;
        s2.kor=1000;
        System.out.println(s2.kor);*/
	}

}



어디까지 사용이 가능한지 잘 알고 있어야 다른 클래스에서 메소드, 생성자, 변수 등을 가져와 쓸 수 있다. 

여러가지가 있지만 그냥 변수는 private, 나머지는 public으로 써주는게 국룰인거 같다. 

또 한가지 알고 있으면 좋은거는 protected를 쓰면 상속받은 클래스에서는 사용할 수 있다는 점. 

 

오후 시간에 한거는 실제 데이터를 끌어와서 프로그램을 만들어 보는거였다. 

 

manager 파일이 로직을 담아두는 파일이고, main에서 실제로 실행되도록 한다. 

VO는 변수들과 getter setter 함수들을 따로 저장하는 공간이다. 

 

수업시간에는 웹에서 긁어온 파일들을 사용해서 프로그램을 만들었다. 

 

그 내용은 다음 포스팅에서 이어서 쓰겠다. 

 

 

 

728x90
반응형