객체 지향 중급 문법
상속
다형성
추상화 / 인터페이스
캡슐화
문법 - 알고리즘 - 디자인패턴(경험으로 만들어진 지식)
//시험
1. 서술형 ex.메서드가 뭔지 설명하시오(틀리면 감점, 상대적으로 너무 짧아도 감점)
2. 문제해결 시나리오 (어떤 에러인지 말하고 해결하려면 어떻게 하면 되는지)
3. 평가자 체크 리스트 (코드짜기 Yes/No 부분점수 없음, 이클립스를 허용하는 상황도 있고 못쓸수도 있음, 웹서핑+기존 워크스페이스 등은 사용 못함)
//요번주 시험은 서술형 1번+평가자체크리스트 1번 > 과락(40점 이하)없이 평균 60점, 이상 통과
public class Silver {
private int id;
private String name;
private int point;
public Silver(int id, String name, int point) {
this.id = id;
this.name = name;
this.point = point;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getPoint() {
return point;
}
public void setPoint(int point) {
this.point = point;
}
}
//mvc 패턴으로 제작
//main은 프론트 화면만
public class Manager {
private Silver[] members = new Silver[10]; // 인스턴스는 0개, 인스턴스를 저장할수 있는 실버형 변수 10개
//스텍: 메니저 참조변수(인스턴스주소)
//힙: 매니저 인스턴스 (멤버스라는 배열의 주소를 가진 참조변수) //
private int index = 0 ; // 지역변수로 놓으면 실행될때 마다 0으로 초기화, 멤버필드로 만들기
public void addMember(Silver s) { //주소를 받아서 배열의 0번칸에 담아라
members[0] = s;
}
public void printMember() {}
}
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
//메인은 프론트데스크 -> 정보는 전산팀에서
Manager manager = new Manager(); // 매니저 인스턴스 생성
Scanner sc = new Scanner(System.in);
System.out.println("=== 회원 관리 시스템 ===");
System.out.println("1. 신규 회원 등록");
System.out.println("2. 회원 목록 출력");
System.out.println("3. 종료");
System.out.println("> ");
String menu = sc.nextLine();
if(menu.contentEquals("1")) {
//입력받는 기능은 Manager에 넣는가? Main화면에 넣는가? -> 범용성, 재활용성 고려
// 다른 프로젝트(콘솔 입력외에 입력방식)에 Manager 클래스를 옮겼을때 그내로 활용할 수 있도록
System.out.println("회원번호 : ");
int id = Integer.parseInt(sc.nextLine());
System.out.println("회원이름 : ");
String name = sc.nextLine();
System.out.println("포인트 : ");
int point = Integer.parseInt(sc.nextLine());
manager.addMember(new Silver(id, name, point));
}else if(menu.contentEquals("2")) {
manager.printMember();
}else if(menu.contentEquals("3")) {
System.out.println("시스템을 종료합니다.");
System.exit(0);
}else {
System.out.println("메뉴를 다시 학인해주세요.");
}
}
}
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Manager manager = new Manager();
스텍 |
[ ] Manager manager (힙메모리에 멤버스/인덱스 가르킴) |
||
힙 |
new Manager |
members(배열 0번째 칸을 가르킴)
|
sliver형 변수 [ ][ ][ ][ ][ ][ ][ ][ ][ ][ ] |
index | |||
new 오른쪽이 인스턴스
기본자료형이면서 메서드 안에 있어야 Stack
멤버필드는 메서드 밖에
힙메모리 안에 쉐어드풀(스트링상수전용) 공간 있음 //지금하는 코드와는 무관
public class Manager {
private Silver[] members = new Silver[10];
private int index = 0 ;
public void addMember(Silver s) {
// addMember Stack( 매개변수 Silver s있음)
// Stack은 건초처럼 위로 쌓아가게 그림
members[index++] = s;
//멤버스 변수의 0번째 칸이 주소를 가르킴
}
모든 매서드 콜은 스텍 메모리를 만든다.
순간적으로 만들어졌다 지워짐
main 매서드의 지역변수들은 거의 안지워짐 (메인매서드가 프로그램 자체이기 때문에)
골드 멤버쉽 추가된 경우
public class Gold {
private int id;
private String name;
private int point;
public Gold() {}
public Gold(int id, String name, int point) {
super();
this.id = id;
this.name = name;
this.point = point;
}
public double getBonus() {
return this.point*0.03;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getPoint() {
return point;
}
public void setPoint(int point) {
this.point = point;
}
}
//mvc 패턴으로 제작
//main은 프론트 화면만
public class Manager {
private Silver[] silverMembers = new Silver[10];
private Gold[] goldMembers = new Gold[10];
private int silverIndex = 0 ;
private int goldIndex = 0 ;
public void addMember(Silver s) {
silverMembers[silverIndex++] = s;
}
public void addMember(Gold s) { // 오버로딩, 매서드이름같아도 매개변수가 다르면 다르다!
goldMembers[goldIndex++] = s;
}
public void printMember() {
System.out.println("=== 회원 목록 ===");
System.out.println("아이디\t이름\t포인트\t보너스");
for(int i=0; i< goldIndex ; i++) {
System.out.println(goldMembers[i].getId()+"\t"
+goldMembers[i].getName()+"\t"
+goldMembers[i].getPoint()+"\t"
+goldMembers[i].getBonus());
}
for(int i=0; i< silverIndex ; i++) {
System.out.println(silverMembers[i].getId()+"\t"
+silverMembers[i].getName()+"\t"
+silverMembers[i].getPoint()+"\t"
+silverMembers[i].getBonus());
}
}
}
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
//메인은 프론트데스크 -> 정보는 전산팀에서
Manager manager = new Manager(); // 매니저 인스턴스 생성
Scanner sc = new Scanner(System.in);
while(true){
System.out.println("=== 회원 관리 시스템 ===");
System.out.println("1. 신규 회원 등록");
System.out.println("2. 회원 목록 출력");
System.out.println("3. 종료");
System.out.print("> ");
String menu = sc.nextLine();
if(menu.contentEquals("1")) {
//입력받는 기능은 Manager에 넣는가? Main화면에 넣는가? -> 범용성, 재활용성 고려
// 다른 프로젝트(콘솔 입력외에 입력방식)에 Manager 클래스를 옮겼을때 그내로 활용할 수 있도록
manager.addMember(new Silver(1001, "Jack", 1000));
manager.addMember(new Silver(1002, "Tom", 2000));
manager.addMember(new Silver(1003, "Jane", 3000));
manager.addMember(new Gold(1004, "Susan", 4000));
}else if(menu.contentEquals("2")) {
manager.printMember();
}else if(menu.contentEquals("3")) {
System.out.println("시스템을 종료합니다.");
System.exit(0);
}else {
System.out.println("메뉴를 다시 학인해주세요.");
}
}
}
}
> 비효율적 (다음 멤버쉽이 추가되면? 기능이 많은 경우는?)
- 현재 작성한 회원 관리 시스템의 Critical한 문제점 3가지
- 코드 중복도 문제
- > (Silver , Gold, ....) > 상속(IS-A) 문법으로 해결
- 클래스간 결합도 문제
- > (Silver & Manager, ... ) > 의존도가 높다, 하나의 클래스가 빠지면 기능 못함, 클래스간 결합도가 낮을수록 좋다. > 다형성 문법으로 해결
- 저장소 문제
- (회원이 10명 넘으면 에러, 처음부터 크게 값을 잡아 놓으면 용량을 많이 차지) > Collection Framework로 해결
- 코드 중복도 문제
- 상속
- Class 간의 관계
- has-a
// 클래스간 관계 : Has-a 포함 관계
// A has a B : A가 B를 가진다
public class Police {
private Gun gun = new Gun(); //포함관계 Police has a Gun
}
public class Gun {
}
IS-A
//골드클래스는 멤버클래스를 확장한다.
//Member는 부모클래스, 상위클래스, super class
//Gold는 하위클래스, 자식클래스, derived class
//오류 발생
public class Silver extends Member{
public Silver(int id, String name, int point) {
this.id = id; //The field Member.id is not visible
this.name = name; //The field Member.id is not visible
this.point = point; //The field Member.id is not visible
//접근제한자를 건드리면 정보은닉을 부분적으로 잃음
//1. private > public 정보은닉을 못함, 안좋은 방법
//2. protected > 상속일 때는 public처럼 쓰임
//3. 안쓰면 패키지
}
}
//setter 사용
public class Silver extends Member{
public Silver(int id, String name, int point) {
this.setId(id);
this.setName(name);
this.setPoint(point);
}
}
public class Silver extends Member{
public Silver(int id, String name, int point) {
super(id,name,point); // 지워도 존재, 상위클래스의 생성자를 부른다.
//인자값 전달을 위해 사용
}
}
public class Member {
private int id;
private String name;
private int point;
public Member(int id, String name, int point) {
this.id =id;
this.name =name;
this.point =point;
}
public double getBonus() {
return this.point*0.03;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getPoint() {
return point;
}
public void setPoint(int point) {
this.point = point;
}
}
public class Gold extends Member{
/*
Implicit super constructor Member() is undefined for default constructor.
Must define an explicit constructor
*/
}
//Construct Member() 가 사라짐
> 골드 생성자를 명시
> Member class에 오버로딩 >> 오류는 사라지지만 값이 초기화 되지 않음
public class Gold extends Member{
public Gold(int id, String name, int point) {
super(id, name, point);
}
}
override Member.getBonus //무효화시키다
override 보다 더 좋은 방법
Member getBonus() 에서 리턴을 하면 안된다
>void로 만들면 오버라이드한 것들 다 작동안함
>>중괄호 지우고 세미콜론 넣기
설계목적으로 만들어진 코드라고 명시
> 아예 지우고 하위클래스에서 오버라이드 대신 각각 코드를 쓰지 않는 이유 > 묶어놨을 때의 이점 있음
설계목적이라면서 콜해버리면 어떻게함?
//설계목적이라면서 콜해버리면 어떻게함?
//클래스에도 abstract 달기, 추상클래스로 만들기
//추상클래스는 new가 안됨 > 인스턴스 못만듦 > call 될 수 없음
abstract public class Member {
private int id;
private String name;
private int point;
public Member(int id, String name, int point) {
this.id =id;
this.name =name;
this.point =point;
}
abstract public double getBonus();
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getPoint() {
return point;
}
public void setPoint(int point) {
this.point = point;
}
}
//다시 에러 발생, 상위클래스의 추상 메서드를 받을수 없어서
//내용을 채워줘야함
//추상 메서드를 상속 받을 때에는 implements 필수
//(추상 메서드에서는 오버라이드라고 하지 않음)
public class Gold extends Member{
public Gold(int id, String name, int point) {
super(id, name, point);
}
public double getBonus() {
return this.getPoint()* 0.03;
}
}
call back 패턴
다형성
class A{
}
class B{
}
//퍼블릭 클래스는 하나만
//퍼블릭이 아닌 클래스는 한 파일에 여러개여도 오류가 나지는 않음
//하지만, 파일 하나당 클래스 하나가 적절
public class Poly {
public static void main(String[] args) {
//다형성, 형태가 많은 성질
//변수 하나가 여러가지 (참조)자료형을 담을 수 있는 상태
A a = new B(); //Type mismatch: cannot convert from A to B
B b = new A(); //Type mismatch: cannot convert from A to B
//참조 자료형 간에 상속 관계에 놓였을때 허용
}
}
class A{
}
class B extends A{
}
public class Poly {
public static void main(String[] args) {
//다형성, 형태가 많은 성질
//변수 하나가 여러가지 (참조)자료형을 담을 수 있는 상태
A a = new B();
B b = new A(); //Type mismatch: cannot convert from A to B
//상위클래스의 참조변수는 자신을 상속 받는 하위클래스의 인스턴스를 저장 할 수 있다
}
}
그렇다면 a는 A로 동작할까 B로 동작할까?
B형 인스턴스 범위가 A보다 더 크다 (A를 상속 받고 확장)
기본적으로는 상위 인스턴스의 기능 사용
B형이라고 생각한다면 A,B 기능 둘다 사용 할 수 있다.
B형 인스턴스를 담을 수는 있지만 B형의 기능은 못쓴다?
B로 다운캐스팅하면 B의 기능도 쓸 수 있다.
예외적으로 down casting 없이 하위 인스턴스 사용하는 경우
- 다형성의 장점
- 모듈화 코드 작성 유리
- 코드 결합도를 낮추는 용도
- 편의성
//다형성 활용 예
public class Manager {
private Member[] members = new Member[10];
//member는 추상클래스 > 인스턴스를 만들 수 없다 .
//지금 이 코드는 멤버 인스턴스를 만든게 아니라 멤버형 변수를 만든 것
private int index = 0 ;
public void addMember(Member m) { //up casting되어
members[index++] = m; // member형으로 저장
}
public void printMember() {
System.out.println("=== 회원 목록 ===");
System.out.println("아이디\t이름\t포인트\t보너스");
for(int i=0; i< index ; i++) {
System.out.println(members[i].getId()+"\t"
+members[i].getName()+"\t"
+members[i].getPoint()+"\t"//멤버의기능(getId,getName,getPoint)만 볼수 있음
+members[i].getBonus()); //getBonus추상메서드가 implements된 값 나옴
}
}
}
암묵적
자바에 존재하는 모든 class는 상속을 받게 되어있다
class A extends Object{ //자바의 모든 class는 암묵적으로 extends Object 상속받음
// A is a Object : A는 객체이다
// Object는 모든 클래스의 최고 조상
}
class B extends A{
}
public class Poly {
public static void main(String[] args) {
//다형성
A a = new A();
a. //
}
}
ㄷ
import java.util.Scanner;
class A {
public void func () {};
}
class B extends A{
}
class C extends B{ //다중 상속, 자식이 아니라 자손
}// 모든 클래스는 어떤 방식이던 Object를 상속 (보이진 않지만)
public class Poly {
public static void main(String[] args) {
//다형성
Object o1 = new Object();
Object o2 = new Scanner(System.in);
Object o3 = new A();
Object o4 = new Silver(1006, "ABC", 1000);
Object o5 = 10; // new Integer(10); //auto boxing
//Object는 모두 담을 수 있다.
//기본형은 상속받는 건 아니지만 auto boxing(자동 형변환)일어남, 몇몇 참조변수만 허용
//Wrapper Class //시험내기 좋다.
// int Integer
// float Float
// double Double
// boolean Boolean
}
}
'디지털 컨버전스 > JAVA' 카테고리의 다른 글
[프로그래밍 언어 활용] 2020.02.21 시험대비 (0) | 2020.02.20 |
---|---|
[Java] Collection Framework, ArrayList, Generic, Foreach (0) | 2020.02.20 |
[Java] FTP (1) | 2020.02.18 |
[Java] member field , Constructor, 정적 변수, 라이브러리, FTP (0) | 2020.02.17 |
[Java] Method , OOP (객체 지향 프로그램) , 정보은닉 , 접근제한자 (0) | 2020.02.14 |