#5 Python进阶教学2

类别

  • 类别里封装了变数和函数
  • 被封装在类别里的变数称为属性
  • 被封装在类别里的函数称为方法(方式、功能)
  • 先定义类别,才能使用类别中封装起来的变数和函数
  • 具有封装、继承、多型特性

类别就是自订的资料型态先定义类别,才能使用类别中封装起来的变数和函数

# 定义类别
class 类别名称():
    变数a
    变数b
    
# 使用类别
# 建立物件,把类别的结构放到变数里,变成物件
变数1 = 类别名称()
变数2 = 类别名称()

# 操作物件里的内容
变数1.变数a = 数值X
变数2.变数a = 数值Y
print(变数1.变数a)

程序码

# 定义类别
class Car():
    color = ""
    brand = ""
    
# 使用类别
if __name__ == "__main__":
    # 建立物件,把类别放到变数里,变成物件
    porsche = Car()
    benz = Car()
    # 操作物件里面的内容(属性)
    porsche.color = "白"
    porsche.brand = "保时捷"
    benz.color = "黑"
    benz.brand = "宾士"
    print(porsche.color, porsche.brand)
    # 印出 白 保时捷
    print(benz.color, benz.brand)
    # 印出 黑 宾士

初始化副程序,俗称建构子,初始化副程序的名称一律为__init__,如果副程序会程序会使用该类别内的其他变数或副程序,那麽在宣告副程序时,就必须在参数内加入一个self参数,副程序就可以使用self参数操作到同个类别内其他的变数或副程序,用法如下

# 定义类别
class 类别名称():
    变数a
    变数b
    
    def __init__(self, 参数...):
        初始化副程序区块...
    
    def 副程序a(self, 参数...):
        副程序区块...
        return 传回值
    
# 使用类别
# 建立物件,把类别放到变数里,变成物件(使用时不用加self)
变数1 = 类别名称(参数...)
变数2 = 类别名称(参数...)

# 操作物件里的内容
变数1.变数a = 数值X
变数2.变数a = 数值Y
print(变数1.变数a)

print(变数2.副程序a(参数...))

程序码示范

# 定义类别
class Car():
    color = ""
    brand = ""
    # 定义初始化副程序
    def __init__(self, c, b):
        self.color = c
        self.brand = b
        print("新车建构完成,"+self.milage(0))

    def milage(self, km):
        return "里程数为"+str(km)+"公里"

# 使用类别
if __name__ == "__main__":
    # 建立物件,把类别放到变数里,变成物件,并执行初始化副程序(加入初始值时不用加self)
    porsche = Car("白", "保时捷")  
    # 印出 新车建构完成,里程数为0公里    
    print(porsche.milage(1000))
    # 印出 里程数为1000公里   

物件导向程序设计有三大特性:

  • 继承
  • 封装
  • 多形

继承

继承就是以一个既有的类别,对那个类别进行扩充,变成一个新的类别,这个就叫继承,原有的类别称为父类别,以父类别为基础做扩充跟改写而成的新类别称为子类别, 在扩充父类别时如果定义新的变数或是副程序,名称跟原本父类别一样的话,将以子类别的为主,这时候就会产生一个问题,若新增在子类别的变数需要再初始化函数时做操作,该怎麽办呢?如果直接写一个新的__init__初始化副程序,就会取代掉原本父类别的初始化副程序了,当然可以直接重写__init__初始化副程序,可是当父类别太庞大时就会很麻烦,因有我们有个方便的解决方法,那就是supersuper可以直接将父类别的初始化副程序保留下来,让我们可以以这为基础进行初始化副程序的改写,这种方式不但继承了类别的结构,连初始化的方式也一并继承下来,可谓真正的物件导向继承的特色阿,以下直接以程序码示范

# 定义类别,此类别在本范例中当成父类别
class 类别名称A:
    变数A(属性)
    
    def __init__(self, 参数1, 参数...):
        初始化副程序区块...
        
    def 副程序A(self, 参数...):
        副程序(方法)区块...
        
# 定义类别,此类别为子类别,以上面的类别最为父类别来继承,以上面类别为基础做扩充改写
class 类别名称B(类别名称A):
    # 新增一个属性,变数B
    变数B(属性)
    
    #定义初始化副程序,将使用super(),继承父类别的初始化副程序
    def __init__(self, 父类别原有的参数..., 子类别新增的参数...):
        # super()可以直接将父类别的初始化副程序保留下来
        # 下面这行可以视为保留父类别原有的初始化副程序程序区块
        super(类别名称B, self).__init__(父类别原有的参数...)
        # 以下是继承後新增的程序码
        新增的初始化副程序区块...
    
    # 新增一个方法,副程序B
    def 副程序B(self, 参数...):
        副程序(方法)区块...

范例

# 定义类别,此类别在本范例中当成父类别
class Car():
    color = ""
    brand = ""

    def __init__(self, c, b):
        self.color = c
        self.brand = b
        print("新车建构完成,"+self.milage(0))

    def milage(self, km):
        return "里程数为"+str(km)+"公里"

# 定义类别,此类别为子类别,以上面的类别最为父类别来继承,以上面类别为基础做扩充改写
class Taxi(Car):
    # 新增一个属性,司机 driver
    driver = ""
    
    #定义初始化副程序,将使用super(),继承父类别的初始化副程序
    def __init__(self, c, b, d):
        # super()可以直接将父类别的初始化副程序保留下来
        # 下面这行可以视为保留父类别原有的初始化副程序程序区块
        super(Taxi, self).__init__(c, b)
        # 以下是继承後新增的程序码
        self.driver = d

    # 新增一个方法,传回牌照种类,副程序licensePlate
    def licensePlate(self):
        return "营业用牌照"

if __name__ == "__main__":
    uber = Taxi("白", "保时捷", "韩总鸡")  
    # 印出 新车建构完成,里程数为0公里
    print(uber.milage(1000))
    # 印出 里程数为1000公里
    print(uber.driver)
    # 印出 韩总鸡
    print(uber.licensePlate())
    # 印出 营业用牌照

封装

简单来说,你不需要知道类别里面是如何设计的,你只要会使用就好,就像一台手机,内部零件五花八门,但你不需要懂零件,只要会用就好,零件都被封装起来一般,类别里不想要被存取变数和副程序,就是需要被封装起来的成员,称为私有成员,作法很简单,只要在变数或副程序的名称前加上__,该变数或副程序就会被封装起来了,尔後在操作时,只要试图存取被封装的私有成员,都是不允许的,范例如下

class 类别名称:
    变数A(属性)
    #定义私有成员变数B
    __变数B(属性)
    
    def 副程序A(self, 参数...):
        副程序(方法)区块...
    #定义私有成员副程序B   
    def __副程序B(self, 参数...):
        副程序(方法)区块...

程序码 圆面积计算器

class Area():
    r = 0
    # 定义私有成员__pi
    __pi = 3.14

    def __init__(self, r):
        self.r = r
        print("面积为" + str(self.__area()))
        
    # 定义私有成员__area()
    def __area(self):
        return self.r ** 2 * self.__pi


if __name__ == "__main__":
    o = Area(6)  
    #印出 面积为113.04
    print(o.r)
    #印出  6
    print(o.__pi)
    #私有成员,无法存取所以会报错 

多形

意思就是呼叫同样名称的方法时,会得到不同的结果,python会根据呼叫的类别来决定要执行哪个副程序,这就是多型

class Thor():
    def cast(self):
        print("Chris Hemsworth")

class CaptainAmerica():
    def cast(self):
        print("Chris Evans")

class StarLord():
    def cast(self):
        print("Chris Pratt")

if __name__ == "__main__":
    Chris1 = Thor()
    Chris2 = CaptainAmerica()
    Chris3 = StarLord()
    Chris1.cast()
    #印出 Chris Hemsworth
    Chris2.cast()
    #印出 Chris Evans
    Chris3.cast()
    #印出 Chris Pratt

<<:  JWT实作(一)(Day5)

>>:  冒险村05 - Release Drafter

MyBatis 设定

MyBatis设定 ...

[Day 12]从零开始学习 JS 的连续-30 Days---DOM是什麽?

DOM是什麽? DOM 的英文全名是 Document Object Model,中文是「文件物件模...

DAY27-this总结

总结来说this就像是没什麽太大的意义对於function而言,因为不管function的this他...

IT铁人DAY 23-Command 命令模式

  今天要学习的是Command Pattern,我个人觉得它的实用性蛮高的,也觉得它很好理解,如果...

身为与会者,控场的重要性

会议中的每个人都是可以掌控会议的节奏,因为谁也不知道控场的人哪一天也自己不受控制。因应疫情,所以先从...