Python学习五:面向对象设计程序

时间:2022-10-31 12:56:08


文章目录

  • ​​一、引言​​
  • ​​二、对象​​
  • ​​定义​​
  • ​​三、类​​
  • ​​定义​​
  • ​​四、面向对象程序的设计特点​​
  • ​​三大基本特点:封装、继承、多态​​
  • ​​1.封装​​
  • ​​2.继承​​
  • ​​3.多态​​
  • ​​五、类的定义和使用​​
  • ​​5.1定义类​​
  • ​​5.2 创建类的实例​​
  • ​​5.3 创建__init__()方法​​
  • ​​5.4 创建类的成员并且访问​​
  • ​​5.5 创建数据成员并且访问​​
  • ​​5.6 访问限制​​
  • ​​1. _foo 单下划线命名的方法或者属性表示protected​​
  • ​​2. __foo 双下划线命名的方法或者属性表示private​​
  • ​​3. `__foo__` 双下划线命名的方法或者属性表示特殊意义比如__init__()​​
  • ​​5.7 属性​​
  • ​​5.7.1 定义​​
  • ​​5.7.2 创建用于计算的属性​​
  • ​​语法​​
  • ​​改属性值​​
  • ​​5.8 继承实现​​
  • ​​5.8.1 语法​​
  • ​​5.8.2 方法重写​​
  • ​​5.8.3 派生类调用基类的__init__()方法​​

一、引言

面向对象是一种设计思想,其中对象是客观世界中存在的对象,这个对象具有唯一性,每个对象都有字的运动规律和内部状态,对象与对象之间又是可以互相联系互相作用的。

对象----> 属性(可选)+行为(可选)

二、对象

定义

通常将对象划分为两个部分,即静态部分和动态部;静态部分被称为“属性”,动态部分(行为)。

比如小明这个人就可以称之为一个对象,小明的年龄,性别就可以称之为“属性”,小明正在跑步 这个动态部分称之为“行为”。
​​​在Python中,一切都是对象,即不仅是具体的事物称之为对象,字符串,函数等也可以称之为对象。这已说明了Python天生就是面向对象的​

三、类

定义

类是封装对象的属性和行为的载体,具有相同的属性和行为的一类实体称之为类。

比如说小明和小红都是人类 ,我们可以抽象一个类叫人类,这个类具有属性和行为 ,而小明和小红就是这个类实例化的结果称之为对象。

四、面向对象程序的设计特点

三大基本特点:封装、继承、多态

1.封装

封装是面向对象的核心思想,就是将对象性的属性和行为封装起来,而将对象的属性和行为封装起来的载体就是类,类通常对客户隐藏其实现细节,这就是封装的思想。

2.继承

打个比方;我现在有个类,这个类命名为A
这个类具有属性:年龄,性别;行为:走路

打个比方;我现在有个类,这个类命名为B
这个类具有属性:年龄,性别 ,​​​国籍​​​;行为:走路,​​吃饭​

此时A类有的属性和行为B类也有,为了不让B类重复写这些属性和行为,就可以让B类继承A就可以,这样就可以得到A的属性和行为

3.多态

将父类对象应用于子类的特征就是多态;

五、类的定义和使用

5.1定义类

类的定义中用关键词class来实现

class ClassName:
'''类的说明信息'''
statement #类体

ClassName:类名 首字母大写
statement:类体主要由类变量、方法、属性等定义语句组成,如果没有想好类里面有什么内容,也可以用 pass语句代替

eg:

class Geese:
'''动物'''
pass

5.2 创建类的实例

定义完类之后,不会创建一个实例。
创建实例语句

ClassName(paramterlist)
  1. ClassNam:是必选参数
  2. paramterlist:是可选参数:如果创建一个类时,没有创建__init__()方法,或者__init__()方法只有self参数时候,可以省略paramterlist

eg:

wildGoose =Geese()# 这时候我们就通过Geese类创建了一个叫wildGoose实例

5.3 创建__init__()方法

在创建类之后,通常会创建一个__init__()方法,用于初始化实例的属性或者调用方法;在每次实用类创建对象的时候,会自动调用__init__()方法,init()方法必须包含一个​​self​​​参数,​​并且位置是第一个​​​。self是指向本身的一个应用,用于访问类中的方法和属性。
eg

class Geese:
'''动物'''
def __init__(self):
print("成功创建一个类")




wildGoose =Geese();

>>>成功创建一个类

eg2

class Geese:
'''动物'''
def __init__(self,date):
print("成功创建一个类")
print(data)




wildGoose =Geese("欧力给");

>>>成功创建一个类
>欧力给

5.4 创建类的成员并且访问

eg2

class Geese:
'''动物'''
def __init__(self,date):
print("成功创建一个类")
print(data)

def fiy(self,state):
print(state)


wildGoose =Geese("欧力给");
wildGoose.fiy("调用函数")

>>>成功创建一个类
>欧力给
>调用函数

5.5 创建数据成员并且访问

​数据成员​​​是指在类中的定义的变量,即:属性;根据定义的位置可以分为​​类属性​​​和​​实例属性​

  1. 类属性

类属性是指定义在类中,并且在函数体外的属性。类属性可以在类的所有实例之间共享值,也就是在所有实例化的对象中公用。

class Geese:
'''动物'''
nack="脖子"
def __init__(self):
print("实例化类")
def fiy(self,state):
print(state)


wildGoose1 =Geese();
wildGoose2 =Geese();
print(wildGoose1.nack)
print(wildGoose2.nack)

Geese.abc="额外定义"

print(wildGoose1.abc)
print(wildGoose2.abc)

>>>
>
>实例化类
>实例化类
>脖子
>脖子
>额外定义
>额外定义
  1. 实例属性

实例属性是指定义在类中的方法的属性,只用作于当前的实例当中

class Geese:
'''动物'''

def __init__(self):
print("实例化类")
self.nack="脖子"
def fiy(self,state):
print(state)

wildGoose1.nack="改变脖子"
wildGoose1 =Geese();
wildGoose2 =Geese();
print(wildGoose1.nack)
print(wildGoose2.nack)


>>>
>
>实例化类
>实例化类
>改变脖子
>脖子

5.6 访问限制

1. _foo 单下划线命名的方法或者属性表示protected

​保护的可以通过实例名访问​​ eg:

class Swan:
_neck_swan='天鹅的脖子很长'
def __init__(self):
print("__init__():",Swan._neck_swan)
swan=Swan();
print("直接访问:",swan._neck_swan)

》》》 __init__():天鹅的脖子很长
》》》直接访问:天鹅的脖子很长

2. __foo 双下划线命名的方法或者属性表示private

​私有属性可以在类的实例方法中访问,也可以通过“实例名.类名__XXX”方法访问,但是不能直接通过实例名+属性名访问​

class Swan:
__neck_swan='天鹅的脖子很长'
def __init__(self):
print("__init__():",Swan.__neck_swan)
swan=Swan();
print("加入类名:",swan.Swan__neck_swan)
print("直接访问:",swan.__neck_swan)

》》》 __init__():天鹅的脖子很长
》》》加入类名:天鹅的脖子很长
》》》报错:因为私有属性不能通过实例名访问

3. ​​__foo__​​ 双下划线命名的方法或者属性表示特殊意义比如__init__()

5.7 属性

5.7.1 定义

这里的属性和上面介绍的属性是不一样的,这里的属性​​在访问的时候进行计算​​​,另外​​该属性还可以添加安全保护机制​

5.7.2 创建用于计算的属性

在python中,可以通过@property(装饰器)将一个方法转换为属性

语法

@property
def methodname(self):
bolck
  1. methodname 用于指定方法名,一般用小写字母开头。
  2. self 必要参数
  3. bolck 方法体
class Rect:
def __init__(self,width,height):
self.width=width
self.height=height
@property
def area(self):
return self.width*self.height

rect =Rect(800,600)
print(rect.area)

>>> 480000

改属性值

当属性值设为私有的时候,正常以上方法是不可以,更改属性值的,属性值只能为已读。
想更改属性值方法
​​​使用另外一个函数,并且该函数使用@属性函数名.setter(装饰器)​

class Rect:
def __init__(self,width,height):
self.width=width
self.height=height
self.__num=width*height
@property
def area(self,):
return self.__num
@area.setter
def alt(self,num):
self.__num=num


rect =Rect(800,600)
print(rect.area)
rect.alt=88
print(rect.area)
>>> 480000
>>> 88

5.8 继承实现

5.8.1 语法

class ClassName(baseclasslist):
'''类的帮助信息'''
Statement #类体
  1. ClassName 类名
  2. baseclasslist 用于指定要继承的基类,可以有多个,用逗号隔开,如果不指定,将使用所有Python对象的根类object
class Fruit:
color = "绿色"
def harvest(self,color):
print("水果是"+color+"的!")
print("水果已经收获")
print("水果原来是"+Fruit.color+"的!")
class Apple(Fruit):
color = "红色"
def __init__(self):
print("我是苹果")
class Orange(Fruit):
color = "橙色"
def __init__(self):
print("\n我是橘子")

if __name__ == '__main__':
apple = Apple()
apple.harvest(apple.color)

orange = Orange()
orange.harvest(orange.color)

>>>
我是苹果
水果是红色的!
水果已经收获
水果原来是绿色的!

我是橘子
水果是橙色的!
水果已经收获
水果原来是绿色的!

5.8.2 方法重写

就是派生类把基类的方法重新写,参数和方法名要相同(这一点和java的重写是一样的)

class Fruit:
color = "绿色"
def harvest(self,color):
print("水果是"+color+"的!")
print("水果已经收获")
print("水果原来是"+Fruit.color+"的!")
class Apple(Fruit):
color = "红色"
def __init__(self):
print("我是苹果")
class Orange(Fruit):
color = "橙色"
def __init__(self):
print("\n我是橘子")
def harvest(self,color):
print("橘子是"+color+"的!")
print("橘子已经收获")
print("橘子原来是"+Fruit.color+"的!")

if __name__ == '__main__':
apple = Apple()
apple.harvest(apple.color)

orange = Orange()
orange.harvest(orange.color)



>>>
我是苹果
水果是红色的!
水果已经收获
水果原来是绿色的!

我是橘子
橘子是橙色的!
橘子已经收获
橘子原来是绿色的!

5.8.3 派生类调用基类的__init__()方法

在派生中定义​​__init__()​​​方法时,不会自动的调用基类的​​__init__()​​​方法。因此要在派生类调用基类的​​__init__()​​​方法进行必要的初始化,需要在派生类使用supper()函数调用基类的​​__init__()​​方法

​super().__init__()​​​ #与java不同的是,不必要放在第一行
语法

class Fruit:
def __init__(self,color="绿色"):
Fruit.color=color
print("水果是" + Fruit.color + "的!")
def harvest(self):
print("水果原来是"+Fruit.color+"的!")
class Apple(Fruit):
color = "红色"
def __init__(self):
print("我是苹果")
if __name__ == '__main__':
apple = Apple()
apple.harvest()
>>>
Traceback (most recent call last):
File "E:\大三\python_project_Best\fruit.py", line 13, in <module>
apple.harvest()
File "E:\大三\python_project_Best\fruit.py", line 6, in harvest
print("水果原来是"+Fruit.color+"的!")
AttributeError: type object 'Fruit' has no attribute 'color'
我是苹果

添加之后

class Fruit:
color = "绿色"
def __init__(self,color="绿色"):
Fruit.color=color
print("水果是" + Fruit.color + "的!")
def harvest(self):
print("水果原来是"+Fruit.color+"的!")
class Apple(Fruit):
color = "红色"
def __init__(self):
super().__init__()
print("我是苹果")
if __name__ == '__main__':
apple = Apple()
apple.harvest()

》水果是绿色的!
我是苹果
水果原来是绿色的!