조컴퓨터

200828 OOP 12 - Java 객체지향 프로그래밍 (Ⅱ) 본문

자바 웹개발자 과정/JAVA

200828 OOP 12 - Java 객체지향 프로그래밍 (Ⅱ)

챠오위 2020. 9. 7. 21:52

Super

상속 관계에서 부모, 조상의 개념을 Super라 한다.

 

부모, 조상, super

부모 클래스 superclass

자식 클래스 subclass

 

super: 자식 클래스에서 부모 클래스의 멤버변수에 접근할 때

super(): 자식 클래스의 생성자 함수가 부모 클래스의 생성자 함수를 호출할 때

 

this: 멤버 변수(field)와 일반 변수를 구분하기 위해

this(): 자신의 생성자 함수가 자신의 생성자 함수를 호출할 때

 

 

상속 관계에서 생성자 함수 호출 순서

부모 생성자가 먼저 호출되고 자신의 생성자 함수가 호출된다.

School() → MiddleSchool()

School() → HighSchool()

 

상속 관계에서 부모 생성자 함수 호출 명령어

super(); //생략 가능하다. 허나 가끔씩 노출이 되어야 하는 경우가 있다.

 

 

 

예제1)

 

class School{
	String name="학교";
	public School() {
		System.out.println("School()...");
	}
}//class end

class MiddleSchool extends School{
	String name="중학교";
	public MiddleSchool() {
		super(); //생략가능하다.
		System.out.println("MiddleSchool()...");
	}
}//class end

class HighSchool extends School{
	String name="고등학교";
	public HighSchool() {
		System.out.println("HighSchool()...");
	}
	public void disp() {	//method 멤버함수
		String name="종로고등학교"; 	//지역변수의 우선순위가 가장 높다
		System.out.println(name);	//종로고등학교
		System.out.println(this.name);	//고등학교
		System.out.println(super.name);	//학교
	}//disp() end
}//class end

public class Test01_super {
	public static void main(String[] args) {
		
		//School()->MiddleSchool()
		MiddleSchool ms=new MiddleSchool();
		
		//School()->HighSchool()
		HighSchool hs=new HighSchool();
		hs.disp();

	}//main() end
}//class end

결과값

School()...
MiddleSchool()...
School()...
HighSchool()...
종로고등학교
고등학교
학교

 

 

예제2)

 

class Parent{
	int one, two;
	public Parent() {}
	
	public Parent(int one, int two) {
		this.one = one;
		this.two = two;
	}
}//class end

class Child extends Parent{
	int three;
	public Child() {
		super();
	}
	public Child(int a, int b, int c) {
		//1)one, two멤버변수가 private속성이면 에러발생
		//super.one=a;//private이 아니기 때문에 one값이 출력됨
		//super.two=b;
		
		//2)상속받은 멤버변수(one, two)에 초기값 전달
		super(a, b);
		this.three=c;
	}
}//class end

public class Test02_super {
	public static void main(String[] args) {
		
		Child child=new Child(10, 20, 30);
		System.out.println(child.one); //10
		System.out.println(child.two); //20
		System.out.println(child.three);//30
		
		
	}//main() end
}//class end

 

 

 

 

다형성 Polymorphism (★★★★★)

다형성은 같은 형이지만 실행 결과가 다양한 객체를 이용할 수 있는 성질을 말한다. 코드 측면에서 보면 다형성은 하나의 자료형에 여러 객체를 대입함으로써 다양한 기능을 이용할 수 있도록 해준다. 다형성을 위해 자바는 부모 클래스로 형변환을 허용한다. 

형변환이란 데이터 자료형을 다른 데이터 자료형으로 변환하는 행위를 말한다. 기본형 변환은 미리 학습한 바 있고, 클래스형도 마찬가지로 형변환이 있다. 클래스 형변환은 상속 관계에 있는 클래스 사이에서 발생한다.

 

즉, 상속 관계에서의 다형성은 부모 클래스의 입장에서 형태가 여러 가지로 나뉘고, 클래스 간의 형변환이 이루어진다는 것을 의미한다.

 

다형성은 상속, 추상화와 함께 객체지향 프로그래밍을 구성하는 중요한 특징 중 하나이다.

 

1. 다형성은 하나의 객체를 여러 타입으로 선언할 수 있다는 뜻이다.

2. Java에서 다형성은 상속과 인터페이스를 통해 이루어진다.

3. 인터페이스가 상속보다 다형성에 더욱 유연함을 제공한다.

 

//다형성의 예)
Calendar cal=new GregorianCalendar();
//java.lang.Object > java.util.Calendar > java.util.GregorianCalendar

 

 

1) 일반적인 방식의 객체 생성

    → new 연산자 이용

    → POJO(Plain Old Java Object) 방식

 

import java.util.Calendar;
import java.util.GregorianCalendar;

class Father{
	public String name="아버지";
	public String addr="주소";
	
	public Father() {}	//default constructor
	public Father(String name, String addr) {
		this.name = name;	//this.멤버변수=매개변수
		this.addr = addr;
	}
	
	public void disp() {	//멤버함수 method
		System.out.println(this.name);
		System.out.println(this.addr);
	}//disp() end	
}//class end

class Son extends Father{
	public Son() {}
	public Son(String n, String a) {
		super.name=n;
		super.addr=a;
	}
}//class end

class Daughter extends Father{
	String friend="절친";
	public Daughter() {}
	public Daughter(String n, String a) {
		super(n, a);	//부모생성자함수호출 super()
	}
}//class end


public class Test03_poly {
	public static void main(String[] args) {
    		//다형성 Polymorphism
		//상속관계에서의 다형성
		//->부모클래스의 입장에서 형태가 여러 가지
        
        	//다형성의 핵심->자식이 부모 집에 들어갈 수 있다? 있다.
		
		Father fa=new Father();
		fa.disp();		
		
		Son son=new Son("손흥민", "영국");
		son.disp();
	
		Daughter dau=new Daughter("김연아", "한국");
		dau.disp();
		
	}//main() end
}//class end

 

Son과 Daughter이 Father의 의지를 계승하였다.

overload가 진행되지 않으면 부모의 값이 출력된다.

 

 

 

2) 다형성을 이용한 객체 생성

    → 자식 클래스가 부모 클래스에 대입 가능하다.

 

Father fa=new Son("개나리", "관철동");
fa.disp();
		
fa=new Daughter("진달래", "인사동");
fa.disp();

 

결과값

개나리
관철동
진달래
인사동

 

 

부모 클래스도 자식 클래스에 대입 가능하다. 

단, 자식 클래스의 모습으로 형변환해야 한다.

 

Father father=new Father();
Son son=new Son();

father=son;		//자식이 부모에 대입
son=(Son)father;	//부모가 자식에 대입

 

 

 

 

Object

자바 클래스의 최고 조상: Object

자바의 모든 클래스는 Object 클래스의 후손이다.

따라서 모든 클래스의 객체는 이 클래스 타입으로 형변환을 할 수 있다.

 

Object obj=new Integer(3);
Integer inte=(Integer) obj;
obj=new Father();

 

- toString( )의 오버라이드 자동 생성

  Source → Generate toString( )

 

 

 

 

Abstract(추상) 클래스

 

1) 추상화의 이해

- 구체적인 개념으로부터 공통된 부분들만 추려내어 일반화 할 수 있도록 하는 것을 의미

- 일반적으로 사용할 수 있는 단계가 아닌 아직 미완성적 개념

- 적용분야 : 메소드, 클래스

 

2) 추상 클래스의 구성

- 꼭 필요하지만 자손마다 다르게 구현될 것으로 예상되는 경우에 주로 사용

- 미완성 클래스. 미완성이기 때문에 메모리를 잡지 않는다.

 

- 추상 클래스는 추상 메소드가 1개 이상 선언되어 있다.

- 추상 클래스는 일반 메소드와 추상 메소드가 같이 선언 가능하다.

- 추상 클래스는 객체를 생성할 수 없다. new 연산자 직접 사용 불가능

- 추상 클래스는 반드시 상속 받아 자식 클래스에서 사용해야 한다.

- 추상 클래스가 객체를 생성하려면 추상 메소드를 Overriding(재정의)해야 한다.

- 추상 클래스에서 파생된 자식 클래스로 객체를 생성할 수 있다.

 

* 추상 메소드의 구성

- 미완성 메소드

  리턴형 함수명( );

- 메소드의 body { }가 없는 함수

- 메소드를 선언만 해 놓음

 

 

3) 추상 클래스 상속 관계에서의 다형성

- 부모 클래스로 상속 받은 자식 클래스의 객체를 생성할 수 있다.

- 부모 클래스의 이름으로 자식 클래스의 새로운 멤버에 접근할 수 없다.

- 자식 클래스로 부모 클래스의 객체는 생성할 수 없다.

 

 

예제1) 추상 클래스와 다형성

 

package oop0828;

abstract class Animal{		//추상 클래스
	String name;
	void view() {}		//일반 메소드
	abstract void disp();	//추상 메소드(미완성 메소드)
}//class end

//추상 클래스는 자식들의 부모 역할만 주로 한다
//추상 클래스를 상속 받은 자식 클래스는 반드시 추상 메소드를 완성해야 한다(override)
class Elephant extends Animal{
	@Override
	void disp() {
		System.out.println("점보");
	}
}//class end

class Tuna extends Animal{
	@Override
	void disp() {
		System.out.println("니모");
	}
}//class end


public class Test04_abstract {
	public static void main(String[] args) {
		//추상클래스 Abstract class
		//->미완성 클래스 (미완성이기 때문에 메모리를 잡지 않는다)
		//*인터페이스는 빈집 만들기
		//->추상메소드가 1개라도 있으면 추상 클래스
		//->일반메소드와 추상메소드가 같이 선언가능하다
		//->객체를 생성할 수 없다
		//->new 연산자를 직접 사용할 수 없다
		
		//추상메소드
		//->미완성 메소드 *미완성 메소드가 무엇인가? 형식을 보면 알 수 있다
		//->형식)리턴형 함수명();
		//->메소드의 body {}가 없는 함수
		//->메소드를 선언만 해 놓음
		
		//인터페이스: 추상메소드만 선언 가능하다
		//*추상클래스와 인터페이스는 추상메소드를 선언 -> 
		
//-----------------------------------------------------------
		//추상클래스는 new 연산자로 직접 객체생성할 수 없다
		//Animal ani=new Animal(); //에러
		
		Elephant jumbo=new Elephant();
		jumbo.disp(); //점보
		
		Tuna nemo=new Tuna();
		nemo.disp(); //니모
		
		//다형성(*자식이 부모 집에 들어가는 패턴)
		Animal animal=new Elephant();
		animal.disp(); //점보
		
		animal=new Tuna();
		animal.disp(); //니모
		
	}//main() end
}//class end

 

 

예제2) 추상 메소드를 활용한 추상 클래스와 다형성

 

package oop0828;

abstract class Travel{				//추상 클래스
	void view() {}					//일반 메소드
	abstract String TravelWhere();	//추상 메소드
}//class end

class TypeA extends Travel{
	@Override
	String TravelWhere() {
		return "제주도 올레길";
	}
}//class end

class TypeB extends Travel{
	@Override
	String TravelWhere() {
		return "여의도 불꽃축제";
	}
}//class end

class TypeC extends Travel{
	@Override
	String TravelWhere() {
		return "지리산 둘레길";
	}
}//class end


public class Test05_abstract {
	public static void main(String[] args) {
		//추상클래스와 다형성
		
		Travel tour=new TypeA();
		System.out.println(tour.TravelWhere()); //제주도 올레길
		
		tour=new TypeB();
		System.out.println(tour.TravelWhere()); //여의도 불꽃축제
		
		tour=new TypeC();
		System.out.println(tour.TravelWhere()); //지리산 둘레길
		
	}//main() end
}//class end

 

 

 

 

Interface 인터페이스

 

1) 인터페이스 정의

- 추상 메소드로만 구성되어 있다.

- 추상 클래스보다 더 추상화 되어 있다.

- 서비스 요청에 따른 중계자 역할을 하는 것.

  실제 구현된 것이 전혀 없는 기본 설계도(메뉴판)

- 인터페이스는 일반 멤버 변수, 일반 멤버 메소드를 갖지 못한다.

- 변수는 상수로 자동 설정, 메소드는 추상 메소드로 정의

- 일반 클래스에서 implements 예약어로 특정 인터페이스를 구현하겠다고 명시해야 함

- 인터페이스가 가지는 추상 메소드들은 구현 받은 클래스에서 하나도 빠짐없이 오버라이딩해야 한다.

- 만들어진 인터페이스의 활용도가 더 높음

 

2) 인터페이스 형식

    [접근제한] interface 인터페이스명 {

                  상수;

                  추상 메소드;

    }

 

  - 구현

    class 클래스명 implements 인터페이스명 {

 

    }

 

 

예제1) 인터페이스와 다형성

 

package oop0828;

interface Animal2{
	//void disp() {} 	//에러. 일반 메소드 사용 불가
	abstract void kind();	//추상 메소드
	void breathe();		//abstract 생략 가능
}//interface end

//클래스 입장에서 부모가 클래스: extends 확장
//클래스 입장에서 부모가 인터페이스: implements 구현
class Elephant2 implements Animal2{

	@Override
	public void kind() {	//>override/Implements method
		System.out.println("포유류");
	}

	@Override
	public void breathe() {
		System.out.println("허파");
	}
	
}//class end

class Tuna2 implements Animal2{

	@Override
	public void kind() {
		System.out.println("어류");
	}

	@Override
	public void breathe() {
		System.out.println("아가미");
	}
	
}//class end


public class Test06_interface {
	public static void main(String[] args) {
		//인터페이스 interface
		//->추상 메소드로만 구성되어 있다
		//->추상 클래스보다 더 추상화 되어 있다
		//상속
		//->확장 extends
		//->구현 implements
		
//-----------------------------------------------------------
		//인터페이스는 자신으로 직접 객체 생성 불가능
		//Animal2 ani=new Animal2(); //에러
		
		//인터페이스에서의 다형성
		Animal2 ani=new Elephant2();
		ani.kind(); //포유류
		ani.breathe(); //허파
		
		ani=new Tuna2();
		ani.kind(); //어류
		ani.breathe(); //아가미

	}//main() end
}//class end

 

 

예제2) extends와 implements

         인터페이스의 다중 상속 

 

package oop0828;

class Unit{
	int currentHP;
	int x, y;
	
}//class end

interface Movable{
	void move(int x, int y);//추상 메소드
}//interface end

interface Attackable{
	void attack(Unit u);//추상 메소드
}//interface end

interface Fightable extends Movable, Attackable{
	//interface가 interface 상속할 때 extends
	//인터페이스 간의 상속은 다중 상속이 가능하다
}//interface end 

class Fight extends Unit		 
	    implements Fightable{
	//class가 class 상속할 때 extends
	//class가 interface 상속할 때 implements 
	//클래스 간의 상속은 단일 상속만 가능하다

	@Override
	public void move(int x, int y) {}

	@Override
	public void attack(Unit u) {}
	
}//class end

class Tetris extends Unit
	     implements Movable, Attackable{
	 		 //다중 구현이 가능하다
	@Override
	public void attack(Unit u) {}

	@Override
	public void move(int x, int y) {}
	
}//class end


public class Test07_interface {
	public static void main(String[] args) {
		//클래스와 인터페이스간의 상속
				
		
	}//main() end
}//class end

 

 

 

 

Anonymous(익명) 클래스

- 이름이 없는 클래스

- 이름이 없기 때문에 생성자를 가질 수 없음

- 한 번만 사용하고 버려지는 객체를 사용할 때 유용한 내부 클래스

 

- 이벤트 처리(마우스 클릭, 마우스 오버, 키보드 눌렀을 때 등)에 많이 사용

  예) 자바스크립트 → jQuery, Ajax

- GUI 어플리케이션(AWT, Swing)의 이벤트 처리에 주로 사용

  .Graphic User Interface 환경

  .Character User Interface 환경

 

 

① 내부 클래스의 이름과 참조할 수 있는 참조 변수가 없는 유형

   class Outer {

          ...

          public void methodA( ) {

                   new Inner( ) {

                   };

          }

          ...

   }

 

② 내부 클래스의 이름은 존재하지 않지만 참조할 수 있는 참조 변수의 이름이 있는 경우

   class Outer {

          ...

          Inner inn = new Inner ( ) {

          };

          ...

   }

 

 

예제1) 익명 클래스 

 

package oop0828;

interface IMessage{
	public void msgPrint();
}//interface end

class Message implements IMessage{
	@Override
	public void msgPrint() {
		System.out.println("Message클래스");
	}
}//class end


public class Test08_anonymous {
	public static void main(String[] args) {
		//익명 내부 클래스 Anonymous class
		
		//인터페이스는 직접 객체 생성할 수 없다
		//IMessage msg=new IMessage(); //에러
		
		//1)구현한 클래스
		Message msg=new Message();
		msg.msgPrint(); //Message클래스
		
		//2)다형성
		IMessage imess=new Message();
		imess.msgPrint(); //Message클래스
		
		//3)익명객체
		//->필요한 곳에서 일시적으로 생성
		//->이벤트
		//->모바일앱, JavaScript, jQuery 등에서 많이 사용
		//->예)$("button").click()
		IMessage mess=new IMessage() {
			@Override
			public void msgPrint() {
				System.out.println("익명객체");
			}
		};
		mess.msgPrint();
		
	}//main() end
}//class end

 

 

 

문제1) 살아온 날 수 구하기 (이후 추가)

 

package oop0828;

public class Test09_quiz {
	public static void main(String[] args) {
		//과제) 살아온 날 수 구하기		
		Sheng birth=new Sheng("8912301234567");
		
		if(birth.getdate()) {
			birth.disp();
		}else {
			System.out.println("주민번호 틀리다");
		}//if end

	}//main() end
}//class end