2010년 2월 22일 월요일

워렌 버핏이 미국의 대학생들에게..

자신의 미래 수익의 10%를 투자해야 한다면.

투자하고 싶은 사람을 주위에서 골라보십시요.

 

대부분은

가장 잘생긴 사람이나 운동을 잘하는 학생

키가 큰 학생, 가장 날쌘 학생

가장 돈이 많은 학생

나아가 가장 머리가 좋은 학생을 고르진 않습니다.

 

당신이 고르는 대상은 그들 가운데

가장 인격이 뛰어난 사람 일것입니다.

 

누가 가장 많은 수익을 올릴지 모든 사람은

본능적으로 알기 때문입니다.

 

 

거꾸로.

당신이 가장 투자하고 싶지 않은 사람,

다시 말해 가장 수익이 떨어질것으로 보이는 사람을 골라보십시요.

 

이번에도 가장 성적이 떨어지거나

운동시합이 있을때마다 후보신세를 벗어나지 못하고 만년벤치나

데우고 있는 학생이나.

나아가 지능이 가장 떨어지는 학생이 아닐 가능성이 큽니다.

 

당신이 고르는 대상은

잔머리를 굴리고 거짓말을 하고

남의 공로를 가로채는-

신뢰할수 없고 이기적이고 오만하며 독선적이고

신용이 없는 사람일것입니다.

 

 

이 두 부류 사람들의 차이는

인생에서 성공하느냐

실패하느냐의 차이입니다.

 

인격은

당신의 말,. 행동, 옷차림,

당신이 쓴 글,

심지어 당신의 생김새에서 까지..

모든면에서 들어납니다.

결코 숨길수도 위조할수도 없습니다.

 

숨길수 없지만..

고쳐질수 없는 것도 아니니 희망을 잃지 마십시요.

 

인격 또한 하나의 습관이기 때문이다.

 

당신이 닮고 싶은 사람의 인격의 특징을

종이 한장에다가 써보십시요.

 

반대로 당신이 닮고 싶지 않은

사람의 인격의 특징을 써보십시요.

 

그리고 둘 사이의 차이를 비교해보십시요.

 

그것은 결코 큰 차이가 아닐것입니다.

 

야구공은 100미터 넘게 던지느냐.못던지느냐의

역기를 100킬로 넘게 드느냐. 마느냐의 차이가 아닐것입니다.

 

거짓말을 하느냐. 안하느냐.

 

자기마음대로 말을 내밷느냐.

한번더 생각을 하느냐.

 

남을 배려하는 말투인가.

남을 무시하는 말투인가.

 

조금 더 신경써서 일하느냐.

조금 더 게으르게 행동하느냐..

 

잘못을 저질렀을때.정직한가, 아니면, 둘러대며 남탓하는가.

 

결코 큰차이가 아닌..이런 작은 차이가

엄청난 차이를 만들어냅니다.

 

여러분이 아직 젊다면..

여러분이 닮고 싶은 인격을 조금만 신경써 연습한다면.

머지 않아 당신의 인격으로 만들수 있을것입니다.

 

인격 또한 습관이기 때문입니다.

 

습관은 처음엔 깃털같아 결코 느낄수 없지만.

나중엔 무거운 쇳덩이 같아 결코 바꿀수 없습니다.

 

내 나이때 습관을 고치는것은 거의 불가능에 가깝습니다.

여러분은 젊습니다.

아직 충분히 기회가 있습니다.

 

 

그리고 정직하십시요.

어떠한 경우에도 거짓말하지 마세요.

변호사가 뭐라하든 신경쓰지 마세요.

그저 자기가 보는 그대로 풀어놓으십시요.

 

 

저의 성공에는

우리(버크셔해서웨이)의 평판덕이 큽니다.

 

저는 저의 사람들에게

법의 테두리보다 훨씬 더 안쪽의 경계선에서 행동하며.

우리에게 비판적이고 또한 영리한 기자가

우리의 행동을 신문에 대서특필할수 있을 정도로.

행동하길 바랬습니다.

 

저는 저의 회사들의 지사장들에게 2년에 한번 이와같은

메세지를 줍니다.

 

"여러분은

돈을 잃어도 상관 없습니다.

많은 돈이어도 괜찮습니다. 하지만 평판을 잃지 마십시요.

인격을 잃지는 마십시요.

우리에겐 돈을 잃은 여유는 충분히 있으나.

평판을 잃는 여유는 조금도 없습니다."

 

여러분 (대학생들)은 아직 젊습니다.

지금의 모습보다 훨씬 낳아질 가능성이 충분합니다.

 

결코 돈 때문에 직장 선택하거나

사람을 사귀지 마십시요.

여러분이 좋아하는 직업을갖고

좋아하고 존경할 만한 사람만을 사귀십시요.

 

저는 아무리 큰 돈을 벌어준다고 해도.

도덕적으로 믿을수 없고.

신용이 가지 않은 사람과는 함께 사업을 하지 않습니다.

그것은

언젠가는 뱉어내야한다란걸 알고 있기때문입니다.

 

저는 1년내내 제가 좋아하는 일을

제가 좋아하는 사람들과만 함께 합니다.

제 속을 뒤집어 놓는 사람과는 상종도 안하죠.

결국 가장 중요한것은 이것이라고 생각합니다.

 

이것이 제 원칙입니다.

금전적으로 성공하는것은 두번째의 일입니다.

 

전 가난했던..젊은 시절에도.

저는 충분히 행복했고. 지금 처럼 제 일을 사랑했습니다.

가난했던때와 조금은 부유해진 지금과 바뀐것은

저에겐 별로 없습니다.

 

 

여러분들이 좋아하는 일을 즐겁게 하고.

성실히.

그리고 정직하게 생활한다면.

거기다 유머 또한 잃지 않고 하루를 유쾌히 감사한다면..

여러분은

성공을 결코 피할수 없을 겁니다.

 

 

 

- 워렌 버핏 미국의 대학생들에게 -

출처- 워렌버핏, 벤자민 그레이엄 연구모임(2007년 10월 27일)

2010년 2월 8일 월요일

4. 메소드

4. 메소드


억세서 메소드
클래스의 선언과 정의를 바르게 하고, Object 루트클래스의 alloc 메소드를 호출하면 클래스의 인스턴스가 생성됩니다. 클래스의 정의는 구조체의 선언과 같은 것으로, 인스턴스를 생성하는 것은 구조체형의 변수를 정의하고 구조체를 표현하기 위하여 필요한 메모리를 할당하는 행위와 비슷합니다. 그러나 클래스는 멤버변수와 그것을 처리하는 전용함수를 연결하는 점에서 구조체와 크게 다릅니다.


전회에 클래스를 선언하고, 메소드를 정의하여 그것을 호출하는 일을 했습니다. 전회의 메소드는 인수나 반환값을 전달하지 않는 매우 단순한 것이었지만, 여기서는 보다 복잣한 메소드를 실현하기 위하여 메소드를 상세히 해설합니다. 특히, 메소드는 함수와는 달리, 설계론의 개론에서 인스턴스나 클래스의 역할에 관련되어야 합니다.


예를 들면, 2차원좌표의 점을 나타내는 Point 클래스를 작성한다고 합니다. 이 경우 Point 클래스는 좌표 X와 Y를 제공해야 합니다. Point 클래스는 int형의 인스턴스변수 x와 y를 선언하고, 이들의 값을 제어하는 메소드군을 제공해야 할 필요가 있습니다.


원칙적으로, 클래스의 인스탄스변수에는 클래스의 외부에서는 억세스할 수 없습니다. 왜냐하면, 변수가 자유롭게 변경되어 버리면 변수의 의미나 입출력하는 데이터의 사양이 변경되는 경우 등, 보수성이나 코드전체의 유연성이 저하되기 때문입니다. 그래서, Objective-C 에는 변수에 억세스하기 위하여 메소드를 사용합니다. Point 클래스의 기본적인 선언은 다음과 같이 될 것입니다.

 

@interface Point : Object
{
 int x, y;
}
- (void)setPoint:(int)ptx:(int)pty;
- (int)getX;
- (int)getY;
@end

 

이 클래스의 선언에는 좌표를 보존하기 위하여 변수 x와 y를 선언하고, 이 변수에 클래스 외부에서 접근하기 위한 메소드를 선언합니다. setPoint 메소드는 x와 y의 값을 변경하기 위한 메소드로 getX와 getY메소드는 각각의 변수를 가져오기 위한 메소드입니다. 이같은 메소드를 특별히 억세서메소드라고 부릅니다. 또, 이같은 인스턴스의 성질에 관련된 외붕에 제공하기 위한 정보를 특별히 프로퍼티라고도 합니다.

 

인수를 받아들이는 메소드는 인수형을 ()의 속에 지정하고, 그 다음에 가인수의 이름을 지정합니다. 이 때의 ()는 캐스트식과 같이 형을 지정하지 않는 경우에는 반환값과 같이 id형이 기본값이 됩니다. 복수의 인수가 있는 경우, 다시금 콜론 : 에 이어 지정합니다. 보다 구체적으로는 메소드의 선언은 다음과 같습니다.

 

- (반환형)메소드명: (인수형) 변수명 레이블: ...

 

복수의 인수를 받아들이는 메소드는 변수명의 뒤에 레이블을 지정할 수 있습니다. 비교적, Objective-C의 세계에는 레이블을 지정하는 일이 습관이 되어있습니다만, 이 레이블과 콜론은 메소드명의 일부라고 인식되어지는 것입니다.


레이블과 콜론이 이름의 일부라고 인식되어지기 때문에, Objective-C에는 같은 반환값, 인수, 메소드명을 가진 메소드를 구별하여 호출하는 일을 할수 있습니다. 예를 들어 (void)setPoint:(int):(int) 라고 하는 메소드와 (void)setPoint:(int) label:(int) 메소드는 다른 메소드로 선언, 정의할 수 있습니다.

 

인수가 붙은 메소드의 호출에는 메시지식에 메소드명에 이어서 인수에 넘겨주는 값을 지정합니다. 레이블을 지정하지 않은 전자의 setPoint 의 경우 [obj setPoint:x:y] 라고 하는 형으로 호출하는대 반하여, 레이블을 붙인 메소드는 [obj setPoint:x label:y] 라는 형태로 호출합니다. 인수의 수나 레이블이 다르면, 메소드명이 같아도 구별하여 호출할수 있는 구조입니다. 특정의 기능을 제공하는 메소드를 여러 가지 형에 대응하여 제공하고 싶은 경우에 레이블이 필요하게 됩니다. setPoint 메소드를 , int형 이외의 정수에도 대응시키고 싶은 경우등은 중요할 것입니다.

 

#import <stdio.h>
#import <objc/Object.h>

@interface Point : Object
{
 int x, y;
}
- (void)setPoint:(int)ptx int:(int)pty;
- (int)getX;
- (int)getY;
@end

@implementation Point
- (void)setPoint:(int)ptx int:(int)pty {
 x = ptx;
 y = pty;
}
- (int)getX {
 return x;
}
- (int)getY {
 return y;
}
@end

int main() {
 id point1 , point2;
 point1 = [Point alloc];
 point2 = [Point alloc];

 [point1 setPoint:16 int:32];
 [point2 setPoint:256 int:128];

 printf("point1:X=%d, Y=%d\n", [point1 getX] , [point1 getY]);
 printf("point2:X=%d, Y=%d\n", [point2 getX] , [point2 getY]);
 return 0;
}

 

이 프로그램의 Point 클래스는 2개의 정수형인수를 받아들이는 setPoint:int: 메소드와 설정되어있는 좌표를 반환하는 getX, getY메소드를 선언하고 있습니다. setPoint 메소드의 선언은 setPoint(int)ptx:(int)pty 에도 문제없습니다만, 장래 setPoint를 확장하는 일을 생각할 경우는, 레이블을 지정하는 것이 좋을 것입니다.

 

main() 메소드에는 alloc 메소드를 이용하여 Ppint 클래스의 인스턴스를 2개 만듭니다. point1 변수와 point2변수가 가리키는 인스턴스는 다르기 때문에, 각각의 인스턴스에 설정된 값은 개별의 메모리에 보존되어있는 것이고, 출력결과에서 확인할 수 있습니다.

 


암묵의 self
메소드의 스코프범위 내에는 가인수나 선언된 변수이외에 암묵의 변수인 self과 정의되어있습니다. self 변수는 id형에 항상 메소드를 호출하는 인스턴스를 참조합니다. 즉, 메소드를 실행하는 오브젝트자신을 나타내는 변수가 self입니다.


self 는 메소드이에의 장소에서든 사용할 수 없고, 항상 메소드 실행코드부분에만 암묵적으로 존재합니다. self를 이용함에 다라, 오브젝트의 인스턴스변수에 오브젝트에서 참조하는 일이 가능합니다. 이것은, 메소드의 가인수의 변수명이 인스턴스 변수명을 은폐하고 있을 때등에 이용할 수 있습니다. 억세서메소드에는 특히 중요한 존재일 것입니다.

 

#import <stdio.h>
#import <objc/Object.h>

@interface Point : Object
{
 int x, y;
}
- (void)setPoint:(int)ptx int:(int)pty;
- (int)getX;
- (int)getY;
@end

@implementation Point
- (void)setPoint:(int)x int:(int)y {
 self->x = x;
 self->y = y;
}
- (int)getX {
 return x;
}
- (int)getY {
 return y;
}
@end

int main() {
 id point1 , point2;
 point1 = [Point alloc];
 point2 = [Point alloc];

 [point1 setPoint:32 int:64];
 [point2 setPoint:256 int:128];

 printf("point1:X=%d, Y=%d\n", [point1 getX] , [point1 getY]);
 printf("point2:X=%d, Y=%d\n", [point2 getX] , [point2 getY]);
 return 0;
}

 

이 프로그램의 setPoint:int: 메소드는 가인수에 선언된 이름이 인스턴스변수 x와 y에 충돌하고 잇습니다. 이것자체는 문제가 없습니다만, 이 변수의 스코프범위에는 인스턴스변수가 은폐되어 버립니다. 그래서 인스턴스변수에 억세스하는 수단으로, 현재의 메소드를 실행하고 있는 오브젝트를 참조하는 self변수를 사용합니다. 클래스외부에서 인스턴스변수에 참조하는 일은 할수 없지만, 메소드는 클래스의 내부이므로, 오브젝트에서 직접 인스터스변수에 억세스할 수 있습니다. 프로그램에는 self->x 라는 형태로, 인스턴스 변수에 넘겨준 데이터를 보존하고 있습니다.

또, 메소드에서 같은 인스탄스의 다른 메소드를 호출하는 경우에도 self가 필요합니다. 일부 메소드가 기능의 일부를 공유하고 있는 설계등에는 동일한 클래스의 다른 메소드를 호출할 필요가 있습니다.

 

#import <stdio.h>
#import <objc/Object.h>

@interface Test : Object
- (void)methodA;
- (void)methodB;
@end

@implementation Test
- (void)methodA {
 printf("method A\n");
 [self methodB];
}
- (void)methodB {
 printf("method B\n");
}
@end

int main() {
 [[Test alloc] methodA];
 return 0;
}

 

이 프로그램의 Test클래스에는 methodA메소드에서 methodB메소드를 self 오브젝트를 사용하여 호출하고 있습니다. self는 methodA를 실행하고 있는 인스턴스이므로, 동일 인스턴스의 methodB를 호출한다는 것입니다.

 

 

원본 : http://wisdom.sakura.ne.jp/programming/objc/objc4.html