面向对象分为以下方面:
(1)类 (2)类变量 (3)数据成员 (4)方法重写 (5)局部变量 (6)实例变量 (7)继承 (8)实例化 (9)方法 (10)对象
一、类(Class): 用来描述具有相同的属性和方法的对象的集合。它定义了该集合中每个对象所共有的属性和方法。对象是类的实例。
1.创建类:利用class语句创建类:class 后跟类名并以冒号结尾:
class student:
name=None
gender=None
age=None
#student为类名,name,gender,age为类的属性
类的属性:即定义在类中的变量(成员变量)
类的行为:即定义在类中的函数(成员方法)
注:函数与方法的区别:函数是写在类外部的,方法是写在类内部的(即定义在类中的函数称之为方法)
2.创建对象:对象=类名() :
stu_1=student()
stu_1=student()
#stu_1和stu_2既是变量也是对象
3.对象属性赋值:通过对象.属性名的方式赋值:
stu_1.name='张三'
stu_1.gender='男'
stu_1.age=18
4.访问属性:对象.属性名的方式进行访问:
print(stu_1.name)
print(stu_1.gender)
print(stu_1.age)
5.成员方法的定义:
def 方法名(self,形参1,形参2,...,形参n):
方法体
class student:
name=None
gender=None
age=None
def say_hi(self):
print('大家好我是',self.name)
stu_1=student()
stu_1.name='张三'
stu_1.gender='男'
stu_1.age=18
stu_1.say_hi()
注:self关键字是成员方法定义时必须填写的,它用来表示类对象自身的意思,当我们使用类对象调用方法时,self会自动被传入,在方法内部,想要访问类的成员变量,必须使用self。
含有参数的成员方法:
class student:
name=None
#不带参数的成员方法:
def say_hi(self):
print('大家好我叫',self.name,'希望多多照顾')
#带参数的成员方法:
def say_hi2(self,msg):
print('大家好我叫',self.name,msg)
stu1=student()
stu1.name='李子木'
stu1.say_hi()
stu2=student()
stu2.name='罗森'
stu2.say_hi2('我是一家便利店')
面向对象编程:就是使用对象进行编程,设计类,基于类去创建对象,并使用对象来完成具体的工作:
class clock:
price=None
id=None
def ring(self):
import winsound
winsound.Beep(2000,5000)
clock_1=clock()
clock_1.price=10
clock_1.id='001'
clock_1.ring()
构造方法:_ _init_ _()方法,作用:
(1)在创建类对象(构造类)的时候,会自动执行
(2)在创建类对象(构造类)的时候,将传入参数自动传递给_init_方法使用,借此特性给成员变量赋值
class student:
#可写可不写
'''
name=None
age=None
tel=None
'''
def __init__(self,name,age,tel):
#既有给成员变量赋值的功能也有定义成员变量的功能
self.name=name
self.age=age
self.tel=tel
print('可以自动运行')
stu=student('李子木',20,'12345678912')
print(stu.name,stu.age,stu.tel)
常见的魔术方法:
(1)构造方法:_ _init_ _
(2)字符串方法:_ _str_ _
#使用字符串魔术方法可以控制类转换为字符串的行为:
class student:
def __init__(self,name,age,tel):
self.name=name
self.age=age
self.tel=tel
def __str__(self):
return f'name:{self.name},age:{self.age},tel:{self.tel}'
stu=student('李子木',20,'12345678912')
print(stu)
print(str(stu))
#不使用字符串魔术方法打印类对象输出的是内存地址:
class student:
def __init__(self,name,age,tel):
self.name=name
self.age=age
self.tel=tel
stu=student('李子木',20,'12345678912')
print(stu)
print(str(stu))
(3)小于大于符号比较:_ _lt_ _
class student:
def __init__(self,name,age):
self.name=name
self.age=age
#other,另一个类对象
def __lt__(self,other):
#返回值为TRUE或FALSE
return self.age<other.age
stu1=student('李子木',20)
stu2=student('林木',25)
print(stu1<stu2)
print(stu1>stu2)
(4)小于等于,大于等于符号比较:_ _le_ _
class student:
def __init__(self,name,age):
self.name=name
self.age=age
#other,代表另一个类对象
def __le__(self, other):
#返回值为TRUE或FALSE
return self.age<=other.age
stu1=student('李子木',20)
stu2=student('林木',25)
print(stu1<=stu2)
print(stu1>=stu2)
(5)==符号比较:_ _eq_ _
class student:
def __init__(self,name,age):
self.name=name
self.age=age
#other,代表另一个类对象
def __eq__(self, other):
#返回值为TRUE或FALSE
return self.age==other.age
stu1=student('李子木',25)
stu2=student('林木',25)
stu3=student('张三',30)
print(stu1==stu2)
print(stu1==stu3)
==符号比较两个值是否相等,若没有使用_ _eq_ _方法,则默认比较的是两个对象的内存地址
class student:
def __init__(self,name,age):
self.name=name
self.age=age
stu1=student('李子木',25)
stu2=student('林木',25)
stu3=student('张三',30)
print(stu1==stu2)
print(stu1==stu3)
面向对象的三大特性:
1.封装 2.继承 3.多态
1.封装:将现实世界事物的属性和行为封装到类中,描述为成员变量和成员方法,从而完成程序对现实世界事物的描述
定义私有成员的方式:
(1)私有成员变量(无法赋值也无法获取值):变量名以_ _开头(两个英文下划线)
(2)私有成员方法(无法直接被类对象使用):方法名以_ _开头(两个英文下划线)
class phone:
__voltage=None
def __keep_single_core(self):
print('让CPU以单核模式运行')
phone1=phone()
#报错
print(phone1.__voltage)
#报错
phone1.__keep_single_core()
私有成员无法被类对象使用,但是可以被类中其它的成员使用(即不公开的属性和方法,在类中提供仅供内部使用的属性和方法,而不对外开放,即类对象无法使用)
class phone:
__voltage=0.8
def __keep_single_core(self):
print('让CPU以单核模式运行')
def open_5g(self):
if self.__voltage>=1:
print('5g已开启')
else:
self.__keep_single_core()
print('无法开启5g并开启省电模式')
phone1=phone()
phone1.open_5g()
2.继承:继承分为单继承和多继承(被继承的类叫父类,继承的类叫子类)
(1) 继承的语法:
class 类名(父类名):
类内容体
(2)单继承:一个子类继承一个父类
class phone:
producer='huawei'
def call_by_4g(self):
print('4g通话')
class New_phone(phone):
face_id='001'
def call_by_5g(self):
print('新功能5g通话')
phone1=New_phone()
print(phone1.producer)
phone1.call_by_4g()
phone1.call_by_5g()
(3)多继承:一个子类继承多个父类(多个父类名之间用逗号隔开)
class NFCreader:
nfc_type='第五代'
producer='xiaomi'
def read_card(self):
print('NFC读卡')
def write_card(self):
print('NFC写卡')
class phone:
producer='huawei'
def call_by_4g(self):
print('4g通话')
class remote:
re_type='红外遥控'
def control(self):
print('已开启红外遥控')
class My_phone(NFCreader,phone,remote):
#pass语句表示空,占位作用使语法不报错
pass
phone1=My_phone()
phone1.control()
phone1.call_by_4g()
print(phone1.producer)
phone1.read_card()
注:如果父类中有同名的属性或方法,则从左至右先继承的优先级高于后继承
复写:子类继承父类的成员属性和成员方法后,如果对其不满意,则可进行复写(即在子类中重新定义同名的属性或方法即可)
class phone:
price=3000
producer='xiaomi'
def call_by_4g(self):
print('4g网络通话')
class my_P(phone):
price=2999
def call_by_4g(self):
print('即将升级5g')
phone=my_P()
print(phone.price)
print(phone.producer)
phone.call_by_4g()
调用父类同名成员:
一旦复写父类成员,那么类对象调用成员的时候会调用复写后的新成员若需要使用被复写的父类成员,则需用特殊调用方式:
方式一:
使用成员变量:父类名.成员变量
使用成员方法:父类名.成员方法(self)
class phone:
price=3000
producer='xiaomi'
def call_by_5g(self):
print('5g网络通话')
class my_P(phone):
price=2999
def call_by_5g(self):
print('父类:',phone.price)
print('子类:', self.price)
print('更加省电')
print('性能更好')
phone.call_by_5g(self)
phone1=my_P()
phone1.call_by_5g()
print(phone1.price)
方式二:使用super()调用父类成员
使用成员变量:super( ).成员变量
使用成员方法:super( ).成员方法( )
class phone:
price=3000
producer='xiaomi'
def call_by_5g(self):
print('5g网络通话')
class my_P(phone):
price=2999
def call_by_5g(self):
print('子类:',self.price)
print('父类:',super().price)
super().call_by_5g()
print('更加省电')
print('性能更好')
phone1=my_P()
phone1.call_by_5g()
注:只可以在子类内部调用父类的同名成员,子类的实体类对象调用默认是调用子类复写的
类型注解(类型注解只是提示性的备注,不会影响程序的执行):在代码中涉及数据交互的地方,提供数据类型的注解(显示的说明)
类型注解支持:
(1)变量的类型注解
(2)函数(方法)形参列表和返回值的类型注解
主要功能:
(1)帮助第三方IDE工具(如pycharm)对代码进行类型推断,协助做代码提示
(2)帮助开发者自身对变量进行类型注解
类型注解的语法:
为变量设置类型注解:
(1)变量:类型
#基础数据类型注解:
var_1: int=10
var_2: float=3.1415926
var_3: bool=True
var_4: str='apple'
#类对象类型注解:
class Student:
pass
stu: Student=Student()
#基础容器类型注解:
my_list: list=[1,2,3]
my_tuple: tuple=(1,2,3)
my_set: set={1,2,3}
my_dict: dict={'id':1}
my_str: str='orange'
#容器类型详细注解:
my_list: list[int]=[1,2,3]
my_tuple: tuple[str,int,bool]=('a',2,True)
my_set: set[int]={1,2,3}
my_dict: dict[str,int]={'id':1}
(2)# type: 类型
import json
import random
var_1 = random.randint(1,10) # type: int
#json.loads可以把字符串数据转换为字典类型
var_2 = json.loads('{"name":"apollo"}') # type: dict[str,str]
def func():
return 10
var_3 = func() # type: int
注:(1)元组类型设置类型详细注解,需要将每一个元素类型都标记出来
(2)字典类型设置类型详细注解,需要2个类型,第一个是key第二个是value
为函数(方法)的类型注解——形参注解:
函数和方法的形参类型注解语法:
def 函数方法名(形参名:类型,形参名:类型,...):
pass
def add(x: int, y: int):
return x+y
print(add(12,2))
为函数(方法)的类型注解——返回值注解:
语法:
def 函数方法名(形参名:类型,形参名:类型,...)一> 返回值类型:
pass
def func(a: list) -> list:
return a
print(func([1,2,3]))
Union联合类型注解(在变量注解,函数,方法中的形参和返回值注解中均可使用):
使用Union类型注解必须导包:from typing import Union
语法:Union[类型1,类型2,...]
from typing import Union
my_list: list[Union[str, int]] = [1, 2, 3, 'a', 'b', 'c']
my_dict: dict[str, Union[str, int]] = {'a': 1, 'b': 'apollo', 'c': 2}
def func(data: Union[list, int, str]) -> Union[list, int, str]:
return data
print(func(1))
print(func('a'))
print(func([1,2,3]))
多态 :同一个行为,使用不同的对象获得不同的状态
抽象类(接口):包含抽象方法的类,称之为抽象类,抽象类方法是指没有具体实现的方法(pass)称之为抽象方法,抽象类多用于做顶层设计,以便子类做具体实现,并配合多态实现不同的状态
class Animal:
def speak(self):
pass
class Dog(Animal):
def speak(self):
print('汪汪汪')
class Cat(Animal):
def speak(self):
print('喵喵喵')
def speaking(animal: Animal):
animal.speak()
dog=Dog()
cat=Cat()
speaking(dog)
speaking(cat)