<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
	<id>https://workspace.onionmixer.net/wiki/index.php?action=history&amp;feed=atom&amp;title=AndreaSmalltalkLecture%3AQnA_07</id>
	<title>AndreaSmalltalkLecture:QnA 07 - Revision history</title>
	<link rel="self" type="application/atom+xml" href="https://workspace.onionmixer.net/wiki/index.php?action=history&amp;feed=atom&amp;title=AndreaSmalltalkLecture%3AQnA_07"/>
	<link rel="alternate" type="text/html" href="https://workspace.onionmixer.net/wiki/index.php?title=AndreaSmalltalkLecture:QnA_07&amp;action=history"/>
	<updated>2026-04-21T08:26:32Z</updated>
	<subtitle>Revision history for this page on the wiki</subtitle>
	<generator>MediaWiki 1.44.0</generator>
	<entry>
		<id>https://workspace.onionmixer.net/wiki/index.php?title=AndreaSmalltalkLecture:QnA_07&amp;diff=752&amp;oldid=prev</id>
		<title>Onionmixer: 안드레아::질문과답-7 페이지 추가</title>
		<link rel="alternate" type="text/html" href="https://workspace.onionmixer.net/wiki/index.php?title=AndreaSmalltalkLecture:QnA_07&amp;diff=752&amp;oldid=prev"/>
		<updated>2013-12-05T15:05:11Z</updated>

		<summary type="html">&lt;p&gt;안드레아::질문과답-7 페이지 추가&lt;/p&gt;
&lt;p&gt;&lt;b&gt;New page&lt;/b&gt;&lt;/p&gt;&lt;div&gt;;질문과 답변-7::Objective-C의 개략적 개념&lt;br /&gt;
&lt;br /&gt;
==Objective-C의 개략적 개념==&lt;br /&gt;
&lt;br /&gt;
음, 저도 Objective-C가 구체적으로 어떤 문법을 가지고 있는지는 잘 모 릅니다. 그저 간단하게 제가 알고있는 사항을 정리해드린다면...&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
우선  Objective-C는 보통 C언어에다가 Smalltalk를 합쳐놓았다고 생각하면 쉽습니다. 즉 C++는 OOP를 표현하기 위해서 C언어의 문법을 확장했지만, Objective-C는 C언어의 문법을 거의 그대로 사용하면서 OOP를 표현하고 싶을 때에는 Smalltalk의 형식을 빌었다고 생각됩니다. 이를테면&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;objc&amp;quot;&amp;gt;&lt;br /&gt;
if ( [anObject isKindOf: Integer] ) return -1;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
뭐 이런 식으로 코드가 적용된다고 알고 있습니다. 즉 C언어식으로 코딩을 하다가 OOP의 방식을 사용해야 할 경우에는 대괄호[ ] 안에 명령을 적어주는 식입니다. 흡사 Smalltalk에서 대괄호 안에 명령문을 적어넣어서 덩이(block)를 만드는 것과 같다고 보면 됩니다.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
그런데 이 Objective-C 는 두 개의 패러다임이 전혀 융화되지 않은 상태이고, 즉 물과 기름을 섞어놓은 듯한 상태이고, 또한 사용자들은 C 라는 철학과 OOP라는 철학을 함께 익히고 있어야 하므로 문법이 매우 복잡해 진다는 단점을 가지고 있습니다. 즉 이거면 이거, 저거면 저거가 아니라 물에 물 탄듯, 술에 술탄듯 하는 형상이라는 것이지요.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
뭐 C++도 별반 칭찬해줄 것은 없지만, 그래도 C++는 나름대로 C언어 안에서 OOP를 표현해보려고 시도를 한 셈이지요. 그러나 Objective-C 의 경우는 그게 그렇지가 않았으니까요. 한 가지 예를 더 들자면, 대괄호 안에서는 Smalltalk처럼 자료형에 대한 개념이 없으며(즉 변수에 자료형을 지정하지 않음), 대괄호 밖에서는 C언어처럼 자료형을 따집니다.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
아무튼 C++과 맞먹을 정도로 황당한 언어가 Objective-C라고 생각합니다.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Objective-C의 셈플코드==&lt;br /&gt;
&lt;br /&gt;
Objective-C의 셈플 소스코드랍니다. 저도 아직 다 이해는 못해봤지만, 도움이되셨으면 좋겠습니다.&lt;br /&gt;
&lt;br /&gt;
http://www.cis.ohio-state.edu/hypertext/faq/usenet/Objective-C/sample/faq.html 의 내용을 발췌한 것입니다.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;objc&amp;quot;&amp;gt;&lt;br /&gt;
// This is a comment, just like the previous line.  Everything to the right&lt;br /&gt;
// of a double slash is ignored.&lt;br /&gt;
&lt;br /&gt;
/* Classes are the one real extension which Objective-C adds to C.  A class&lt;br /&gt;
   is a description of a collection of data, like a C structure, and the&lt;br /&gt;
   methods by which that data may be accessed or manipulated.  Instances of&lt;br /&gt;
   a class are called objects, and methods are invoked by sending messages&lt;br /&gt;
   to either the class itself, to produce objects, or to those objects.  The&lt;br /&gt;
   recipient of a message is called a &amp;quot;receiver&amp;quot;.  The form of a message is:&lt;br /&gt;
&lt;br /&gt;
	[receiver method andMaybeSomeArguments]&lt;br /&gt;
&lt;br /&gt;
   the receiver and method components are mandatory, as are the square&lt;br /&gt;
   brackets surrounding the message.  Additional arguments may or may not be&lt;br /&gt;
   present, depending upon the method definition.  Messages may appear&lt;br /&gt;
   anywhere a statement is allowed in C.&lt;br /&gt;
&lt;br /&gt;
   The first thing we do is bring in some include files, as in C.  On the&lt;br /&gt;
   NeXT, it is customary to use the &amp;quot;import&amp;quot; statement which guarantees that&lt;br /&gt;
   the file isn&amp;#039;t included more than once.  Using GNU CC this is not all&lt;br /&gt;
   that nice sinds it generates a huge warning for every file being&lt;br /&gt;
   compiled.  So, since it does not really matter, we&amp;#039;ll stick to&lt;br /&gt;
   `#include&amp;#039;.  */&lt;br /&gt;
&lt;br /&gt;
#import &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#import &amp;lt;objc/Object.h&amp;gt;&lt;br /&gt;
#import &amp;quot;Queue.h&amp;quot;&lt;br /&gt;
#import &amp;quot;Stack.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
/* That brought in class definitions for Objects, Queues, and Stacks.  The&lt;br /&gt;
   Object class is the basis for all other classes, which is why it gets&lt;br /&gt;
   brought in first.  It provides basic functional behavior which is&lt;br /&gt;
   inherited by all derived classes.  All user created classes normally have&lt;br /&gt;
   Object somewhere in their ancestry.&lt;br /&gt;
&lt;br /&gt;
   Queue and Stack are classes of our own construction, and provide FIFO and&lt;br /&gt;
   LIFO storage capabilities, respectively.  I&amp;#039;m not going to go into&lt;br /&gt;
   implementation details here.  It&amp;#039;s irrelevant how they work, all that is&lt;br /&gt;
   important is that they both respond to &amp;#039;put:&amp;#039; and &amp;#039;get&amp;#039;.  If you want to&lt;br /&gt;
   inspect them, look into the Queue.m, Stack.m, Queue.h and Stack.h files.&lt;br /&gt;
&lt;br /&gt;
   A simple Class definition follows.  It inherits directly from the base&lt;br /&gt;
   class &amp;quot;Object&amp;quot;.  This gives it lots of nice properties, not the least of&lt;br /&gt;
   which is the ability to be referenced by any pointer of the generic&lt;br /&gt;
   object type &amp;quot;id&amp;quot;.  All objects can be pointed to by any id variable, and&lt;br /&gt;
   the default return type from methods is id.  This allows messages to be&lt;br /&gt;
   embedded in other messages, either as receivers or arguments.&lt;br /&gt;
&lt;br /&gt;
   An Int object allocates space for a single integer.  The &amp;quot;report&amp;quot; message&lt;br /&gt;
   causes it to report its value.  Everything between the @implementation&lt;br /&gt;
   and the @end is part of the class definition.&lt;br /&gt;
&lt;br /&gt;
   Note - It is *highly* unusual to have a class implementation in your main&lt;br /&gt;
   program.  Since the object is fully defined before it gets used, no&lt;br /&gt;
   interface description is required.  There is nothing illegal about doing&lt;br /&gt;
   things this way, but it is so unusual that the compiler will produce a&lt;br /&gt;
   warning for this class.  The Int class implementation is here solely for&lt;br /&gt;
   expository purposes.  */&lt;br /&gt;
&lt;br /&gt;
@implementation Int: Object	// Int is derived from Object&lt;br /&gt;
{&lt;br /&gt;
    int value;		// This is the data portion.  Like a struct.&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* The following are the method definitions.  A `+&amp;#039; prefix means it is a&lt;br /&gt;
   factory method, i.e., how to manufacture instances of the class.  The&lt;br /&gt;
   body of the method is between braces, like a C function.&lt;br /&gt;
&lt;br /&gt;
   This class doesn&amp;#039;t define any factory methods.  It relies on the +alloc&lt;br /&gt;
   method defined in class Object.  For examples of factory methods, look at&lt;br /&gt;
   the +new method defined in the Stack or Queue implementations.&lt;br /&gt;
&lt;br /&gt;
   Self is a special variable, which refers to the object currently being&lt;br /&gt;
   manipulated.  Super refers to the parent class of self.  The following&lt;br /&gt;
   method asks the parent class (Object) to hand us a new instance, which&lt;br /&gt;
   becomes self.  Then we update the instance variables and return a pointer&lt;br /&gt;
   to the new object.&lt;br /&gt;
&lt;br /&gt;
   It is standard for methods that do not need to return any special value&lt;br /&gt;
   to instead return self.  This allows for a nested syntax of method calls.&lt;br /&gt;
&lt;br /&gt;
   The &amp;quot;-&amp;quot; in front of init means that it&amp;#039;s an instance method, i.e.,&lt;br /&gt;
   something a particular object should respond to.  */&lt;br /&gt;
&lt;br /&gt;
-init: (int) i&lt;br /&gt;
{&lt;br /&gt;
  /* Have our superclass initialize its part of us.  After that,&lt;br /&gt;
     initialize the part of us introduced by this class (Int).  */&lt;br /&gt;
  [super init];&lt;br /&gt;
  value = i;&lt;br /&gt;
  return self;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
-report&lt;br /&gt;
{&lt;br /&gt;
  printf (&amp;quot;%4d&amp;quot;, value);&lt;br /&gt;
  return self;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
@end&lt;br /&gt;
&lt;br /&gt;
/* We have implemented Float and Char classes more traditionally, using&lt;br /&gt;
   separate files for the interface (.h) and implementation (.m).  The Float&lt;br /&gt;
   and Char objects are like the Int object, but with the obvious difference&lt;br /&gt;
   that they work with floats and characters.  We include the interface&lt;br /&gt;
   definitions at this point.  */&lt;br /&gt;
&lt;br /&gt;
#import &amp;quot;Float.h&amp;quot;&lt;br /&gt;
#import &amp;quot;Char.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
/* If you inspect those files, note polymorphism -- methods have same&lt;br /&gt;
   names as in the Int class.  */&lt;br /&gt;
&lt;br /&gt;
int main (void)&lt;br /&gt;
{&lt;br /&gt;
    /* First create instances of &amp;quot;Stack&amp;quot; and &amp;quot;Queue&amp;quot; data structures.  */&lt;br /&gt;
    id queue = [[Queue alloc] init];&lt;br /&gt;
    id stack = [[Stack alloc] init];&lt;br /&gt;
    int i, reply;&lt;br /&gt;
    &lt;br /&gt;
    fprintf (stderr, &amp;quot;Include the Char class in the demo? (y/n): &amp;quot;);&lt;br /&gt;
&lt;br /&gt;
    /* Anything not matching `y.*&amp;#039; means no.  */&lt;br /&gt;
    reply = getchar ();&lt;br /&gt;
&lt;br /&gt;
    for (i = 5; i &amp;gt; -6; --i)&lt;br /&gt;
      {&lt;br /&gt;
	/* Depending on which version of the demo we&amp;#039;re running, we&lt;br /&gt;
	   alternately put Ints and Floats onto the queue and stack, or&lt;br /&gt;
	   Ints, Floats, and Chars.  */&lt;br /&gt;
	if (reply == &amp;#039;y&amp;#039;)&lt;br /&gt;
	  {&lt;br /&gt;
	    /* If I is odd we put an Int on the queue and a Char on the&lt;br /&gt;
	       stack.  If I is even we put an Char on the queue and a Float&lt;br /&gt;
	       on the stack.&lt;br /&gt;
&lt;br /&gt;
	       Since there is more than one method `-init:&amp;#039; and since&lt;br /&gt;
	       `+alloc&amp;#039; returns a plain, typeless, `id&amp;#039;, the compiler&lt;br /&gt;
	       doesn&amp;#039;t know the type of the object returned by alloc.  An&lt;br /&gt;
	       explicit cast (i.e. static type indication) ensures that the&lt;br /&gt;
	       compiler knows which `init:&amp;#039; is invoked---the one accepting a&lt;br /&gt;
	       char or the other one accepting an int.&lt;br /&gt;
&lt;br /&gt;
	       Another solution, which avoids the static type indication, is&lt;br /&gt;
	       to put typing information on the method in the method&amp;#039;s name.&lt;br /&gt;
	       This is done for the Float class.  */&lt;br /&gt;
	    id my_char = [(Char *) [Char alloc] init: &amp;#039;m&amp;#039; + i];&lt;br /&gt;
&lt;br /&gt;
	    if (i &amp;amp; 1)&lt;br /&gt;
	      {&lt;br /&gt;
		[queue put: [(Int *) [Int alloc] init: i]];&lt;br /&gt;
		[stack put: my_char];&lt;br /&gt;
	      }&lt;br /&gt;
	    else&lt;br /&gt;
	      {&lt;br /&gt;
		[queue put: my_char];&lt;br /&gt;
		[stack put: [[Float alloc] initFloatValue: i]];&lt;br /&gt;
	      }&lt;br /&gt;
          }&lt;br /&gt;
	else&lt;br /&gt;
	  {&lt;br /&gt;
	    /* If I is odd we put an Int on the queue and a Float on the&lt;br /&gt;
	       stack.  If I is even we put a Float on the queue and an Int&lt;br /&gt;
	       on the stack.  */&lt;br /&gt;
            [queue put: ((i &amp;amp; 1)&lt;br /&gt;
			 ? [(Int *) [Int alloc] init: i]&lt;br /&gt;
			 : [[Float alloc] initFloatValue: i])];&lt;br /&gt;
            [stack put: ((i &amp;amp; 1)&lt;br /&gt;
			 ? [[Float alloc] initFloatValue: i]&lt;br /&gt;
			 : [(Int*) [Int alloc] init: i])];&lt;br /&gt;
	}&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    while ([queue size] &amp;amp;&amp;amp; [stack size])&lt;br /&gt;
      {&lt;br /&gt;
	/* The following illustrates run-time binding.  Will report be&lt;br /&gt;
	   invoked for a Float object or an Int object?  Did the user elect&lt;br /&gt;
	   for Char objects at run time?  We don&amp;#039;t know ahead of time, but&lt;br /&gt;
	   with run-time binding and polymorphism it works properly.  The&lt;br /&gt;
	   burden is on the class implementer rather than the class user.&lt;br /&gt;
&lt;br /&gt;
	   Note that the following lines remain unchanged, whether we are&lt;br /&gt;
	   using the Char class or not.  The queue and stack hand us the&lt;br /&gt;
	   next object, it reports itself regardless of its type, and then&lt;br /&gt;
	   it frees itself.  */&lt;br /&gt;
&lt;br /&gt;
	printf (&amp;quot;queue:&amp;quot;);&lt;br /&gt;
	[[[queue get] report] free];&lt;br /&gt;
	printf (&amp;quot;, stack:&amp;quot;);&lt;br /&gt;
	[[[stack get] report] free];&lt;br /&gt;
	putchar(&amp;#039;\n&amp;#039;);&lt;br /&gt;
      }&lt;br /&gt;
  return 0;&lt;br /&gt;
}&lt;br /&gt;
__EOF__&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Notes==&lt;br /&gt;
&amp;lt;references /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Category:AndreaSmalltalkLecture]]&lt;/div&gt;</summary>
		<author><name>Onionmixer</name></author>
	</entry>
</feed>