ÀÌ ¼½¼ÇÀº ´ç½Å¿¡°Ô Replace
Inheritance With Delegation ¸®ÆÑÅ丵 ±â´ÉÀÇ Æ÷°ýÀûÀÎ overview¿Í how ÀÌ ¸®ÆÑÅ丵ÀÌ IntelliJ IDEA¿¡¼ »ç¿ëµÉ ¼ö Àִ°¡¸¦ Á¦°øÇÕ´Ï´Ù.
Replace Inheritance With Delegation ¸®ÆÑÅ丵 ±â´ÉÀº »ç¿ëÀÚ¿¡°Ô º£À̽º Ŭ·¡½º/ÀÎÅÍÆäÀ̽ººÎÅÍ Á¶»ó Ŭ·¡½º ÀνºÅϽº
¶Ç´Â °°Àº ÀÎÅÍÆäÀ̽º¸¦ ±¸ÇöÇÏ´Â ³»ºÎ Ŭ·¡½º·Î ÆÄ»ýÇÑ Á¤ÀÇ ¸Þ¼ÒµåÀÇ ½ÇÇàÀ» ´ë¸®ÇÏ´Â °ÍÀ» Çã¶ôÇÕ´Ï´Ù.
ÀÌ ¸®ÆÑÅ丵 ±â´É´Â ´ÙÀ½ ¹æ¹ý ÁßÀÇ ÇÑ °³·Î »ç¿ëµÉ ¼ö ÀÖ½À´Ï´Ù:
1. ¿À¹ö¶óÀ̵ù ¸Þ¼Òµå·Î:
public class ClassParent {
public void method1(){
method2();
}
public void method2(){
System.out.println("ClassParent");
}
}
public class ClassChild extends ClassParent {
public void method2(){
System.out.println("ClassChild");
}
}
¼ºê Ŭ·¡½º¿¡¼, method2´Â ºÎ¸ð Ŭ·¡½ºÀÇ »óÀÀÇÏ´Â ¸Þ¼Òµå¸¦ ¿À¹ö¶óÀ̵å ÇÕ´Ï´Ù. ¸®ÆÑÅ丵 method2 °¡ ´ë¸®µÇ°í ³ ÈÄ¿¡ ¼ºê Ŭ·¡½º¿Í ÄÚµå·ÎºÎÅÍÀÇ ½´ÆÛŬ·¡½º¿¡¼ ½ÇÇàÀº ´ÙÀ½°ú °°ÀÌ º¸ÀÏ °ÍÀÔ´Ï´Ù:
public class ClassChild {
private final MyClassParent classParent = new MyClassParent();
public void method2() {
classParent.method2();
}
private class MyClassParent extends ClassParent {
public void method2(){
System.out.println("ClassChild");
}
}
}
2. ÀÎÅÍÆäÀ̽º·Î:
public interface ParentInterface {
void method1();
void method2();
}
public class ClassParent implements ParentInterface {
public void method1(){
method2();
}
public void method2(){
System.out.println("ClassParent");
}
}
±×¸®°í ´ç½ÅÀÌ method1()À» ´ë¸®ÇÑ ÈÄÀÇ ÄÚµå.
public class ClassParent {
private final MyParentInterface parentInterface = new MyParentInterface();
public void method1() {
parentInterface.method1();
}
private class MyParentInterface implements ParentInterface {
public void method1(){
method2();
}
public void method2(){
System.out.println("ClassParent");
}
}
}
¸ðµç °æ¿ì¿¡, ºÎ¸ð Ŭ·¡½º/ÀÎÅÍÆäÀ̽ºÀÇ ¸Þ¼Òµå¸¦ ±¸ÇöÇϰí ÀÖ´Â ³»ºÎ Ŭ·¡½º´Â ±× ÀνºÅϽº¿Í ÇÔ²² »ý¼ºµË´Ï´Ù.
±×¸®°í ´ë¸®µÈ ¸Þ¼Òµå·ÎÀÇ ¸ðµç ÄÝÀº ÀÌ ³»ºÎ Ŭ·¡½º ÀνºÅϽº¸¦ »ç¿ëÇÏ¸é¼ ¼öÇàµË´Ï´Ù.
3. Ŭ·¡½º ¸â¹ö »ç¿ë:
ÀÌÀüÀÇ ¿¹¸¦ È®ÀåÇϰí ClassParent¸¦ »ç¿ëÇϰí ÀÖ´Â ¶Ç ÇϳªÀÇ Å¬·¡½º¸¦ Ãß°¡ÇϽʽÿÀ.
public class ClassUsage {
public ClassParent classParent = new ClassParent();
void methodInChild(){
classParent.method2();
classParent.method1();
myMethod(classParent);
ParentInterface pi = classParent;
//some code here
}
void myMethod(ParentInterface p){
//some code here
}
}
±× ´ÙÀ½ ¸®ÆÑÅ丵Àº ClassParent ¿¡¼ Àû¿ëµË´Ï´Ù. ±×¸®°í ´Ù½Ã method1()Àº ´ë¸®µË´Ï´Ù.
public class ClassParent {
private final MyParentInterface parentInterface = new MyParentInterface();
public ParentInterface getParentInterface() {
return parentInterface;
}
public void method1() {
parentInterface.method1();
}
private class MyParentInterface implements ParentInterface {
public void method1(){
method2();
}
public void method2(){
//some code here
}
}
}
public class ClassUsage {
public ClassParent classParent = new ClassParent();
void methodInChild(){
classParent.getParentInterface().method2();
classParent.method1();
myMethod(classParent.getParentInterface());
ParentInterface pi = classParent.getParentInterface();
//some code here
}
void myMethod(ParentInterface p){
//some code here
}
}
´ç½ÅÀÌ º¸´Â °Íó·³, ¸®ÆÑÅ丵 ÈÄ¿¡ º¸ÀÌÁö ¾Ê´Â Ŭ·¡½º ¸â¹ö¸¦ »ç¿ëÇϱâ À§Çؼ, Ưº°ÇÑ °ÔÅÍ ¸Þ¼Òµå(getParentInterface())´Â »ý¼ºµË´Ï´Ù. ±×·¯³ª, ´Ù¸¥ Ŭ·¡½º ¸â¹öÀÇ »ç¿ëÀº ¹Ù²îÁö ¾Ê¾Ò½À´Ï´Ù.
»ó¼ÓµÈ Ŭ·¡½º ¸â¹ö¸¦ ´ë¸®·Î ±³Ã¼Çϱâ À§Çؼ:
1. ¿¡µðÅÍ¿¡¼ ¶Ç´Â Project View / Commander ¿¡¼, ¸Þ¼Òµå/ÀÎÅÍÆäÀ̽º°¡ ´ë¸®·Î ±³Ã¼µÇ¾î¾ß¸¸ Çϴ Ŭ·¡½º À§¿¡ ij·µÀ» ¼³Á¤ÇÏ°í ¸ÞÀÎ ¸Þ´º ¶Ç´Â ¿À¸¥ÂÊ ¹öưÀ» Ŭ¸¯ÇÏ´Â °Í¿¡ ÀÇÇØ ºÒ·ÁÁö´Â ÆË¾÷ ¸Þ´º¿¡¼ Refactor | Replace
Inheritance With Delegation... ¸¦ Ŭ¸¯ÇϽʽÿÀ.
2. ´ç½ÅÀº Replace Inheritance With Delegation ´ÙÀ̾ó·Î±×¸¦ º¸°Ô µÉ °Í ÀÔ´Ï´Ù.

´ë¸®·Î »ó¼ÓÀ» ±³Ã¼
|
µå·Ó-´Ù¿î ¹Ú½º¿¡¼ ´ç½ÅÀº ´ë¸®·Î ±³Ã¼µÈ »ó¼Ó Ŭ·¡½º/ÀÎÅÍÆäÀ̽º¸¦ ¼±ÅÃÇÒ ¼ö ÀÖ½À´Ï´Ù.
|
Çʵå À̸§
|
À̸§À» ÀÔ·ÂÇϰųª, »ó¼Ó Ŭ·¡½º/ÀÎÅÍÆäÀ̽º ÀνºÅϽº¸¦ À§ÇÑ À̸§ÀÌ µÇ´Â Çʵ忡 ´ëÇØ IDEA¿¡ ÀÇÇØ Á¦¾ÈµÈ Çϳª¸¦ »ç¿ëÇÕ´Ï´Ù.
|
³»ºÎ Ŭ·¡½º À̸§
|
À̸§À» ÀÔ·ÂÇϰųª, »ó¼Ó Ŭ·¡½º/ÀÎÅÍÆäÀ̽º ±â´ÉÀ» Æ÷ÇÔÇÏ´Â ³»ºÎ Ŭ·¡½º¿¡ ´ëÇØ IDEA¿¡ ÀÇÇØ Á¦¾ÈµÈ Çϳª¸¦ »ç¿ëÇÕ´Ï´Ù.
|
´ë¸® ¸â¹ö
|
ÀÌ ÆÐ³ÎÀº °ü·Ã ÀÎÅÍÆäÀ̽º¿Í ¸Þ¼Òµå¸¦ Æ÷ÇÔÇÏ¸é¼ ´ë¸®µÉ ¼ö ÀÖ´Â ¸ðµç »ó¼Ó Ŭ·¡½º ¸â¹öÀÇ ¸ñ·ÏÀ» Ç¥½ÃÇÕ´Ï´Ù. ´ë¸®¸¦ À§ÇÑ Å¬·¡½º ¸â¹ö¸¦ ¸¶Å©Çϱâ À§ÇØ, ´ç½ÅÀº ±× ¿ÞÂÊ¿¡ üũ ¹Ú½º¸¦ ¼±ÅÃÇØ¾ß¸¸ ÇÕ´Ï´Ù.
|
´ë¸®µÈ ±¸¼º ¿ä¼Ò¸¦ À§ÇØ °ÔÅÍ »ý¼º
|
¸¸ÀÏ ¼±ÅõǸé, ´ë¸®ÀÚ Å¸°ÙÀ» À§ÇÑ °ÔÅͰ¡ »ý¼ºµË´Ï´Ù.
ÀÌ °ÔÅÍ´Â ¸®ÆÑÅ丵 ÀÌÈÄ º¸¿©ÁöÁö ¾Ê´Â ´ë¸®µÈ ±¸¼º ¿ä¼Ò¿¡ ¾×¼¼½ºÇϱâ À§ÇØ »ç¿ëµË´Ï´Ù.
|
º¯°æµÈ ¹Ì¸® º¸±â »ç¿ë
|
ÀÌ Ã¼Å© ¹Ú½º¸¦ ¼±ÅÃÇÏ¸é ´ç½Å¿¡°Ô »ç¿ëÀÌ ¹ß°ßµÈ °ÍÀÇ Á¤º¸¸¦ °è¼Ó ¾ò´Â °ÍÀ» Çã¶ôÇϰí, ´ç½Å¿¡°Ô ±×µéÀÇ ±³Ã¼¸¦ ½ÂÀÎÇÏ´Â °ÍÀ» Çã¶ôÇÕ´Ï´Ù.
ÀÌ Ã¼Å© ¹Ú½º°¡ ¼±ÅõÇÁö ¾ÊÀ» ¶§, IDEA´Â ±³Ã¼ ±â´É¸¦ ÀÚµ¿ÀûÀ¸·Î ¼öÇàÇÕ´Ï´Ù.

|
½ÉÁö¾î üũ ¹Ú½º°¡ È®ÀεÇÁö ¾Ê¾ÒÀ» ¶§µµ, ¸¸ÀÏ ¹ß°ßµÈ »ç¿ëÀÌ ¾î¶² Àбâ Àü¿ë ÆÄÀÏ¿¡¼ Á¸ÀçÇÏ¸é ´ç½Å¿¡°Ô »ç¿ë ±³Ã¼¸¦ È®ÀÎÇϱâ À§ÇØ ÇÁ·ÒÇÁÆ® µÉ °ÍÀÔ´Ï´Ù.
|
Refactoring Preview ´ÙÀ̾ó·Î±×(¸¸ÀÏ ±×°ÍÀÌ ³ªÅ¸³ª¸é)¿¡¼, ´ç½ÅÀº ¼öÇàµÈ º¯°æÀ» ºÐ¼®ÇÒ ¼ö ÀÖ½À´Ï´Ù.
¸®ÆÑÅ丵°ú ÇÔ²² ÁøÇàÇϱâ À§Çؼ, Do
Refactor Ŭ¸¯ÇϽʽÿÀ, ±×·¸Áö ¾Ê´Ù¸é Cancel À» Ŭ¸¯ÇϽʽÿÀ. ´õ¿í »ó¼¼ÇÑ °ÍÀº Refactoring
Preview¸¦ º¸½Ê½Ã¿À.
|
|
´ç½ÅÀÌ OK ¸¦ Ŭ¸¯ÇÏ°í ³ ÈÄ¿¡ ¸®ÆÑÅ丵Àº Àû¿ëµÉ °ÍÀÔ´Ï´Ù.
ÀϹÝÀûÀ¸·Î, ´ç½ÅÀº ´ÙÀ½ÀÇ º¯°æÀ» º¼ °ÍÀÔ´Ï´Ù:
1.
¸®ÆÑÅä(¼Ò½º)Ŭ·¡½º¿¡¼:
o ´ë¸® Ÿ°Ù(¸®ÆÑÅä Ŭ·¡½º ¸â¹ö°¡ ´ë¸®µÈ Ŭ·¡½ºÀÇ ÀνºÅϽº)À» Æ÷ÇÔÇÏ´Â Çʵ尡 »ý¼ºµË´Ï´Ù.
o
¸¸ÀÏ ¸®ÆÑÅä Ŭ·¡½º°¡ ´ë¸®ÀÚ Å¸°Ù Ŭ·¡½º/ÀÎÅÍÆäÀ̽º¸¦ ¿À¹ö¶óÀ̵ù/±¸ÇöÇÏ´Â ¸Þ¼Òµå¸¦ Æ÷ÇÔÇϸé, ³»ºÎ Ŭ·¡½º´Â »ý¼ºµË´Ï´Ù.
o ´ë¸®ÀÚ Å¸°ÙÀÌ À§ÀÓµÈ ¸Þ¼Òµå°¡ »ý¼ºµË´Ï´Ù
o±¸ÇöÀÌ ´ë¸® Ÿ°Ù¿¡ ´ë¸®¹ÞÀ¸¸é¼ÀÎ ¸Þ¼Òµå´Â »ý¼ºµË´Ï´Ù.
o »ó¼ÓÀº Á¦°ÅµË´Ï´Ù.
2.
¸®ÆÑÅä Ŭ·¡½º ÀνºÅϽºÀÇ »ç¿ë¿¡¼:

|
¸¸ÀÏ Generate
getter for delegated component ÀÌ Ã¼Å©µÇ¸é, Ŭ·¡½ºÀÇ ¸®ÆÑÅä Ŭ·¡½º ÀνºÅϽº »ç¿ëÀº
º¯°æµË´Ï´Ù.
|
»ç¿ëÀº µÎ °³ÀÇ Å¸ÀÔÀ¸·Î ³ª´²Áý´Ï´Ù:
o
not-delegated Ŭ·¡½º ¸â¹ö¿¡ ÀÚ°ÝÀ» ÁÖ´Â »ç¿ë.
¸¸ÀÏ ¸®ÆÑÅ丵 ÈÄÀÇ ±×·± ¸â¹ö°¡ º¸ÀÌ¸é ¾Æ¹«°Íµµ ÇÏÁö ¾Ê½À´Ï´Ù. ±×¸®°í ¸¸ÀÏ ÀÌ ¸â¹ö°¡ º¸ÀÌÁö ¾ÊÀ¸¸é, °ÔÅÍ ÄÝÀº »ðÀԵ˴ϴÙ. °ÔÅͰ¡ ¾øÀ¸¸é(¸¸ÀÏ Generate getter for delegated component °¡ üũµÇÁö ¾ÊÀ¸¸é) ±×·¯ÇÑ °æ¿ì¿¡ ´ç½Å¿¡°Ô Problems Detected ´ÙÀ̾ó·Î±×°¡ ÇÁ·ÒÇÁÆ® µÉ °Í ÀÔ´Ï´Ù.
oº¯¼ö¿¡ ÇÒ´çµÇ°Å³ª, ¸Å°³ º¯¼ö·Î¼ ³Ñ¾î°¡´Â »ç¿ë.
¸®ÆÑÅ丵 ÀÌÈÄ ¸¸ÀÏ ÀνºÅϽº Ŭ·¡½º°¡ Ÿ°Ù ŸÀÔ(±×°ÍÀÌ ÇÒ´çµÈ ÀÏÁ¾ÀÇ º¯¼ö ¶Ç´Â ±×°ÍÀÌ ³Ñ¾î°¡´Â ¸Å°³ º¯¼ö)¿¡¼ ¾Æ´Ï¸é, °ÔÅÍ´Â ¶ÇÇÑ »ðÀԵ˴ϴÙ. °ÔÅÍ ¾øÀÌ(¸¸ÀÏ Generate getter for delegated component °¡ üũµÇÁö ¾ÊÀ¸¸é) ±×·¯ÇÑ °æ¿ì¿¡ ´ç½Å¿¡°Ô Problems
Detected ´ÙÀ̾ó·Î±×°¡ ÇÁ·ÒÇÁÆ® µÉ °Í ÀÔ´Ï´Ù.
º°µµÀÇ ÁÖ¼®Àº ´ÙÀ½ÀÇ µÎ °æ¿ì¿¡ ÁÖ¾îÁý´Ï´Ù:
1. »ç¿ë Ÿ°Ù ŸÀÔÀº java.lang.Object ÀÏ ¶§, IDEAÀº °ÔÅÍ ÄÝÀ» »ðÀÔÇÏ´ÂÁö ¾Æ´ÑÁö ¾Ë°í ÀÖÁö ¾Ê½À´Ï´Ù.
¿¹¸¦ µé¸é:
public class ClassParent implements ParentInterface {
public void method1(){
method2();
}
public void method2(){
//some code here
}
}
public class ClassChild {
public ClassParent classParent = new ClassParent();
void methodInChild(){
ArrayList list = new ArrayList();
list.add(classParent);
// some complicated code...
ParentInterface intf = (ParentInterface) list.get(0);
ClassParent p = (ClassParent) list.get(0);
}
}
ÀÌ·± °æ¿ì¿¡, ÁÖ¿ä ¹®Á¦´Â ParentInterface intf = (ParentInterface) list.get(0); ¶Ç´Â
ClassParent p = (ClassParent) list.get(0); Áß¿¡ ¾î¶² °ÍÀ» ¾î´À ¹®¸Æ¿¡¼ ¸ñ·Ï ¿ä¼Ò°¡ ³ªÁß¿¡ »ç¿ëµÉ °ÍÀÎÁö
¾ËÁö ¸øÇÏ´Â µ¿¾È ¿ä¼Ò ¸ñ·ÏÀÌ ( lis.add(classParent) )¸¦ Ãß°¡ ÇÒ ¶§ IDEA°¡ °ÔÅ͸¦ ºÒ·¯¾ß ÇÏ´ÂÁö ¾Æ´ÑÁö °áÁ¤ÇÑ
¾Æ¹«·± Àå¼Ò°¡ ¾ø´Ù´Â °Í ÀÔ´Ï´Ù.
Problems Detected ´ÙÀ̾ó·Î±× °æ°í¸¦ ºÎ¸£´Â method1 ÄÝÀ» ´ë¸®Çϰí ÀÖ´Â ClassParent ¿¡¼ ¸®ÆÑÅ丵À» Àû¿ëÇϸé
java.lang.Object ¿¡ upcastingÀÌ ½ÃµµµË´Ï´Ù.

±×¸®°í ¸¸ÀÏ ´ç½ÅÀÌ °è¼ÓÇϱâ·Î °áÁ¤Çϸé, Instances
upcast to Object ¶ó°í ºÒ·ÁÁö´Â ºÐ¸®µÈ Find ÅÇÀº ´ç½Å¿¡°Ô ±×
ÀνºÅϽº¸¦ º¸¿©ÁÙ °ÍÀÔ´Ï´Ù.

ÀÌ ÅÇÀº ÂüÁ¶ ¸ñÀû¸¸À» À§ÇØ »ç¿ëµË´Ï´Ù.
¸¸ÀÏ ´ç½ÅÀÌ ¸®ÆÑÅ丵À» Àû¿ëÇϱâ·Î °áÁ¤Çϰí Refactoring preview ÅÇ¿¡¼ Do Refactor¸¦ ´©¸¥´Ù¸é,
¿À·ÎÁö not-Object-upcast ÀνºÅϽº´Â º¯°æµÉ °ÍÀÔ´Ï´Ù.
2. ¸®ÆÑÅ丵ÀÌ Ãß»ó Ŭ·¡½º¿¡¼ »ç¿ëµÉ ¶§ ´ÙÀ½ ¿¹¿¡ ³ªÅ¸³ª´Â °Í¿¡ µû¶ó ƯÁ¤ÀÇ ¶Ç ´Ù¸¥ °æ¿ì°¡ ÀÖ½À´Ï´Ù. public abstract class AbstractClass implements Runnable {
void activity() {
// ... some setup
run();
// ... some postprocessing
}
}
public class ImplementationClass extends AbstractClass {
public void run() {
// do something useful
}
}
±×¸®°í ¸®ÆÑÅ丵Àº AbstractClass ¿¡¼ ÀÎÅÍÆäÀ̽º ±â´ÉÀ» ´ë¸®Çϱâ À§ÇØ Àû¿ëµË´Ï´Ù.
public abstract class AbstractClass {
private final MyRunnable runnable = new MyRunnable();
void activity() {
// ... some setup
runnable.run();
// ... some postprocessing
}
protected abstract void run();
public Runnable getRunnable() {
return runnable;
}
private class MyRunnable implements Runnable {
public void run() {
AbstractClass. this .run();
}
}
}
¸®ÆÑÅ丵 ÀÌÈÄ, º¯°æÀº ´ÙÀ½°ú °°½À´Ï´Ù:
´ë¸®°¡ ¼öÇàµÈ(Åë»ó ÀÌ ¸®ÆÑÅ丵 ±â´É¿¡)°÷¿¡ Çʵå´Â Ãß°¡µË´Ï´Ù.
Ÿ°Ù ÀÎÅÍÆäÀ̽º¸¦ ½ÇÇàÇϰí ÀÖ´Â ³»ºÎ Ŭ·¡½º´Â Ãß°¡µË´Ï´Ù.
Ãß»ó Ŭ·¡½ºÀÇ °æ¿ì¿¡´Â, ÀÎÅÍÆäÀ̽º ¸Þ¼Òµå°¡ ¸®ÆÑÅä Ŭ·¡½º(¿©±â- AbstractClass)ÀÇ ¼ºê Ŭ·¡½º (¿©±â- ImplementationClass) ¿¡¼ ±¸ÇöµÈ °Í ÀÔ´Ï´Ù.
µû¶ó¼, À̸¥¹Ù ''reverse delegation '¿¡ ÀÇÇØ ¾Æ·¡¿¡ ¼³¸íÇÑ ¹Ù¿Í °°ÀÌ ´Þ¼ºµÉ ¼ö ÀÖ´Â ¼ºê Ŭ·¡½º·ÎºÎÅÍ ÀÌ ³»ºÎ Ŭ·¡½º´Â ¸Þ¼ÒµåÀÇ ±¸ÇöÀ» »ç¿ëÇØ¾ß¸¸ ÇÕ´Ï´Ù.
¸®ÆÑÅä Ŭ·¡½ºÀÇ ÀÎÅÍÆäÀ̽º ¹Ì ½ÇÀåÀ¸·ÎºÎÅÍÀÇ Ãß»ó ¸Þ¼Òµå´Â ÈÄÀÚ¿¡ ¸í¹éÈ÷ Ãß°¡µË´Ï´Ù. ±×¸®°í ³»ºÎ Ŭ·¡½ºÀÇ ÀÎÅÍÆäÀ̽º ±¸ÇöÀº ÀÌ ¸Þ¼Òµå¸¦ ºÎ¸¨´Ï´Ù. À̰ÍÀº ''reverse delegation '¶ó°í ºÒ¸³´Ï´Ù.
µû¶ó¼, ´ç½ÅÀº ÇൿÀÌ À¯ÁöµÈ °ÍÀ» ÇÁ·Î±×·¥ ÇÕ´Ï´Ù.
ÀÌ Æ¯Â¡Àº Ŭ·¡½º °èÃþ°ú ÇÔ²² »ç¼ÒÇÏÁö ¾ÊÀº ÀϺΠÁ¶ÀÛ¿¡ À¯¿ëÇÕ´Ï´Ù. À§ÀÇ ¿¹¸¦ µé¸é Çϳª´Â Extract Superclass
¸®ÆÑÅ丵À» Àû¿ëÇÒ ¼ö ÀÖ½À´Ï´Ù. »ý¼ºµÈ ½´ÆÛŬ·¡½º¿¡ runnable ÇÑ Çʵå¿Í ¸Þ¼Òµå activity À» ¿Å±é´Ï´Ù.
|