Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Which strategy follow to create class?

Tags:

python

class

I am trying to learn how classes work. I would like to create different classes with some shared elements and others not, but as far as I know I can create it from three different ways:

  • Create a class with all the shared elements and then inherit this class and modify specific methods and attributes in the new class. Something like that:

     class Enemy(object):  
         """Enemy!"""  
        def __init__(self, damage=30, life=100, enemy="Hero"):  
        #And keep defining the class and its methods and attributes in common with all the enemys
    
     class Troll(Enemy):  
         """Troll!"""
         def __init__ (self, defense=0):  
         #And define the specific attributes and methods for Trolls.
    
  • Create a class and ask for a type of class, and change the definition of the object from which input it got. Something like that:

    class Enemy(object):  
         """Enemy!"""  
         def __init__(self, damage=30, defense=0, life=100, type="Troll" enemy="Hero"):  
             if type=="Troll":  
                #Do that for type "Troll"  
             if type=="Goblin":  
                #Do that for type  "Goblin"  
             #And keep defining the class and its methods and attributes for each accepted type
    
  • Create two different classes and then do multiple inheritance:

    class Enemy(object):  
        """Enemy!"""  
        def __init__(self, damage=30, life=100, enemy="Hero"):  
            #And keep defining the class and its methods and attributes in common with all the enemys
    
    class Trolls(object):  
         """Trolls!"""
         def __init__ (self, defense=1, shield=20):  
             #And define the specific attributes and methods for Trolls.  
    
    class SuperTroll(Enemy, Trolls):
    

I see the first one is the easy one that let me be more flexible to create multiple classes with shared methods and attributes. But the second one seems to me more easy to use(or at least I like it), and I can get out of the if conditionals whatever I want. And the third one could be practical for mixing different classes without any shared method or attribute, and if they share it wouldn't mess it (or it would?).

Which one is better?
But about writing in one or the other way it seems it is just a matter of strategy about how do you want your code. Is this correct?

like image 784
llrs Avatar asked Jan 06 '14 15:01

llrs


2 Answers

The second example is not a good idea; it will lead to a lot of duplicated code, and you have to edit your Enemy class every time you come up with a new type of enemy character.

Picking between the first and third is trickier, and will depend on what you want to achieve ("a matter of strategy", as you have it).

The first, single inheritance from Enemy for Troll and Goblin, is useful because it allows you to define all the code that all Enemy characters will have once, and only define the differences in the Troll and Goblin classes. You could extend this further, and have Enemy inherit from a superclass (or metaclass) Character, that provides the really basic stuff for both Enemy and Hero classes (e.g. name, health, ...).

class Enemy(Character)

class Troll(Enemy)

The third example may be useful if you want to separate characters and roles, e.g. you could have

class FriendlyTroll(Troll, Friend)

and

class UnfriendlyTroll(Troll, Enemy)

if those roles are going to mean different instance attributes (e.g. the Friend mix-in might introduce a share method). This allows for more complexity in your character definitions, but if you are not going to use the extra functionality it is a lot of complication to get your head around, and may lead to intractable multiple-inheritance problems.

TL;DR: Use the first one! If you decide later that you really need to separate out roles into mix-in classes, that isn't too complex a task.

like image 183
jonrsharpe Avatar answered Oct 02 '22 20:10

jonrsharpe


First one:

Proper way to go...You are inheriting from what is collectively "ENEMY". Here you can have common things that "ENEMY" has under the class and have individual classes for all types of enemy and also you can well override some of the methods that makes some kind of "ENEMY" distinct.

Second one:

Not nice or properly object oriented because what if "trolls" have some property that is not shared by other "enemy". You might say that it can go under "if" statement you have but this makes the code very-less manageable which is why you use OOP ( to manage the code, it's not all but one of the reason).

Third one:

I strongly suggest not using multiple-inheritance as far as possible. Google diamond death problem and you will know why. One rule for multiple-inheritence--"If you think you need multiple inheritance, you are probably wrong. If you know you have to use multiple inheritance, you are probably right."

like image 33
Jack_of_All_Trades Avatar answered Oct 02 '22 19:10

Jack_of_All_Trades