ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

python-day06-类和对象以及(封装、继承、多态)

python-day06-类和对象以及(封装、继承、多态) 目录一、类和对象1.1.类class1.2.对象Object二、面向对象的三大属性2.1.封装2.1.1.私有变量2.1.2.私有方法2.1.3.属性2.2.继承2.2.1.单继承2.2.2.多继承2.2.3.方法重写2.3.多态2.3.1.继承和多态一、类和对象类和对象都是面向对象中的重要概念。面向对象万事万物皆对象是一种编程思想即按照真实认知世界的思维方式构建软件系统。例如在真实世界的校园里有学生和老师学生有学号、姓名、所在班级等属性静态属性-属性还有学习、提问、吃饭和走路等动作动态属性-方法。如果我们要开发一个校园管理系统那么在构建软件系统时也会有学生和老师等”类”张同学、李同学是学生类的个体被称为“对象”“对象”也被称为“实例”。1.1.类class定义类模板class 类名[(父类)]类体注意Object类是所有类的根类可以理解为文件系统的/ 根目录或者说一个可以个性化定制的模板在python中任何一个类除object都直接或间接继承了object直接继承object时object部分的代码可以省略。类的成员类体类既然被称之为模板那么类里边能存放哪些内容呢类里边能存放的对象有成员变量实例变量、类变量、构造方法、成员方法实例方法、类方法、属性property成员变量也被称之为数据成员保存了类或对象的数据。例如学生的姓名和学号构造方法是一种特殊的函数用于初始化类的成员变量成员方法是在类中定义的函数属性是对类进行封装而提供的特殊方法后边会有所解释。注意实例变量和实例方法带着实例两者属于对象通过对象来进行调用类变量和类方法属于类通过类来调用。类成员对应列表关系类成员变量解释实例变量实例变量就是对象个体特有的“数据”例如狗狗的名称和年龄等。实例变量不会主动进行赋值通常需要搭配构造方法来进行联动使用从而给实例变量进行赋值。使用语法对象.实例变量。class Dog:# 构造方法def __init__(self,name,age,sex‘雌性’):self.name name # 创建和初始化实例变量nameself.age age # 创建和初始化实例变量ageself.sex sex # 创建和初始化实例变量sex# 打印测试print(f狗的名字叫{self.name狗的年龄是{self.age}狗的性别是{self.sex})# 调用dog Dog(旺财‘2)构造方法标识__init_()是类中的一个特殊的方法用来创建和初始化实例变量这种方法就称为“构造方法”。注意1在定义_init_()方法时它的第一个参数应该是self之后的参数用来初始化实例变量。调用构造方法时不需要传入self参数。注意2类中的self标识当前对象构造方法中的self参数说明这个方法属于实例self.age中的self表示age属于实例即实例成员变量。使用方法class dog:# 构造方法def __init__(self,name,age,sex‘雌性’):self.name name # 创建和初始化实例变量nameself.age age # 创建和初始化实例变量ageself.sex sex # 创建和初始化实例变量sex# 打印测试print(f狗的名字叫{self.name狗的年龄是{self.age}狗的性别是{self.sex})# 调用dog Dog(旺财‘2)成员/实例方法实例方法和实例变量一样都是某个实例或对象个体特有的方法。定义方法方法的第一个参数是self这会将当前实例与该方法绑定起来这也说明该方法属于实例。在调用方法时不需要传入self类似于构造方法。使用方法class dog:# 构造方法def __init__(self,name,age,sex‘雌性’):self.name name # 创建和初始化实例变量nameself.age age # 创建和初始化实例变量ageself.sex sex # 创建和初始化实例变量sex# 打印测试print(f狗的名字叫{self.name狗的年龄是{self.age}狗的性别是{self.sex})# 实例方法def run(self):print(f{self.name}在跑)# 调用对象.实例方法dog Dog(旺财‘2)dog.run()类变量类变量是属于类的变量不专属单个对象。例如有一个Account(银行账户)类它有三个成员变量:amount(账户金额)、interest_rate(利率)和owner(账户名)。amount和owner对于每一个账户都是不同的而interest_rate对于所有账户都是相同的。amount和owners是实例变量interest_rate是所有账户实例共享的变量它属于类被称为“类变量”。例如class Account:# 定义类变量interest_rate 0.1234 # 类变量利率interest_rate# 定义构造方法def __init__(self,owner,amount):self.owner owner # 创建并初始化实例变量ownerself.amount amount # 创建并初始化实例变量amount# 初始化一个对象account Acount(tony,80000)print(f“账户名{account.owner}账户金额{account.amount}”)print(f利率是{Account.interest_rate}}类方法类方法与类变量类似属于类不属于个体实例。在定义类方法时它的第一个参数不是self,而是类本身。注意类方法中可以访问其它类方法和类变量不能访问实例方法和实例变量因为他俩不在同一层级。例如class Account:# 定义类变量interest_rate 0.1234 # 类变量利率interest_rate# 定义构造方法def __init__(self,owner,amount):self.owner owner # 创建并初始化实例变量ownerself.amount amount # 创建并初始化实例变量amount# 定义类方法计算利息classmethoddef interest_by(cls,amt): # cls代表类本身即Account类可以直接将cls写为Account。return cls.interest_rate * amt # 调用类变量 * 金额也可为Account.interest_rate * amt# 初始化一个对象account Acount(tony,80000)print(f账户名{account.owner}账户金额{account.amount})print(f利率是{Account.interest_rate}})# 计算利息interest Account.interest_by(50000.0)print(f计算之后的利息为{interest})属性属性是对类进行封装而提供的特殊方法它的本质上就是两个方法在方法前加上装饰器property使得方法成为属性。属性使用起来类似于公有变量可以在赋值符()左边或右边左边被赋值右边取值。1.2.对象Object对象类模板定义好之后依据这样的模板来创建对象就称之为类的实例化所以对象也被称之为“实例”创建对象的语法对象名 调用的类构造方法例如定义一个汽车类class Car():str brandcar Car()注意python中的对象由Python垃圾回收器在后台释放对象不需要程序员手动释放对象。运行示例# 定义Account类(模板) class Account: # 定义类变量 interest_rate 0.1234 # 类变量利率interest_rate # 定义构造方法 def __init__(self,owner,amount): self.owner owner # 创建并初始化实例变量owner self.amount amount # 创建并初始化实例变量amount print(f当前类的创建的实例参数owner是{self.owner}, amount参数是{self.amount}) # 定义类方法计算利息 classmethod def interest_by(cls,amt): # cls代表类本身即Account类可以直接将cls写为Account。 return cls.interest_rate * amt # 调用类变量 * 金额也可为Account.interest_rate * amt # 以Account模板初始化2个对象 zhangsan_account Account(张三,80000) lisi_account Account(李四, 50000) print(f账户名{zhangsan_account.owner}账户金额{zhangsan_account.amount}) print(f利率是{Account.interest_rate}) # 计算利息 interest Account.interest_by(50000.0) print(f计算之后的利息为{interest})二、面向对象的三大属性2.1.封装封装性是面向对象重要的基本特性之一。封装隐藏了对象的内部细节只保留有限的对外接口外部调用者不用关心对象的内部细节使得操作对象变得简单。例如一台计算机内部极其复杂有主板、CPU、硬盘和内存等而一般人不需要了解它的内部细节。计算机制造商用机箱把计算机封装起来对外提供了一些接口如鼠标、键盘和显示器等使用计算机就变得非常简单。2.1.1.私有变量在默认的情况下python中的变量是公有的可以在类的外部访问进行访问也就是类名.变量名。为了防止外部调用者随意存取类的内部数据成员变量内部数据成员变量就会考虑封装为“私有变量”。外部调用者只能通过方法来调用私有变量。语法__变量名。也就是在变量前加入两段下划线__未封装前# 定义Account类(模板) class Account: # 定义类变量 interest_rate 0.1234 # 类变量利率interest_rate # 定义构造方法 def __init__(self,owner,amount): self.owner owner # 创建并初始化实例变量owner self.amount amount # 创建并初始化实例变量amount print(f当前类的创建的实例参数owner是{self.owner}, amount参数是{self.amount}) # 定义类方法计算利息 classmethod def interest_by(cls,amt): # cls代表类本身即Account类可以直接将cls写为Account。 return cls.interest_rate * amt # 调用类变量 * 金额也可为Account.interest_rate * amt print(fAccount类的类变量为{Account.interest_rate})封装后# 定义Account类(模板) class Account: # 定义类变量 __interest_rate 0.1234 # 类变量利率interest_rate # 定义构造方法 def __init__(self,owner,amount): self.owner owner # 创建并初始化实例变量owner self.amount amount # 创建并初始化实例变量amount print(f当前类的创建的实例参数owner是{self.owner}, amount参数是{self.amount}) # 定义类方法计算利息 classmethod def interest_by(cls,amt): # cls代表类本身即Account类可以直接将cls写为Account。 return cls.interest_rate * amt # 调用类变量 * 金额也可为Account.interest_rate * amt print(fAccount类的类变量为{Account.interest_rate})结果提示目标类对象里边找不到我们需要的属性也就是__interest_rate变量已经不对外公开了注意私有变量只能在类这个范围中进行使用同级范围并且在同级使用的过程中也需要带着双下划线__2.1.2.私有方法私有方法和私有变量的封装是类似的在方法前面加上双下划线__就是私有方法了。私有方法不能在类的外边进行使用。只能在类的内部进行使用。class Account: # 定义类变量 __interest_rate 0.1234 # 类变量利率interest_rate # 定义构造方法 def __init__(self,owner,amount): self.owner owner # 创建并初始化实例变量owner self.__amount amount # 创建并初始化实例变量amount # 定义一个实例方法 def Account_info(self): print(f账户归属为{self.owner}) self.__get_account_info() # 定义一个私有方法 def __get_account_info(self): print(f账户余额为{self.__amount}) # 定义类方法计算利息 classmethod def interest_by(cls,amt): # cls代表类本身即Account类可以直接将cls写为Account。 return cls.__interest_rate * amt # 调用类变量 * 金额也可为Account.interest_rate * amt # 以Account模板初始化1个对象 lisi_account Account(李四, 50000) # print(f账户名{lisi_account.owner}账户金额{lisi_account.__amount}) # 不允许类外部的对象访问私有变量 lisi_account.Account_info() # 计算利息 interest Account.interest_by(50000.0) print(f计算之后的利息为{interest})2.1.3.属性为了实现对象的封装在一个类中不应该有公有的成员变量这些成员变量应该被设计为私有的然后通过公有的set(赋值)和get(取值)方法访问。使用set和get方法进行封装示例代码如下class Account: # 定义类变量 interest_rate 0.1234 # 类变量利率interest_rate # 定义构造方法 def __init__(self,owner,amount): self._owner owner # 创建并初始化实例变量owner self._amount amount # 创建并初始化实例变量amount # get取值 property def owner(self): return self._owner owner.setter def owner(self,owner): self._owner owner # 定义类方法计算利息 classmethod def interest_by(cls,amt): # cls代表类本身即Account类可以直接将cls写为Account。 return cls._interest_rate * amt # 调用类变量 * 金额也可为Account.interest_rate * amt # 以Account模板初始化1个对象 lisi Account(李四, 2000) print(lisi.owner) lisi.owner 张三 print(lisi.owner) print(lisi._amount) print(Account.interest_rate)2.2.继承继承性也是面向对象重要的基本特性之一。在现实世界中继承关系无处不在。例如猫与动物之间的关系猫是一种特殊动物具有动物的全部特征和行为即外貌特征数据和行为动作。在面向对象中动物是一般类被称为“父类猫是特殊类被称为“子类”。特殊类拥有一般类的全部数据和操作可称之为子类继承父类。2.2.1.单继承在python中声明子类继承父类语法比较简单前面在类的定义中就已经进行说明也就是只需要定义类时在类的后边使用一对小括号指定它的父类就可以了。eg:class Animal: def __init__(self, name): self.animal_name name def show_info(self): return 动物的名字{0}.format(self.animal_name) def move(self): print(猎食......) class Cat(Animal): def __init__(self, name, age): super().__init__(name) self.age age cat Cat(Tom,2) cat.move() print(cat.show_info())注意继承只继承类里公有的成员变量和方法。2.2.2.多继承从面向对象的继承性理论上讲一个子类可以有多个父类。但是如果在多个父类中有相同的方法那么子类应该继承哪一个父类方法?这样会发生冲突。所以很多计算机语言都不支持多继承而Python支持!在Python中当子类继承多个父类时如果在多个父类中有相同的成员方法或成员变量则子类优先继承左边父类中的成员方法或成员变量从左到右继承级别从高到低。示例代码如下:class Horse: def __init__(self,name): self.name name def show_info(self): return 马的名字{0}.format(self.name) def run(self): print(马跑....) class Donkey: def __init__(self,name): self.name name def show_info(self): return 驴的名字{0}.format(self.name) def run(self): print(驴跑....) def roll(self): print(驴打滚) class Multiple(Horse, Donkey): def __init__(self,name,age): super().__init__(name) self.age age m Multiple(杂交品种驴,1) m.run() m.roll() print(m.show_info())2.2.3.方法重写如果子类的方法与父类的方法名相同则在这种情况下子类的方法会重写Override父类的同名方法。class Animal: def __init__(self, name): self.animal_name name def show_info(self): return 动物的名字{0}.format(self.animal_name) def move(self): print(动物是怎么猎食的......) class Cat(Animal): def __init__(self, name, age): super().__init__(name) self.age age def move(self): print(猫在猎食的过程中状态很敏锐) cat Cat(Tom,2) cat.move() print(cat.show_info())2.3.多态多态性也是面向对象重要的基本特性之一。“多态”指对象可以表现出多种形态。例如猫、狗、鸭子都属于动物它们有“叫”和“动”等行为但是叫的方式不同动的方式也不同。2.3.1.继承和多态在多个子类继承父类并重写父类方法后这些子类所创建的对象之间就是多态的。这些对象采用不同的方式实现父类方法。示例1代码如下:class Animal: def speak(self): print(动物叫但不知道是哪种动物叫!) class Dog(Animal): def speak(self): print(小狗:旺旺叫...) class Cat(Animal): def speak(self): print(小猫:喵喵叫...) an1 Dog() an2 Cat() an1.speak() an2.speak()示例2代码如下class Animal: def speak(self): pass class Dog(Animal): def speak(self): # --- 这里就是【方法重写】改变了内部逻辑 return 汪汪 class Cat(Animal): def speak(self): # --- 这里也是【方法重写】 return 喵喵 # ------------------ 下面展示【多态】 ------------------ def make_sound(animal: Animal): print(animal.speak()) # --- 这里就是【多态】现象同一个调用不同结果 make_sound(Dog()) # 输出汪汪 make_sound(Cat()) # 输出喵喵
返回列表