160323: 8회차
종료하기 전 티스토리 네이버 로그아웃 할 것
가끔 저장 해놓기.
1. 툴
동일
추가시: staruml 5.0
2. 폴더
동일
추가시:
3. 사용할 사이트
동일
추가시: \\172.16.3.249
4. 공부하는 것
오늘부터 상속!
: 부모가 자식한테 물려주는 것
부모(상위 클래스)의 특성(필드,메소드)를 자식(하위 클래스)에게 물려주는 것
superclass subclass
basicclass
기본 클래스 확장 클래스
특성을 물려주는 상위 클래스 특성을 물려받는 하위 클래스
부모의 특성을 재정의할 필요가 없어서 정의가 간결해짐
이거는 멤버 변수보다는 메소드를 상속하려고 쓰는 건데
부모 클래스 기능 확장할 때 얘를 직접 수정하지 않고 자식이 기능을 확장해서 씀 (메소드 추가!)
- 만약에 부모가 + 랑 - 기능 있으면 - 자식이 %랑 *랑 / 기능 만들면 부모가 주는 +랑 - 기능을 안 써놔도 쓰기 가능
기능이란 건 메소드란 뜻
구래서 기본 + 메소드 확장해서 쓰니까 자식클래스가 확장클래스
상속을 계속계속 하게 될 경우에는 기능이 짱 많아짐.
근데 a(부모) -> b(자식) 인 경우에 c(부모) -> b(자식) 이렇게 여러 클래스를 상속하지는 못함
(자바에서는 못함... c++에서는 가능이긴 한데 복잡한것)
상속을 안 쓰면 같은 기능을 쓰는 클래스가 여러개인데 상속 받으면 편함

이런 식으로 부모1 -> 부모2(부모1의 자식) -> 자식(부모2의 자식) 가능
상속 쓰는 법은
public class a{
} //맨 처음 부모 클래스
public class b extends a{
//a를 상속받는 클래스 b인것
}
public class c extends b{
//b를 상속받는 클래스 c인것
}
이렇게 쓰는 예시
package day08;
class Movie{
String prat = "영화";
}
class KorMovie extends Movie{
String m1 = "가문의 위기";
}
class ForMovie extends Movie{
String m1 = "박물관이 살아있다.";
}
public class MovieTest {
public static void main(String[] args) {
KorMovie k = new KorMovie();
System.out.println("장르: " + k.prat);
System.out.println("제목: " + k.m1);
ForMovie f = new ForMovie();
System.out.println("장르: " + f.prat);
System.out.println("제목: " + f.m1);
}
}
package day08;
class Movie{
String prat = "영화";
}
class KorMovie extends Movie{
String m1 = "가문의 위기";
}
class KorMovie2 extends KorMovie{
String m1 = "가문의 위기2";
}
class ForMovie extends Movie{
String m1 = "박물관이 살아있다.";
}
public class MovieTest {
public static void main(String[] args) {
KorMovie k = new KorMovie();
System.out.println("장르: " + k.prat);
System.out.println("제목: " + k.m1);
KorMovie2 k2 = new KorMovie2();
System.out.println("장르: " + k2.prat);
System.out.println("제목: " + k2.m1);
ForMovie f = new ForMovie();
System.out.println("장르: " + f.prat);
System.out.println("제목: " + f.m1);
}
}
요런 식으로
Movie -> KorMovie -> KorMovie2 인 경우에도 멤버변수 잘 쓸 수 있음
<<메모리친구>>
KorMovie k 생성시 Movie객체(그 전에 Object)를 먼저 만듬 - k.m1은 이 Movie객체도 접근 가능
- 항상 부모 영역 부터 만들고 쓰는 거라 상속 많이 쓰면 메모리 많이 먹음...
- Object 같은 거 쓰는 건 .hashCode() 이런 거 출력할 때 쓰는거임
사실 상속 쓸 때 무조건 private 멤버함수를 쓰니까 setter랑 getter 필수
//메소드 상속
package day08;
class Car {
public void gear() {
System.out.println("수동 기어를 사용합니다.");
}
}
class ChildCar extends Car {
public void auto_gear() {
System.out.println("자동 기어를 사용합니다.");
}
}
class ChildCar2 extends ChildCar {
// public void gear(){
// System.out.println("수동 기어를 사용하지 않습니다.");
// }
public void auto_gear2() {
System.out.println("수동/자동 기어를 혼합하여 사용합니다.");
}
}
public class CarTest {
public static void main(String[] args) {
ChildCar2 cc2 = new ChildCar2();
cc2.gear();
cc2.auto_gear();
cc2.auto_gear2();
}
}
그래도 해시코드는 childcar2 거만 cc2가 가지고 있는것
이렇게 보면 Object 상속받은 거 볼 수 있음.
그러니까 Object가 java.lang 패키지 내의 최상위 클래스인데
이런 클래스 구조도를 가지고 있음
출처: http://hyeonstorage.tistory.com/178
사용자가 클래스를 정의할 떄 extends java.lang.Object 를 안 도 자동으로 상속받게 되어
Object 클래스의 모든 메소드와 변수를 사용자가 만드는 모든 클래스에서 사용 가능하다.
---------------------------------------------------------------------------------
starUML 써보는 것
Empty project -> 모듈 익스플로러에 있는 거 f2 누르면 이름 변경 가능 -> package 상속 생성
상속 -> add Diagram -> class Diagram
Annotation 에서 더블클릭 해서 클래스 생성 후 Select(화살표 모양) - 하면 선택 가능
클래스에서 선택해서 Add attribute랑 Add operation 할 수 있음 (멤버랑 메소드)
-prat: string = 이거는 private 타입 String 변수임
String 안하고 starUML에서는 소문자 string
이걸 상속으로 만드려면
Generalization (상속) 누르고 그냥 부모한테 연결해 주면 됨
메인은
+main(args :string[]): void = +는 public 타입
그리고 static 변경법은
model Explorer 에서 - 밑에 properties 보면 detail에 OwnerScope를 CLASSIFIER로 변경해 주면 static으로 바뀐다.
Association - 양방향 이용 가능
DirectedAssociation - 한방향만 이용중인 것
<- 같이 생긴 건 : DirectedAssociation
◁- 같이 생긴 건 : Generalization
접근하는 건 위로만 올라감 (반대로 내려오면 안된다.)
CarTest.java는 이렇게.
-----------------------3교시---------------------
package day08;
class A {
public int p;
private int n;
public void setN(int n) {
this.n = n;
}
public int getN() {
return n;
}
}
class B extends A {
private int m;
public void setM(int m) {
this.m = m;
}
public int getM() {
return m;
}
public String toString() {
String s = getN() + " " + getM();
return s;
}
}
public class Main {
public static void main(String[] args) {
A a = new A();
a.setN(0);
System.out.println(a.getN());
B b = new B();
b.setN(1);
b.setM(2);
System.out.println(b.toString());
}
}
------------다른 패키지의 상속관계--------------------
package pb;
import pa.A3;
//package pa;
//
//public class A3 {
// int i;
// public int pub;
//
// protected int pro;
// private int pri;
//}
public class B3 extends A3{
void set(){
// i = 1; //default 멤버는 접근 불가능
pro = 2;
// pri = 3;//private 멤버도 접근 불가능
pub = 4;
}
void printSet(){
// System.out.println("i : " + i);
System.out.println("pro : " + pro);
// System.out.println("pri : " + pri);
System.out.println("pub : " + pub);
}
public static void main (String args []){
B3 b = new B3();
b.set();
b.printSet();
}
}
접근 제한자 같은 클래스 같은 패키지 상속관계의 다른 패키지 관련없는 다른 패키지
(같은 폴더) (폴더 상관없음) (다른 폴더)
------------ -----------------------------------------------------------------------------
private ○ X X X (중요)
-----------------------------------------------------------------------------------------
friendly ○ ○ X X
-----------------------------------------------------------------------------------------
protected ○ ○ ○ X
------------------------------------------------------------------------------------------
public ○ ○ ○ ○ (중요)
------------------------------------------------------------------------------------------
여기서 보면 protected는 남의 패키지라도 상속중이면 사용이 가능해서 오류나지 않는다.
근데 default = friendly는 상속중이더라도 남의 패키지면 사용이 불가능하다.
그래서
package pb;
import pa.A3;
/*
* package pa;
public class A3 {
public int pub;
protected int pro;
private int pri;
public int getPri(){
return pri;
}
public void setPri(int pri){
this.pri = pri;
}
int i;
public int getI(){
return i;
}
public void setI(int i){
this.i = i;
}
}
*
* */
public class B3 extends A3{
void set(){
setI(1); //default 멤버는 접근 불가능
pro = 2;
setPri(3);//private 멤버도 접근 불가능
pub = 4;
}
void printSet(){
System.out.println("i : " + getI());
System.out.println("pro : " + pro);
System.out.println("pri : " + getPri());
System.out.println("pub : " + pub);
}
public static void main (String args []){
B3 b = new B3();
b.set();
b.printSet();
}
}
JVM은
0. 생성자 자동으로 만들어 줌
1. java.lang 패키지는 자동 import
2. object 클래스는 클래스 자동 상속
//이렇게 하면 출력까지 됨
package pb;
import pa.A3;
/*
* package pa;
public class A3 {
public int pub;
protected int pro;
private int pri;
public int getPri(){
return pri;
}
public void setPri(int pri){
this.pri = pri;
}
int i;
public int getI(){
return i;
}
public void setI(int i){
this.i = i;
}
}
*
* */
public class B3 extends A3 {
void getValue() {
java.util.Scanner s = new java.util.Scanner(System.in);
System.out.println("i 값을 입력해주세요.");
setI(s.nextInt()); // default 멤버는 접근 불가능
System.out.println("pro 값을 입력해주세요.");
pro = s.nextInt();
System.out.println("Pri 값을 입력해주세요.");
setPri(s.nextInt());// private 멤버도 접근 불가능
System.out.println("pub 값을 입력해주세요.");
pub = s.nextInt();
}
void printValue() {
System.out.println("i : " + getI());
System.out.println("pro : " + pro);
System.out.println("pri : " + getPri());
System.out.println("pub : " + pub);
}
public static void main(String args[]) {
B3 b = new B3();
b.getValue();
b.printValue();
}
}
-메소드 이름, 메소드 인자 타입 및 개수, 리턴 타입이 다 동일해야함.
-그러니까 부모 클래스의 메소드를 자식이 재정의 하는거임
접근 지정자는 부모 클래스의 메소드의 접근지정자보다 좁아질 수 없다. (?)
출처: http://blog.eairship.kr/119
접근 지정자가 프라이빗 퍼블릭 프로텍티드 디폴트 이런거 있을 때
프로텍티드랑 퍼블릭이랑 디폴트만 접근 가능한데
접근 영역을 줄어들게 만들 수는 없음.
접근 많이 할 수 있는 순서: 퍼블릭>프로텍티드>디폴트
그러니까 부모가 프로텍티드면 자식이 퍼블릭으로는 못 만드는것
static이랑 private이랑 final은 오버라이딩 불가능 // static final이랑 private
//그럼 퍼블릭만 남는 것 아니쉼니까 ? -_-);;
return 타입 다른 경우 오류남!
이거 하면 부모 클래스의 메소드는 무시됨 - 자기가 정의한 걸 가져다 씀 (부모는 은닉됨) = 버전 업 개념
이게 다형성 구현의 핵심 원리인것
메신저 버전업한다고 안메신저 아닌것처럼 기능을 없애닌 게 아니라 기능 교체인것
------------------------코드---------------
package day08;
class OverA{
void show(String str){
System.out.println("상위클래스의 메소드 show(String str) 수행 " + str);
}
}
class SubOverA extends OverA{
void show(){
System.out.println("하위클래스의 메소드 show() 수행");
}
//메소드 인자 타입이 다르니까 오버라이딩 아님
//구냥 상속
//그리고 오버로딩일걸? 아마 값 주면 상위클래스 나옴
//이름이 같은 void 니까 맞음 - 근데 이렇게 해놓고
void show(String str){
System.out.println("나는 오버라이딩: " + str);
}
//이렇게 하면 메소드 이름이랑 인자 타입 및 개수가 같으니까 오버라이딩인것
//오버로딩: 같은 이름의 메소드를 여러개 가지면서
//매개변수의 유형과 개수가 다르도록 하는 기술
//오버라이딩: 상위 클래스가 가지고 있는 메소드를
//하위 클래스가 재정의 해서 사용하는것
//오버로딩은
//*하나의 클래스에서!!!!!!~@!!~!~!~!~!~!~!~!~!~ <- 꺙 'ㅅ'*
//함수명: 같음
//파라미터: 변수 타입 및 개수가 다름
//ㄴ 같은 경우에는 오버로딩이 아닌가?
//리턴 타입: 관계 없음
//사용: 같은 이름으로 함수 정의
//*하나의 클래스에서!!!!!!~@!!~!~!~!~!~!~!~!~!~ <- 꺙 'ㅅ'*
//오버라이딩은
//*자식 클래스에서!!!!!!~@!!~!~!~!~!~!~!~!~!~ <- 꺙 'ㅅ'*
//함수명: 같음
//파라미터: 같음
//리턴 타입: 같음
//사용: 자식 클래스에서 부모 클래스의 함수 재정의
//*자식 클래스에서!!!!!!~@!!~!~!~!~!~!~!~!~!~ <- 꺙 'ㅅ'*
}
public class OverrideExam1 {
public static void main(String[] args) {
SubOverA over = new SubOverA();
over.show("IT KOREA");
over.show();
}
}
package day08;
//하나의 메소드만 추가하면 오버로딩 + 오버라이딩 되게...
class OverA{
void show(String str){
System.out.println("상위클래스의 메소드 show(String str) 수행 " + str);
}
}
class SubOverA extends OverA{
void show(){
System.out.println("나는 오버로딩 : 입력받는 것 없음");
}
void show(String str){
System.out.println("나는 오버라이딩: " + str);
}
void printShow(){
java.util.Scanner s = new java.util.Scanner(System.in);
show();
System.out.println("↓ 값을 입력하세요!");
show(s.nextLine());
}
}
public class OverrideExam1 {
public static void main(String[] args) {
SubOverA over = new SubOverA();
over.printShow();
}
}
----------------------------------------------------------------------------------
객체 형변환
-상속 관계에서는 부모 자식간에 형변환 가능.
-상속 관계에서는 좌측에 부모클래스가 오고 - 우측에 자식클래스가 올 수 있다.
DObject p = new Line(); ---- 부모클래스 p = new 자식클래스();
그래도 실제로 메모리상에는 자식 객체를 생성하고 - 타입만 부모클래스라서 부모만 접근이 가능함 ㅇㅇ
오버라이딩 시에는 부모클래스 타입이더라도 자식클래스의 메소드가 호출됨.
1. 업캐스팅
2. 다운캐스팅이 있음
1. 업캐스팅
- 프로그램에서 이루어지는 자동 변환 타입
-(아까 위에거)
-서브 클래스의 레퍼런스 값을 슈퍼클래스 타입의 변수에 대입함
class Person{
class Student extends Person{
}
Student s = new Student();
Person p = s; // 이렇게 자식 클래스의 레퍼런스 값을 부모 클래스의 변수에 대입하면 부모만 가리킴
}
-------예시에 super()때문에 공부하고 복붙-------------
package day08;
class Pers{
String name;
String id;
//default
public Pers(String name){
this.name = name;
}//생성자
}
class Stud extends Pers{
//String name;
//String id; //사용가능
String grade;
String department;
public Stud(String name){
super(name);//슈퍼가 뭐람
/*
*
* http://neoroid.tistory.com/entry/Java-this-this-super-super-%EC%9D%98-%EC%9D%B4%ED%95%B4
*
* this / this() 하고
* super / super() 하고
*
* this.grade = "A"; 하면
* 이 grade는 이 클래스의 멤버인 것을 나타냄
*
* 근데 this()는 생성자를 호출하기 위해 사용함.
*
* person jame = new person(23, "david", "america");
* person jame = new person(23, "david");
*
* 이런 식으로 여러 종류 생성자가 있을 때 그냥
* 편하게 this(23, "david")처럼 입력해도 되나봄...
*
* 이런 식으로 super();는
* 현재 자식 클래스가 자신을 생성할 때
* 부모 클래스의 생성자를 불러서 한번 초기화 해주고 난 뒤
* 자신을 초기화하는 것임
*
* ---요기까지 보다 말아씀 ------
*
* */
}//생성자
}
public class UpCastingEx {
public static void main(String[] args) {
Pers p;
Stud s = new Stud("길동이");
p = s;
System.out.println(p.name);
// p.grade = "A"; //이거 p에는 없는 변수임
// p.department = "Com";//이것도 p에는 없는 멤버임
}
}
---------------------------------------------------
2. 다운캐스팅
업캐스팅 된 걸 도로 돌리는 거임
부모 클래스 레퍼런스를 자식 클래스 타입의 변수에 넣음
class Person{
}
class Student extends Person{
}
Student s = (Student)p;
----------------------
이런 식으로
public static void main(String[] args) {
Pers p;
Stud s = new Stud("길동이");
p = s;
Stud s2 = (Stud)p;
//s2에다가 p에있는 해시코드를 대입
도로 s->p->s2
다운 캐스팅 할때는 강제 형변환이 이루어지는것임 .
Stud s3 = new Pers(); //이거는 안됨
왜냐면 이거는 Pers를 만들 때 Stud가 만들어지지 않으니까
근데 Stud는 Pers도 만들어지니까 업캐스팅이 가능!
package day08;
class Pers{
String name;
String id;
//default
public Pers(String name){
this.name = name;
}//생성자
}
class Stud extends Pers{
//String name;
//String id; //사용가능
String grade;
String department;
public Stud(String name){
super(name);//슈퍼가 뭐람
/*
*
* http://neoroid.tistory.com/entry/Java-this-this-super-super-%EC%9D%98-%EC%9D%B4%ED%95%B4
*
* this / this() 하고
* super / super() 하고
*
* this.grade = "A"; 하면
* 이 grade는 이 클래스의 멤버인 것을 나타냄
*
* 근데 this()는 생성자를 호출하기 위해 사용함.
*
* person jame = new person(23, "david", "america");
* person jame = new person(23, "david");
*
* 이런 식으로 여러 종류 생성자가 있을 때 그냥
* 편하게 this(23, "david")처럼 입력해도 되나봄...
*
* 이런 식으로 super();는
* 현재 자식 클래스가 자신을 생성할 때
* 부모 클래스의 생성자를 불러서 한번 초기화 해주고 난 뒤
* 자신을 초기화하는 것임
*
* 부모 없이 자식이 존재하지 않으니까
* Stud를 만들려면 Pers를 만들어야 함
*
* 만약에 Stud s = new Stud()라고 할 때
* 얘를 만들기 위해서는
* 얘가 참조하는 Pers부터 만들어야함
*
* 그러면 Pers의 생성자를 찾아간 뒤
* Stud를 만드는 것인데
*
* 이럴 때 Pers의 생성자가 없으니까
* 디폴트값으로 public Pers()와 같이
* 생성자를 만듬.
*
* Stud가 Pers를 상속하니까
* Pers를 만들어야 하는데
* Stud의 생성자에서
* 명시적으로 Pers의 생성자를 적어주지
* 않았으므로 기본값으로
* super(); 를 부름.
*
* 이거 뜻은 부모의 pers() (기본 생성자)
* 를 실행하라는 말임.
*
* 그리고 super는 그냥
* 부모클래스의 필드값이나 메소드를 직접 부를 때 사용
*
* 만약에 Stud나 Pers 둘 다 모두
* setAge(int) 메소드가 있을 때
* 자식 클래스인 Stud에서
* 부모 클래스인 Pers의 setAge(int); 메소드를
* 부를 일이 생겼을 때는
*
* setAge(20); 하면
* Stud의 setAge 메소드를 부르게 되고
* 만약에 Stud에 setAge 메소드가 없으면
* Pers(부모 클래스)에 있는지 찾아보게 됨
*
* 근데 상속된 거 말고 부모의 setAge()를 부르고 싶을 떄는
* super.setAge(); 하면 됨
*
* 그러니까 super는
* 나에게 있는 메소드나 필드를 찾지 말고
* 내 부모 클래스에 있는 필드나 메소드를 사용해라.
*
* --그러니까 상위 클래스를 지칭하는 명령어-
*
* super.변수; //부모 클래스의 변수를 호출한다.
* super(); //부모 클래스의 생성자를 호출한다.
* super(매개변수); //부모 클래스의 생성자(입력값)을 호출한다.
* super.메소드(); //부모 클래스의 메소드를 호출한다.
* super.메소드(매개변수); //부모 클래스의 메소드(입력값)을 호출한다.
*
* */
}//생성자
}
public class UpCastingEx {
public static void main(String[] args) {
Pers p;
Stud s = new Stud("길동이");
p = s;
Stud s2 = (Stud)p;
//s2에다가 p에있는 해시코드를 대입
//Stud s3 = new Pers(); //이거는 안됨
//Pers 만든다고 Stud가 만들어지는게 아니니까
System.out.println(p.name);
// p.grade = "A"; //이거 p에는 없는 변수임
// p.department = "Com";//이것도 p에는 없는 멤버임
}
}
-----------------------------------------------------------------------------
내가 다운캐스팅 시스템을 잘 이해하지 못했음
다운캐스팅: 업캐스팅 된 것을 다시 돌리는 것
아! ㅇㅋ
만약에 업캐스팅 안 된 걸 다운캐스팅 하면 어떻게 될까 - 짜보기
어 이거 Person s = new Student ("kim");
이걸로 해 볼 것
객체 형변환 예제
package day08;
class TypeConvert{
String url = "http://www.kma.go.kr";
public void setUrl(String url){
this.url = url;
}
public String getUrl(){
return this.url;
}
}
public class TypeConvertTest {
public static void main(String[] args) {
TypeConvert tc = new TypeConvert();
Object obj = tc;
//업캐스팅하면
//객체 내에 있는 모든 멤버 접근은 불가능하고
//슈퍼클래스에 있는 멤버만 접근 가능.
//아! 그러니까 업캐스팅 해도 자기한테 있는 멤바만 접근 가능
//오브젝트 클래스의 메소드를 호출함 -_-);;
//System.out.println(obj.getUrl());
//obj 클래스에는 url이라는 스트링이 없음
System.out.println(tc.getUrl());
System.out.println(obj.hashCode());
System.out.println(tc.hashCode());
//아마 같게 나올 듯
//역시 같음
TypeConvert tc2 = (TypeConvert)obj;
System.out.println("tc2: " + tc2.getUrl());
System.out.println("tc2: " + tc2.hashCode());
}
}
----------------------------
동적바인딩 - 오버라이딩 + 업캐스팅 한 경우에 부모 객체에서 메소드 호출해도 자식 객체에 오버라이딩 된 메소드가 출력되는 것
source -> override / Implements Methods 해서 부모 것 오버라이딩 할 수 있는 메소드 생성 가능
그러면 toString을
package day08;
class TypeConvert{
String url = "http://www.kma.go.kr";
public void setUrl(String url){
this.url = url;
}
public String getUrl(){
return this.url;
}
@Override
public String toString() {
// TODO Auto-generated method stub
return "TypeConvert의 Override된 toString()";
}
}
public class TypeConvertTest {
public static void main(String[] args) {
TypeConvert tc = new TypeConvert();
Object obj = tc;
//업캐스팅하면
//객체 내에 있는 모든 멤버 접근은 불가능하고
//슈퍼클래스에 있는 멤버만 접근 가능.
//아! 그러니까 업캐스팅 해도 자기한테 있는 멤바만 접근 가능
//오브젝트 클래스의 메소드를 호출함 -_-);;
//System.out.println(obj.getUrl());
//obj 클래스에는 url이라는 스트링이 없음
System.out.println(tc.getUrl());
System.out.println(obj.hashCode());
System.out.println(obj.toString());
System.out.println(tc.hashCode());
//아마 같게 나올 듯
//역시 같음
TypeConvert tc2 = (TypeConvert)obj;
System.out.println("tc2: " + tc2.getUrl());
System.out.println("tc2: " + tc2.hashCode());
}
}
예전에 했던 예제로 상속 테스트하는 것
Dave's not here man
--------------------이거 넘 스트레스 받아서 소스 받음 -------------
package test.day03;
public class SwitchTest2 {
public static void main(String[] args) {
System.out.println("점수 " + "출력내용");
System.out.println("=================");
int score = 100 ;
int s = (score/10);
switch(s){
case 10:
System.out.println("");
break;
case 9:
System.out.println("등급은 A입니다.");
break;
case 8:
System.out.println("등급은 B입니다.");
break;
case 7:
System.out.println("등급은 C입니다.");
break;
case 6:
System.out.println("등급은 D입니다.");
break;
default:
System.out.println("노력하세요");
}
}
}
5. 수업
진도:
hw:
6. 할것
치즐 - 악기 튜닝 가능한 공방
아크릴 물감
'Programming' 카테고리의 다른 글
| 160325: 10회차 (0) | 2016.03.25 |
|---|---|
| 160324: 9회차 (2) | 2016.03.24 |
| 160322: 7회차 (4) | 2016.03.22 |
| 160321: 6회차 (1) | 2016.03.21 |
| 160318: 5일차 (2) | 2016.03.18 |
staruml-5.0-with-cm.vol1.egg