一、面向对象特性
面向过程(着重做什么);
面向对象oop(着重谁去做,易于管理,结构清晰,方便迭代)
对象:类实例化后的结构体(实实在在的例子)
类:具有相同属性和方法的对象的集合(模板,定义了方法和属性,有什么特点能做什么事情)
封装:将属性和方法封装成类,不需要关注内部实现,只需要用即可
python一切皆对象
#继承、封装、多态
#函数和属性封装
class Animals:
def init(self,name):
self.name = name
def speak(self):
raise NotImplementedError(“x”)
class Dog(Animals):
def speak(self):
return “wow”
my_dog = Dog(“guaibao”)
print(my_dog.name)
print(my_dog.speak())
#不知道动物的具体类型也可以正常工作
def Animals_sound(animal):
print(animal.speak())
Animals_sound(my_dog)
1、类的继承和多态
class Shape:
def init(self, name):
self.name = name
def area(self):
pass
def perimeter(self):
pass
class Rectangle(Shape):
def init(self, width, height):
#super()调用父类的方法,子类重写父类仍想用父类方法。
作用:
1、在子类构造器中,调用父类构造方法,确保父类被正确初始化
2、访问父类方法
super().__init__("Rectangle")
self.width = width
self.height = height
def area(self):
return self.width * self.height
def perimeter(self):
return 2 * (self.width + self.height)
class Circle(Shape):
def init(self, radius):
super().init(“Circle”)
self.radius = radius
def area(self):
return 3.14159 * self.radius ** 2
def perimeter(self):
return 2 * 3.14159 * self.radius
2. 封装和私有属性
class Person:
def init(self, first_name, last_name, age):
self.first_name = first_name
self.last_name = last_name
#私有属性不可通过外部的实例对象直接访问或修改,只能通过类内部定义的公共方法访问或修改
self.__age = age # 私有属性
def get_age(self):
return self.__age
def set_age(self, age):
if 0 <= age <= 120:
self.__age = age
else:
print("Age must be within 0 and 120.")
使用封装
封装好处:
1、安全性:防止外部势力修改对象内部属性
2、接口简化
3、易于维护:
person = Person(“John”, “Doe”, 30)
print(person.first_name) # 正常访问
print(person.__age) # 尝试访问私有属性,将引发错误
print(person.get_age()) # 通过公共方法访问私有属性
person.set_age(110)
print(person.get_age())
接口简化
外部代码无需了解对象内部复杂实现,通过接口简单地与对象交互
class Bankaccount:
def init(self,id,usrname,number):
self.__id = id
self.__usrname = usrname
self.__number = number
def desposit(self,amount):
if amount>0:
self.__number+=amount
print(self.__number)
else :print(“必须存入大于0的金额”)
def withdraw(self,amount):
if amount>0:
self.__number-=amount
print(self.__number)
else:print(“取钱得大于0”)
account=Bankaccount(‘109’,‘xhq’,100)
account.desposit(100)
account.withdraw(10)
- 抽象类和接口
(1)抽象类定义一组公共接口,这些方法没有具体实现,而是作为占位符,强制子类提供实现方法
(2)抽象类不可被实例化
(3)包含一个或多个抽象方法,
(4)这样有助于保证子类具有一致性的行为,提供灵活性和可扩展性
在python中,抽象类通过abc模块中的ABC类(父类)创建。要定义一个抽象类可以使用@abstractmethod装饰器
from abc import ABC, abstractmethod
接口是面向对象编程中的一种规范,定义一组方法但是不提供实现
from abc import ABC, abstractmethod
class Vehicle(ABC):
@abstractmethod
def start(self):
pass
@abstractmethod
def stop(self):
pass
class Car(Vehicle):
def start(self):
print(“Car engine starts.”)
def stop(self):
print("Car engine stops.")
class Bicycle(Vehicle):
def start(self):
print(“Bicycle wheels start moving.”)
def stop(self):
print("Bicycle wheels stop.")
抽象类不能被实例化
vehicle = Vehicle() # 将引发错误
子类必须实现抽象类中的方法
car = Car()
car.start() # 输出: Car engine starts.
car.stop() # 输出: Car engine stops()
bicycle = Bicycle()
bicycle.start() # 输出: Bicycle wheels start moving.
bicycle.stop() # 输出: Bicycle wheels stop.
- 装饰者模式
装饰者模式允许用户在不修改对象的情况下,向对象添加新的功能。
通过创建一个包含对象的类(装饰者类),包装对象,在不改变对象的情况下,增加新的功能
1、增加对象指责
2、遵循开闭原则:对扩展开放,对修改封闭
#Coffee是一个接口,定义了get_cost方法,是所有组件和装饰者类的基类
#基类,定义了一个组件接口
class Coffee:
def get_cost(self):
return 1
#定义了组件的具体实现
class Espresso(Coffee):
def get_cost(self):
return 5
#在这个过程中,我并不知道用的是什么咖啡,我只知道加了奶就得加一块钱,至于什么咖啡我不在乎
class Milk(Coffee):
def init(self, coffee):
self._coffee = coffee
#返回私有变量__coffee的get_cost()方法的调用,并+1
def get_cost(self):
return self._coffee.get_cost() + 1
class Whip(Coffee):
def init(self, coffee):
self._coffee = coffee
def get_cost(self):
return self._coffee.get_cost() + 2
使用装饰者模式
espresso = Espresso()
print(espresso.get_cost()) # 输出: 5
#传入的是浓咖啡的实例(也可以是普通咖啡的实例,那就是1块+1块=2块)
espresso_with_milk = Milk(espresso)
print(espresso_with_milk.get_cost()) # 输出: 6
espresso_with_milk_and_whip = Whip(espresso_with_milk)
print(espresso_with_milk_and_whip.get_cost()) # 输出: 8
作业一:用户atm取款
1、注册、登陆
2、登陆成功后,存款、取款
#用户类:属性-用户名、密码
#atm类:属性-金额、银行
方法:查询、存款、取款
作业二:
[图片]
1、包含用户类(用户名、金额、密码属性);银行atm类(余额属性)
2、用户类不包含注册、登陆等方法,放到主程序中
3、银行负责:存款、取款、操作界面逻辑。
4、主程序实现用户登陆,并由User_dict管理所有用户
class User:
def init(self,name,passwd,money):
self.name = name
self.passwd = passwd
self.money = money
class ATM:
def init(self,bankname,account):
self.bankname = bankname
self.account = account
def desposit(self,U,num):
U.money+=num
self.account+=num
def withdraw(self,U,num):
if U.money>=num:
if self.account>=num:
U.money-=num
self.account-=num
print(“取款成功”)
elif self.account<num:
print(“atm余额不足”)
else :
print(f"用户余额不足,当前余额为{U.money}")
def service(self,U):
while True:
y=input("a、查询\tb、存款\tc、取款\tq、退出\n请输入: “)
if y==“q”:
break
else:
if y==“a”:
print(f"当前账户{U.name},余额为{U.money}”)
elif y==“b”:
n=int(input(‘请输入存款金额:’))
self.desposit(U,n)
elif y==“c”:
n=int(input(‘请输入取钱金额’))
self.withdraw(U,n)
else:
print(“错误输入!”)
if name ==“main”:
u1 = User(‘xhq’,“200108”,500)
u2 = User(‘xrq’,“200814”,1000)
User_dict = {u1.name:u1,u2.name:u2}
atm = ATM(‘changsha_bank’,10000)
while True:
z=input('a、注册\tb、登陆\q、退出\n请输入: ')
if z=="q":
break
elif z=="a":
username = input('输入用户名:')
if username in User_dict:
print('用户已存在,请重新输入!')
continue
passwd = input('input passwd: ')
money = int(input('input money:'))
User_dict[username]=User(username,passwd,money)
print('用户注册成功!')
elif z=="b":
username = input("input username: ")
passwd = input("input passwd: ")
if username in User_dict and passwd == User_dict[username].passwd:
print(f'尊贵的用户:{User_dict[username].name}登陆成功!')
atm.service(User_dict[username])
else:
print("用户名不存在或密码错误!")
else:
print("输入有误!")