Star Trek Spaceships in a Wormhole

How Do They Build The Starships in Star Trek? Classes and Objects in Python

With so many new Star Trek series coming out at the moment and in the near future, new and old Trekkies are all asking the same question: How do they build the starships in the Star Trek universe? Or maybe it’s just me? This article will boldly go on a journey through classes and objects in Python to give you an answer.

This article’s objective is to offer an analogy to help understand classes and objects in Python. Needless to say, I’m using plenty of poetic license and the historical facts (from the Star Trek Universe perspective) described here most certainly do not belong to the Star Trek canon. Federation lawyers need not sue me.

The Laws of Physics and Python Built-Ins

The story starts with the laws of Physics, or their modified versions in the Star Trek universe, of course, which are not quite the same as those you and I have studied! These are the basic building blocks to build a starship that can travel at warp speed (if you’re not a Star Trek fan, just read that as ‘very fast speed’) and do all the other things starships do.

The equivalent concept in coding includes Python’s fundamental tools such as the built-in keywords, functions, and data types. You need to use these fundamental building blocks for any project you write in Python in the same way that the you need to use the laws of Physics as building blocks for building a starship.

OK, so we’re ready to start building the first starship.

Building The First Starship

The scientists and engineers in Starfleet* worked tirelessly to build the first starship, going through many iterations and many failures. That’s how science works even in the Star Trek universe, I assume. During this process, nothing was final. Everything the scientists did was experimental. Some things worked and were kept; other things didn’t, and weren’t.

In coding, the early stages of a project often involve exploratory coding where the focus is not to make the code perfect but to see what works and what doesn’t work.

And then, the first starship was built and successfully launched to start exploring the Alpha Quadrant.

* Possibly, Starfleet didn’t exist yet at this time. Or maybe Starfleet existed but not the Federation? I’m not sure, I should probably go and do some research but it’s not relevant for this narrative, so I’ll move on and be prepared for the ire of die hard Trekkies if I got my facts wrong!

Building Many Starships

But now, Starfleet needed to build many starships. They needed a blueprint based on the knowledge the scientists and engineers gained from building the first starship. This blueprint will enable Starfleet to build many idenitcal starships.

In the object-oriented programming world of Python coding, this blueprint to create many starships is a class. Each starship that’s built using the class (blueprint) is an object, or an instance of the class.

Let’s look at how the Python code to create a Starship class might look like:

class Starship():
    def __init__(self, name, registration):
        self.name = name
        self.registration = registration
        self.max_warp_speed = 4
        self.n_decks = 7

When you define a class, you’re not creating any objects. Not yet anyway. Writing a class definition is the equivalent of creating the blueprint for building starships. There’s no starship yet, only a blueprint.

The __init__() method defines what needs to be done when a new object is created using this class. In this case, I’m assigning some attributes to the new starship. Two of these attributes, .name and .registration, are required as arguments when the object is created. The remaining attributes have default values.

Now you have a blueprint to create a starship, you can create as many as you wish:

class Starship():
    def __init__(self, name, registration):
        self.name = name
        self.registration = registration
        self.max_warp_speed = 4
        self.n_decks = 7

enterprise_nx01 = Starship("Enterprise", "NX-01")
enterprise_d = Starship("USS Enterprise", "NCC-1701-D")
voyager = Starship("USS Voyager", "NCC-74656")

You create three instances of the class Starship(). You’re using the same blueprint but create three separate starships with different names and registrations. Later on, you’ll see how you can make more changes to your starships, too.

In the class definition, which is the blueprint to build starships, you still don’t have a label with which you can refer to the object, since the object doesn’t exist yet. This is why self is used. You can think of self as a placeholder for the label you’ll use later on to refer to the object once you’ve created it. In the examples in the code above, once you create the three starships, you assign them to the variable names enterprise_nx01, enterprise_d, and voyager.

Adding Functionality To The Starships

Starships have names and registration numbers and other data attributes that describe the ship. However, starships also have functionality. They can fly and fire phasers, for example. The blueprint for creating starships needs to include these functions.

In a class definition, these are the methods you can define within the class:

class Starship():
    def __init__(self, name, registration):
        self.name = name
        self.registration = registration
        self.max_warp_speed = 4
        self.n_decks = 7

    def fly_impulse(self, impulse_speed):
        """Add code here"""
        ...

    def fly_warp(self, warp_speed):
        """Add code here"""
        ...

    def fire_phaser(self, power):
        """Add code here"""
        ...

enterprise_nx01 = Starship("Enterprise", "NX-01")
enterprise_d = Starship("USS Enterprise", "NCC-1701-D")
voyager = Starship("USS Voyager", "NCC-74656")

voyager.fly_warp(8)

The methods give functionality to the objects created using the class. Once you define these methods, you can use them on any object created from the class. The examples above don’t have any code in them, but in a real class, each method will include code as its definition.

Creating Different Types of Starships

As Starfleet grew and starship building improved, the need for different types of starships arose. Some starships needed to be small and nimble, others were heavily armed, and so on.

Each type of ship needed its own blueprint. (In Star Trek, the term class refers to the different types of ships but I’ll avoid the Star Trek use of the term class to avoid confusion)

However, it’s not efficient to create a brand new blueprint for each ship since many features of starships will be the same, whatever the type of ship.

The solution is inheritance. You can define a Python class based on another class. The subclass will inherit the attributes of the parent class but can have new attributes, too. You can override inherited attributes, if needed:

class Starship():
    def __init__(self, name, registration):
        self.name = name
        self.registration = registration
        self.max_warp_speed = 4
        self.n_decks = 7

    def fly_impulse(self, impulse_speed):
        """Add code here"""
        ...

    def fly_warp(self, warp_speed):
        """Add code here"""
        ...

    def fire_phaser(self, power):
        """Add code here"""
        ...

class Galaxy(Starship):
    def __init__(self, name, registration):
        super().__init__(name, registration)
        self.max_warp_speed = 9.6
        self.n_decks = 42

    def separate_saucer_section(self):
        """Add code here"""
        ...

class Intrepid(Starship):
    def __init__(self, name, registration):
        super().__init__(name, registration)
        self.max_warp_speed = 9.975
        self.n_decks = 15

    def activate_emergency_medical_hologram(self):
        """Add code here"""
        ...

enterprise_nx01 = Starship("Enterprise", "NX-01")
enterprise_d = Galaxy("USS Enterprise", "NCC-1701-D")
voyager = Intrepid("USS Voyager", "NCC-74656")

enterprise_d.separate_saucer_section()
voyager.activate_emergency_medical_hologram()

enterprise_d.fly_warp(8)
voyager.fly_warp(8)

The Galaxy subclass of starships inherits all the attributes of the Starship class. However, some data attributes have a different default value. This subclass also has a new method which is a feature that this type of starship had that others did not.

You also define another subclass for the Intrepid type of starship. One feature that was new in this type of ship was the presence of an emergency medical hologram and therefore there’s a method for this in this subclass which is not in other types of ship.

Therefore, you can call enterprise_d.separate_saucer_section() since enterprise_d is an instance of the Galaxy class and you can call voyager.activate_emergency_medical_hologram() as voyager is of the Intrepid class. However, you cannot call enterprise_d.activate_emergency_medical_hologram() and you cannot call voyager.separate_saucer_section() either. Both of these calls will raise an AttributeError.

Both subclasses still have the method .fly_warp() which they inherited from the parent class Starship.

Final Words

And so, you now know how they built starships in Star Trek (or maybe not), and you hopefully have a better picture of what classes and objects in Python are.

Now, here’s the real question. Do you think they still use(d) Python in the 24th century of the Star Trek universe and that they used it to design and build starships? I wonder… (I know, Star Trek first came out in the 1960s, so that probably answers the question. Maybe everything is in Fortran, after all!)

Further Reading

2 thoughts on “How Do They Build The Starships in Star Trek? Classes and Objects in Python”

Leave a Reply