面向对象学习笔记(1)

part1

1.封装

概述

如果写代码时,函数比较多比较乱:

  1. 可以将函数归类并放到同一个类中。(方法封装到类中)
  2. 函数如果有一个反复使用的公共值,则可以放到对象中。(相同的参数封装到对象中)

对比面向过程和面向对象:

  • 面向过程

    将多个def函数分别归类到不同的文件夹、py文件中,在main函数需要使用的时候通过from … import …的方式进行调用

  • 面向对象

    使用class进行封装:将同一类的函数(方法)封装到一个类中。

class Goods:
    def goods(self):
        pass
    def func2(self):
        pass

一般习惯:类名首字母大写(函数名:除第一个单词外首字母大写)

应用场景:遇到很多函数,需要给函数进行归类和划分。【封装】

基本格式
# 函数
def func():
    pass

# 调用
from src import account
account.login()
account.logout()
# 定义一个类(类名:Account)
class Account:
    # 方法
    def login(self):
        print("登录")
        
    def logout(self,name):
        print(name+"注销")
        return 12
        
# 调用
# 首先要创建一个类的对象(或者称为实例化)
x = Account()
# 使用对象调用类中的方法
x.login()
num = x.logout("wany")
print(num)

【练习】 假设有n个功能函数,进行封装

class Db:
    #数据库操作
    def db_add(self):
        pass
    def db_del(self):
        pass
    def db_change(self):
        pass
    def db_query(self):
        pass

class File:
    #文件操作
    def file_add(self):
        pass
    def file_del(self):
        pass
    def file_change(self):
        pass
    def file_query(self):
        pass
实例化对象的作用和练习

存储一些值,以后方便自己使用。

class File:
    def read(self):
        with open(self.x , mode='r',encoding='utf-8') as f:
            data = f.read()
        return data

    def write(self , content):
        with open(self.x , mode='a',encoding='utf-8') as f:
            f.write(content)

# 实例化一个对象
obj1 = File()
obj1.x = "test.log"
# 通过对象调用类中的read方法(此时的self就是obj1)
obj1.write("1")
obj1.read()

# 实例化一个对象
obj2 = File()
obj2.x = "info.txt"
# 通过对象调用类中的read方法(此时的self就是obj1)
obj2.write("2")
obj2.read()
# 简单示例:
class Person:
    def show(self):
        print(f"我是{self.name} 年龄{self.age} 性别{self.sex}")
        
p1 = Person()
p1.name = "wany"
p1.age = 100
p1.sex = "男"

p1.show()

以下为一般写法(上述帮助理解)

class Person:
    def __init__(self):
        self.name = "wany"
        self.age = 100
        self.sex = "男"
    
    def show(self):
        print(f"我是{self.name} 年龄{self.age} 性别{self.sex}")、
        
p1 = Person() # 类() =>  实例化对象,只要实例化直接自动执行此类中的__init__方法。
p1.show()

此时出现新的问题:

# 如果此时新实例化一个p2
p2 = Person()
p2.show()

# 此时得到的结果与p1一致

解决方案?使用 参数传递。

class Person:
    def __init__(self , name , age ,sex): # 初始化方法
        self.name = name
        self.age = age
        self.sex = sex

    def show(self):
        print(f"我是{self.name} 年龄{self.age} 性别{self.sex}")


p1 = Person("wany",20,"男")
p1.show()
p2 = Person("cxwxy",25,"女")
p2.show()

【练习】循环让用户输入:用户名/密码,输入 yes 后进行数据打印

# 面向过程的写法:
users_list = []
while True:
    user = input("请输入用户名:")
    pwd = input("请输入密码:")
    temp = {'user':user,'pwd':pwd}
    users_list.append(temp)
    check = input("是否完成?yes or no?")
    if check == "yes":
        break

for e in users_list:
    temp = f"用户名:{e['user']},密码:{e['pwd']}"
    print(temp)
# 面向对象的写法:
class Person:
    def __init__(self,user,pwd):
        self.user = user
        self.pwd =pwd

    def resultprint(self):
        print(f"用户名:{self.user},密码:{self.pwd}")

users_list = []
while True:
    user = input("请输入用户名:")
    pwd = input("请输入密码:")
    temp = Person(user,pwd)
    users_list.append(temp)
    check = input("是否完成?yes or no?")
    if check == "yes":
        break

for e in users_list:
    e.resultprint()
示例
class Police:
    def __init__(self,name):
        self.name = name
        self.hp = 100
    def attack(self,other):
        msg = f"{self.name}攻击了{other.nickname}"
        self.hp -= 10
        other.hp -= 20
        print(msg)

class Bandit:
    def __init__(self,nickname):
        self.nickname = nickname
        self.hp = 100

zs = Police("张三")
ls = Bandit("李四")
zs.attack(ls)

2.继承

概述
# 父类 (基类)
class Father:
    def func1(self):
        print("父类功能1")

# 子类 (派生类)
class Son(Father):  # 表示继承
    def func2(self):
        print("子类功能2")
        
class Son2(Father):  # 表示继承
    def func3(self):
        print("子类2功能3")

# 创建一个子类对象
exp = Son()
# 执行对象方法时,优先在自己的类中找,如果没有再去父类中找
exp.func2()
exp.func1()

# 创建一个父类对象
exp2 = Father()
# exp2.func2()  => 会报错
应用场景

多个类中如果有公共的方法,可以放到基类中避免重复编写。

重点

继承关系中的查找方法顺序:

#示例一
class Base:
	def f1(self):
		print("base.f1")
        
class Foo(Base):
	def f2(self):
		print("foo.f2")
        
obj = Foo()
obj.f1()
obj.f2()
# 结果:
# base.f1
# foo.f2
#示例二
class Base:
	def f1(self):
		print("base.f1")
              
class Foo(Base):
	def f2(self):
		self.f1()
		print("foo.f2")
              
obj = Foo()
obj.f2()
# 结果:
# base.f1
# foo.f2
# 示例三
class Base:
    def f1(self):
        print("base.f1")
        
class Foo(Base):
    def f2(self):
        self.f1()
        print("foo.f2")
    def f1(self):
        print("foo.f1")
        
obj = Foo()
obj.f2()
# 结果:
# foo.f1
# foo.f2
# 示例四
class Base:
    def f1(self):
        self.f2()
        print("base.f1")
    def f2(self):
        print("base.f2")

class Foo(Base):
    def f2(self):
        print("foo.f2")

obj = Foo()
obj.f1()
# 结果:
# foo.f2
# base.f1

注意事项:

  • self 到底是谁?
  • self是哪个类创建的,就从此类开始找
  • 自己没有则去父类寻找
  • 如果继承了多个父类,从左往右找(不推荐使用多继承,只有python,C++语法上支持多继承)

3.多态

多态:多种形态/多种类型(鸭子模型)

# python天生自带多态
def func(arg):
    temp = arg[1]
    print(temp)
# arg可以传 字符串、元组、列表、字典等等具有索引功能的数据类型

# java
def func(str arg):
    temp = arg[-1]
    print(temp)

面试时,什么是鸭子模型?

对于一个函数而言,python对于参数的类型不会限制,那么传入的参数就可以是各种类型。如果函数中有例如arg.send方法,那么就是对传入类型的一个限制(类型必须有send方法)。这就是鸭子模型,类似于上述的函数。(通俗来讲,只要是呱呱叫的,就认为是鸭子)

4.作业题

import sys

class User:
    def __init__(self,name,pwd):
        self.name = name
        self.pwd = pwd

class Account:
    def __init__(self):
        self.user_list = []

    def register(self):
        # 注册:没注册一个用户就创建一个user对象,然后添加到self.user_list中,表示注册成功。
        # 最多存放三个
        while len(self.user_list) < 3:
            user = input("请输入用户名(输入N退出):")
            if user.upper() == "N":
                return
            pwd = input("请输入密码:")
            temp_obj = User(user,pwd)
            self.user_list.append(temp_obj)
            print("注册成功")
        print("存放到达上限")


    def login(self):
        times = 0
        while times < 2:
            user = input("请输入用户名:")
            pwd = input("请输入密码:")
            flag = False
            for item in self.user_list:
                # 每个item是一个User对象
                if item.name == user and item.pwd == pwd:
                    flag = True
                    break
            if flag:
                print("登陆成功")
                sys.exit(0)
            else:
                print("用户名或者密码错误")
            times = times + 1
        print("试错以达上限")
        sys.exit(1)


    def run(self):
        print("1.注册;2.登录;3.退出")
        while True:
            choice = input("输入选择:")
            if choice == "1":
                self.register()
            elif choice == "2":
                self.login()
            elif choice == "3":
                print("退出")
                return
            else:
                print("输入有误")
                return

if __name__ == '__main__':
    # 开辟了一块内存给obj(实例化对象),内存中存储了 user_list = []
    obj = Account()
    obj.run()

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值