# student.py # a "class" is a data type (pre-compile time definition ONLY) # a class is made up of attributes (state) and functions (behavior) # an "object" is a run-time instance of a "class" # OOP is optional in Python (unlike Java) # OOP: inheritance, composition, polymorphism # operator overloading # specialization/generalization (customization via inheritance) class Student: def __init__( self, name, major='EXPL', gpa=4.0 ): self.name = name self.major = major self.gpa = gpa self.someotherattribute = 123 # self is the newly constructed instance object def lastName( self ): return self.name.split()[-1] def __str__( self ): # Java toString() #return 'Student: %s, %s (GPA %.2f)' % ( self.name, self.major, self.gpa ) return 'Student: %s, %s (GPA %.2f)' % ( self.lastName(), self.major, self.gpa ) class GraduateStudent( Student ): # subclass of Student # purpose of subclassing here is for specialization # -- inherits everything from the Student class # modify below by overriding behavior/functions..... def lastName( self ): return 'The ' + Student.lastName( self ) def writeThesis( self ): print( 'okay. all done.' ) # if we run this code, then __name__ == '__main__' # if we import student, then __name__ == 'student' if __name__ == '__main__': s1 = Student( 'David Goldschmidt', major='CSCI' ) s3 = Student( 'Lindsay Lohan', gpa=0.6 ) print( s1.name, s1.major, s1.gpa ) s1.major = 'ENGL' print( s1.lastName() ) # lastName( s1 ) s2 = GraduateStudent( 'Kim Kardashian', '????', 1.2 ) print( s2.name, s2.major, s2.gpa ) print( s2.lastName() ) # use the most specific version of this function print( s2 ) # invokes the __str__() function print( s1 ) L = [ s1, s2, s3, 5 ] for object in L: print( object )