{"id":64,"date":"2009-10-28T20:00:37","date_gmt":"2009-10-28T07:00:37","guid":{"rendered":"http:\/\/www.paradicesoftware.com\/blog\/?p=64"},"modified":"2009-10-28T19:53:39","modified_gmt":"2009-10-28T06:53:39","slug":"oop-part-2-inheritance","status":"publish","type":"post","link":"http:\/\/www.paradicesoftware.com\/blog\/2009\/10\/oop-part-2-inheritance\/","title":{"rendered":"OOP Part 2: Inheritance"},"content":{"rendered":"<p>Last time, we talked about two different approaches to designing objects for a game or application: Inheritance and Composition. It&#8217;s time to look at the pros and cons in more detail. Let&#8217;s start with inheritance.<\/p>\n<h3>Inheritance<\/h3>\n<p>When learning OOP, inheritance is what you learn! Create a common, generic ancestor-type class, and create new classes for specific game objects which inherit from, override and extend the functions of the ancestor. Repeat as desired. Let&#8217;s look at the consequences of following this model:<\/p>\n<p>Pros:<\/p>\n<ol>\n<li>It&#8217;s easy to locate all functionality\u00a0belonging to each type: they&#8217;re\u00a0together in\u00a0the source for the child class.<\/li>\n<li>It&#8217;s easy to write an appropriate constructor for the type; so you know the classes internal state will be consistent.<\/li>\n<li>It&#8217;s\u00a0easy\u00a0to guard against the wrong\u00a0type being passed to a function at compile time: If you have <em>Function AttackMonster(WithWeapon: TWeapon);<\/em> the compiler will prevent you passing a <em>TItem<\/em> that isn&#8217;t a <em>TWeapon<\/em>.<\/li>\n<li>You can specify abstract methods in the parent where you know the divergent behaviour will be, and the language and compiler will help you\u00a0get there and warn you if you&#8217;ve left something out.<\/li>\n<\/ol>\n<p>Cons:<\/p>\n<ol>\n<li>You end up with *lots* of different classes &#8211; which may be in lots of different files.<\/li>\n<li>Some of the classes can be really, really small&#8230;\u00a0e.g., a single method override.<\/li>\n<li>When looking at the child class implementation with a call to the inherited parent, you don&#8217;t know exactly what the parent does.<\/li>\n<li>If two different children of a common ancestor need the same functionality, you have to\u00a0code it twice.<\/li>\n<li>Code that constructs instances\u00a0must take care to call the correct constructor.<\/li>\n<li>You can&#8217;t &#8220;switch&#8221; a child to\u00a0a different\u00a0type;\u00a0you need to destruct it and create a new instance of the other type.<\/li>\n<li>Greater risk of circular-references if your child classes need to interact with each other.<\/li>\n<\/ol>\n<p>You can see the pattern forming. The <strong>Pros<\/strong> of this model tend to be that things are easier to setup up-front, when you&#8217;re initially coding the classes. The <strong>Cons<\/strong> tend to hit you later: when you&#8217;re extending functionality, or just coming back to the code after time spent elsewhere.<\/p>\n<p>It&#8217;s also possible with this model to really make life impossible for yourself. If you come up against Con #4 and are tempted\u00a0to move some of\u00a0that common functionality in the parent class,\u00a0congratulations:\u00a0you just\u00a0blasted\u00a0Pro #1 and debugging and maintaining this code just became a nightmare,\u00a0and now the parent needs to duplicate some child\u00a0state in order to know which of these &#8220;optional-children&#8221; operations it should\u00a0perform. Ick!<\/p>\n<p>Note that this inheritance style is still arguably a gigantic code-safety and readibility improvement from old-style procedual code. The question is, can we do better? In Part 3, we&#8217;ll look at the alternative model of\u00a0Composited classes.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Last time, we talked about two different approaches to designing objects for a game or application: Inheritance and Composition. It&#8217;s time to look at the pros and cons in more detail. Let&#8217;s start with inheritance. Inheritance When learning OOP, inheritance is what you learn! Create a common, generic ancestor-type class, and create new classes for<\/p>\n","protected":false},"author":2722,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[6,3],"tags":[77,4,76,8],"class_list":["post-64","post","type-post","status-publish","format-standard","hentry","category-code","category-icefall","tag-code","tag-freepascal","tag-icefall","tag-oop"],"_links":{"self":[{"href":"http:\/\/www.paradicesoftware.com\/blog\/wp-json\/wp\/v2\/posts\/64","targetHints":{"allow":["GET"]}}],"collection":[{"href":"http:\/\/www.paradicesoftware.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"http:\/\/www.paradicesoftware.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"http:\/\/www.paradicesoftware.com\/blog\/wp-json\/wp\/v2\/users\/2722"}],"replies":[{"embeddable":true,"href":"http:\/\/www.paradicesoftware.com\/blog\/wp-json\/wp\/v2\/comments?post=64"}],"version-history":[{"count":10,"href":"http:\/\/www.paradicesoftware.com\/blog\/wp-json\/wp\/v2\/posts\/64\/revisions"}],"predecessor-version":[{"id":79,"href":"http:\/\/www.paradicesoftware.com\/blog\/wp-json\/wp\/v2\/posts\/64\/revisions\/79"}],"wp:attachment":[{"href":"http:\/\/www.paradicesoftware.com\/blog\/wp-json\/wp\/v2\/media?parent=64"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"http:\/\/www.paradicesoftware.com\/blog\/wp-json\/wp\/v2\/categories?post=64"},{"taxonomy":"post_tag","embeddable":true,"href":"http:\/\/www.paradicesoftware.com\/blog\/wp-json\/wp\/v2\/tags?post=64"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}