ID:154585
 
I've found it infinitely easier to create objects with some variables based off of a data object that belongs exclusively to that object, rather than setting variables for that object. For example,

obj
liquid_container
var/liquid/liquid
var/capacity
vial
blue_potion/New()
liquid = new /liquid/blue_potion

liquid
var
quantity = 1 //millilitres, or fl. oz., or whatever
taste = ""
proc/Drink(mob/M)
M << "It tastes [src.taste]."

blue_potion
taste = "like wild strawberries"
smell = "like mushrooms"
Drink(mob/M)
..()
M.mp = M.maxmp
M.hp = M.maxmp


I find that it works MUCH better than:

obj
liquid_container
var/taste
var/smell
var/capacity
proc/Drink(mob/M)
M << "It tastes [src.taste]."

vial
blue_potion
taste = "like wild strawberries"
smell = "like mushrooms"
Drink(mob/M)
..()
M.mp = M.maxmp
M.hp = M.maxmp


Why? Because then, if you ever wanted to change what was in a container, you could simply delete its liquid object and fill it with another. In the second case, however, you'd have to delete the object itself, and then recreate the object. That has potential problems if you set variables to equal that object (say if you're holding it in your hand or something, and you set the usr.rhnd variable to point to that object. If you ever want to change what's in the container, you'd have to delete the object, create a new one, then change usr.rhnd to point to the new one. But with the top method, you can change what's in it, and no other variables would be affected.)

Something to think about when you design modifiable objects!
On 1/11/01 2:05 pm Spuzzum wrote:
I've found it infinitely easier to create objects with some variables based off of a data object that belongs exclusively to that object, rather than setting variables for that object.

A good point...and this is known in the biz as "composition" or "containment".

That is, one object is composed of one or more other objects/contains one or more objects.

It's a very powerful OO approach, and one of the main reasons you don't need multiple inheritance even though some weenies think you do.
In response to Deadron (#1)
On 1/11/01 4:21 pm Deadron wrote:
It's a very powerful OO approach, and one of the main reasons you don't need multiple inheritance even though some weenies think you do.

I don't even know what multiple inheritance is!

I want to make good use of data objects, but I don't know where to start figuring out what to do with them. Ooh, nice Sidewalk Santas banner. All I can think is that... I could move ALL my object variables into data objects, then only give objects one variable, var/class or something.

Then when I wanted to totally change an object, like make a morningstar into a club (hey, maybe the ball & chain broke off), it'd be easy as pie. Just change obj.class from "morningstar" into "club."

obj/var/class

class
morningstar
var/weight = 7
var/damage = 10
club
var/weight = 4
var/damage = 5

Then I'd have to access variables like obj.class.weight, wouldn't I. Still, it looks like a fun way to get rid of types. Is this feasible? Would it make my savefiles bigger or smaller?

Z
In response to Zilal (#2)
I don't even know what multiple inheritance is!

It lets you dictate that a given object is a child of more than one parent class (or node, in DM terms). For example, say I have this object tree:

mob
horse
var/color
verb/mount(etc.)

steamPoweredVehicle
var/coalRemaining
verb/stoke(etc.)

...and then say I wanted to have some mad scientist build a steam-powered horse. With multiple inheritance, I could just tell the compiler that my infernalHorseAutomation node inherits from both the nodes above, and it would automatically get all the procs and vars of both.

One of the problems with this is that there's a chance of overlapping names. Suppose I'd also given horses a "stoke" verb that let the player pump up the horse's enthusiasm by giving it high-fives. Then the automaton node wouldn't know which verb to use when I referred to "stoke". Deadron could probably give you a lot more information about this than I can, though.

Java has an interesting approach to this problem. It lets you create "interfaces." As I understand it, an interface is just a guarantee that a given class will include certain procs or vars. So, if I tell the compiler that horse implements "ridable", and then I go to compile and the code doesn't include a "ride" proc for the horse, the compiler will warn me that I'm not fulfilling the contract.

The upshot is, in BYOND you can make an object hierarchy that makes sense, and allows certain objects to have selected behaviors of otherwise-unrelated objects; you just have to code a little more for it. Your example of changing a morningstar to a club is certainly feasible, though... I'd probably try to take it down at least to the level of /obj/melee_weapon or something, though, since the two items still have a lot in common.

And if you need to do radical transformations, it'd be just as easy to delete the old object and replace it with a new one of a different type; you might need some special code to map one object to the other, but you'd need that with your idea too. In the end, your object hierarchy will only reflect one dimension of the objects, but it's worth taking the time to figure out what the most useful dimension is (i.e., which view of the object tree will require you to do the least coding for "exceptions to the rule").

For more information, read this link thoroughly! Here's a quote that may help:

Your proposal to have separate phylogenetic and Linnean taxonomies has also been proposed by an Italian systematist, Alessandro Minelli. While I am not opposed to having separate, coexisting taxonomies, I feel that traditional taxonomies are not among those we want to keep around. In my view, traditional taxonomies should be replaced by phylogenetic taxonomies, which might then coexist with taxonomies of relevant classes. Traditional taxonomies are hybrids between phylogenetic taxonomies and taxonomies of relevant classes. Although some authors consider this a strength of the traditional taxonomies, I consider it a weakness. Consider the traditional taxon Reptilia, which consists of ectothermic amniotes. As far as I can tell, there are two "taxa" of interest here, and Reptilia is not one of them. One of them is amniotes--a group consisting not only of what are traditionally called reptiles, but also of birds and mammals. This taxon is significant because it is a clade--a phylogenetic entity consisting of an ancestor and all of its descendants. The other significant "taxon" is ectotherms, the class of organisms that rely largely on external heat sources to maintain their body temperatures. This group includes not only some amniotes (traditional reptiles), but also most non- amniotes (amphibians, fishes, etc.). There are other theoretically relevant classes: herbivores, carnivores, homeotherms, heterotherms, etc. Traditional taxonomies are highly arbitrary in recognizing a taxon Reptilia for the ectothermic amniotes, but not recognizing a taxon for the uricotelic amniotes or one for the oviparous amniotes. In theory, we could name all of these hybrid groups as taxa, but I don't know what good it would do us. In any case, this could not be done in the context of the the traditional taxonomic system, which does not permit partly overlapping taxa.

Hope that helps! :)