首页 > 技术文章 > 面向对象

zwq- 2018-08-27 19:52 原文

一,编写与执行

"""编写类和执行类中方法的流程。
"""
#编写类
# class 类名:
#     def 函数名(self,参数):    #编写一个方法
#         pass
# obj = 类名         #实质化一个对象
# obj.函数名(参数)    #通过对象调用一个方法


二,面向对象的三大特性:封装/继承/多态
  封装:
            将相关功能封装到一个类中:
                class Message:
                    def email(self):pass
                    def msg(self):pass
                    def wechat(self):pass 
            将数据封装到一个对象中:
                
                class Person:
                    def __init__(self,name,age,gender):
                        self.name = name
                        self.age = age
                        self.gender = gender
                        
                obj = Person('孙福来',18,'')
继承:
class SuperBase: def f3(self): print('f3') class Base(SuperBase): # 父类,基类 def f2(self): print('f2') class Foo(Base): # 子类,派生类 def f1(self): print('f1') obj = Foo() obj.f1() obj.f2() obj.f3() # 原则:现在自己类中找,么有就去父类 总结: 1. 继承编写 class Foo(父类): pass 2. 支持多继承(先找左/再找右) 3. 为什么要有多继承? 提供代码重用性 多态: 多种形态或多种状态 鸭子模型,只要可以嘎嘎叫就是鸭子. #Python # 由于python原生支持多态,所以没有特殊性. """ class Foo1: def f1(self): pass class Foo2: def f1(self): pass class Foo3: def f1(self): pass def func(arg): arg.f1() obj = Foo1() # obj= Foo2() obj = Foo3() func(obj) """ #java class Son(list): pass class Son1(list): pass # 以后传参时,arg可以是:list类的对象/list任何子类的对象 public void func(list arg){ print(arg) } # obj = list() # obj = Son() obj = Son1() func(obj)

 三,面向对象中的self指什么

self 是形式参数,指调用类时创建的对象

练习:
'''定义一个类,计算周长和面积的方法(圆的半径通过参数传递到构造⽅方法)。'''
import math
class Compute:
    def __init__(self,r):
        self.r = int(r)
    def perimeter(self):
        return 2*math.pi*self.r
    def area(self):
        return math.pi*self.r**2
obj = Compute(3)
print(obj.perimeter())
print(obj.area())
用类方法计算圆的周长和面积
"""1. while循环提示⽤用户输入:用户名、密码、邮箱(正则满⾜邮箱格式)
2. 为每个⽤用户创建一个对象,并添加到列表中。
3. 当列表中添加了3个对象后,跳出循环并以此循环打印所有⽤用户的姓名和邮箱。如:
                我叫zwq,邮箱是xxx@live.com
                我叫breeze,邮箱是xxx@live.com"""
import re
user_list = []
while True:
    user = input("请输入用户名:")
    pwd = input("请输入密码:")
    email = input("请输入邮箱:")
    email_ret = re.search('[0-9a-zA-Z][\w\-.]+@[a-zA-Z0-9\-]{2,5}\.com',email)
    if email_ret:
        class User:
            def __init__(self, name, pwd, email):
                self.name = name
                self.pwd = pwd
                self.email = email
        obj = User(user, pwd, email)
        user_list.append(obj)
        if len(user_list) == 3:
            for i in user_list:
                print('我叫%s,邮箱是%s'%(i.name,i.email))
            break
    else:
        print('邮箱格式不正确请重新输入')
面向对象方法实现格式化输出
class User:

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

class Account:

    def __init__(self):
        self.user_list = []  #用户列表,数据格式[User对象,User对象,User对象]
    def login(self):
        """用户登录,用户输入用户名和密码并去self.user_list中检查用户是否合法
        :return:
        """
        print("欢迎来到登录系统,请登录")
        n = 3
        while n > 0:
            user_name = input('请输入用户名')
            user_pwd = input('请输入登录密码')
            for i in self.user_list:
                if user_name == i.name and user_pwd == i.pwd:
                    print("欢迎登录")
                    return
            else:
                n -= 1
                print( '用户名或密码错误,请重新输入,还有%s次机会'%n)
                if n==0:
                    print('请15分钟之后再试')

    def register(self):
        """用户注册,动态创建User对象,并添加到self.user_list中
        :return:
        """
        print("欢迎来到注册系统,请进行注册")
        user_name = input('请输入用户名')
        user_pwd = input('请输入注册密码')
        obj = User(user_name,user_pwd)
        self.user_list.append(obj)
    def run(self):
        """主程序,先进行两次用户注册,再进行用户登录(3次重试机会)
        :return:
        """
        for i in range(2):
           self.register()
        self.login()

if __name__ == '__main__':
    obj = Account()
    obj.run()
面向对象方法实现注册和登录

四,类的成员

成员共分为三类: 变量; 方法; 属性
1.变量:
- 实例变量(字段)
- 公有实例变量(字段)
- 私有实例变量(字段)
- 类变量(静态字段)
- 公有类变量(静态字段)
- 私有类变量(静态字段)
# 实例一:
class Foo:
    # 类变量(静态字段)
    country = "中国"
    
    def __init__(self,name):
        # 实例变量(字段)
        self.name = name  
       
    def func(self):
        pass                
obj1 = Foo('zwq')
obj2 = Foo('breeze')
Foo.country
                

类的子类(派生类)也不能调用其私有变量

#无法访问:
class Base(object):
    __secret = "受贿"

class Foo(Base):
    def func(self):
        print(self.__secret)
        print(Foo.__secret)

obj = Foo()
obj.func()

#可以访问:
class Base(object):
    __secret = "受贿"

    def zt(self):
        print(Base.__secret)

class Foo(Base):

    def func(self):
        print(self.__secret)
        print(Foo.__secret)
obj = Foo()
obj.zt()

 

2.方法: 

 实例方法;静态方法;类方法

# 实例方法
class Foo(object):
    def __init__(self, name):
        self.name = name

    # 实例方法
    def func(self):
        print(self.name)
        
obj = Foo('..')
obj.func()

# 静态方法
class Foo(object):
    def __init__(self, name):
        self.name = name

    # 静态方法,如果方法无需使用对象中封装的值,那么就可以使用静态方法
    @staticmethod
    def display(a1,a2):
        return a1 + a2
Foo.display(1,3)

# 类方法
class Foo(object):
    # 类方法,cls是类
    @classmethod
    def show(cls,x1,x2):
        print(cls,x1,x2)

# 执行类方法
Foo.show(1,8)

3.属性

#示例:
class Foo(object):
    def __init__(self):
        pass

    @property
    def start(self):
        return 1
        
    @property
    def end(self):
        return 10

obj = Foo()
print(obj.start)
print(obj.end)
"""
     总结:
         1. 编写时
                - 方法上方写 @property
                - 方法参数:只有一个self
         2. 调用时:无需加括号  对象.方法
         3. 应用场景: 对于简单的方法,当无需传参且有返回值时,可以使用 @property
"""

五,类的组合(嵌套)

#面向对象:
"""
创建三个学校且三个学校的设施内容等都是一致.
"""

class School(object):
    def __init__(self, name, address):
        self.name = name
        self.address = address

    def speech(self):
        print('讲课')

obj1 = School('老男孩北京校区', '美丽富饶的沙河')
obj2 = School('老男孩上海校区', '浦东新区')
obj3 = School('老男孩深圳校区', '南山区')
class Teacher(object):
    def __init__(self, name, age, salary):
        self.name = name
        self.age = age
        self.__salary = salary
        self.school = None

t1 = Teacher('李杰', 19, 188888)
t2 = Teacher('艳涛', 18, 60)
t3 = Teacher('女神',16, 900000)
# ############## 老师分配校区
t1.school = obj1
t2.school = obj1
t3.school = obj2
# ####################################
# 查看t1老师,所在的校区名称/地址
print(t1.school.name)
print(t1.school.address)
print(t1.name)
print(t1.age)
t1.school.speech()

#准则: 字段和方法的归类.
View Code

注意:类或对像可以作字典的键

六,特殊成员
class Foo(object):

    def __init__(self,a1,a2):
        self.a1 = a1
        self.a2 = a2
    
    def __call__(self, *args, **kwargs):
        print(11111,args,kwargs)
        return 123

    def __getitem__(self, item):
        print(item)
        return 8

    def __setitem__(self, key, value):
        print(key,value,111111111)

    def __delitem__(self, key):
        print(key)

    def __add__(self, other):
        return self.a1 + other.a2

    def __enter__(self):
        print('1111')
        return 999

    def __exit__(self, exc_type, exc_val, exc_tb):
        print('22222')

# 1. 类名() 自动执行 __init__
# obj = Foo(1,2)

# 2. 对象() 自动执行 __call__
# ret = obj(6,4,2,k1=456)

# 3. 对象['xx']  自动执行 __getitem__
# ret = obj['yu']
# print(ret)

# 4. 对象['xx'] = 11  自动执行 __setitem__
# obj['k1'] = 123

# 5. del 对象[xx]     自动执行 __delitem__
# del obj['uuu']

# 6. 对象+对象         自动执行 __add__
# obj1 = Foo(1,2)
# obj2 = Foo(88,99)
# ret = obj2 + obj1
# print(ret)

# 7. with 对象        自动执行 __enter__ / __exit__
# obj = Foo(1,2)
# with obj as f:
#     print(f)
#     print('内部代码')

 

 

 

 

 

 

 
 

推荐阅读