zoukankan      html  css  js  c++  java
  • 面向对象初始

    内容详细

    1.面向对象基本格式

    # ###### 定义类 ###### 
    class 类名:
        def 方法名(self,name):
            print(name)
            return 123
        def 方法名(self,name):
            print(name)
            return 123
        def 方法名(self,name):
            print(name)
            return 123
    # ###### 调用类中的方法 ###### 
    # 1.创建该类的对象
    obj = 类名()
    # 2.通过对象调用方法
    result = obj.方法名('alex')
    print(result)
    

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

    2.对象的作用

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

    class File:
        def read(self):
            with open(self.xxxxx, mode='r', encoding='utf-8') as f:
                data = f.read()
            return data
    
        def write(self, content):
            with open(self.xxxxx, mode='a', encoding='utf-8') as f:
                f.write(content)
    
    # # 实例化了一个File类的对象
    obj1 = File()
    # # 在对象中写了一个xxxxx = 'test.log'
    obj1.xxxxx = "test.log"
    # # 通过对象调用类中的read方法,read方法中的self就是obj。
    # # obj1.read()
    obj1.write('alex')
    
    
    # 实例化了一个File类的对象
    obj2 = File()
    # 在对象中写了一个xxxxx = 'test.log'
    obj2.xxxxx = "info.txt"
    # 通过对象调用类中的read方法,read方法中的self就是obj。
    # obj2.read()
    obj2.write('alex')
    
    
    class Person:
        def __init__(self,n,a,g): # 初始化方法(构造方法),给对象的内部做初始化。
            self.name = n
            self.age = a
            self.gender = g
    
        def show(self):
            temp = "我是%s,年龄:%s,性别:%s " % (self.name, self.age, self.gender,)
            print(temp)
    
    # 类() 实例化对象,自动执行此类中的 __init__方法。
    p1 = Person('李兆琪',19,'男')
    p1.show()
    
    p2 = Person('利奇航',19,'男')
    p2.show()
    

    总结:将数据封装到对象,方便使用。

    总结

    """
    如果写代码时,函数比较多比较乱。
    1. 可以将函数归类并放到同一个类中。
    2. 函数如果有一个反复使用的公共值,则可以放到对象中。
    """
    
    class File:
        def __init__(self,path):
            self.file_path = path
            
        def read(self):
            print(self.file_path)
        
        def write(self,content):
            print(self.file_path)
        
        def delete(self):
            print(self.file_path)
        
        def update(self):
            print(self.file_path)
        
    p1 = File('log.txt')
    p1.read()
    
    p2 = File('xxxxxx.txt')
    p2.read()
    
    # 1. 循环让用户输入:用户名/密码/邮箱。 输入完成后再进行数据打印。
    # ########## 以前的写法
    USER_LIST = []
    while True:
        user = input('请输入用户名:')
        pwd = input('请输入密码:')
        email = input('请输入邮箱:')
        temp = {'username':user,'password':pwd,'email':email}
        USER_LIST.append(temp)
    for item in USER_LIST:
        temp = "我的名字:%s,密码:%s,邮箱%s" %(item['username'],item['password'],item['email'],)
        print(temp)
        
    # ########## 面向对象写法
    
    class Person:
        def __init__(self,user,pwd,email):
            self.username = user
            self.password = pwd
            self.email = email
    	
    USER_LIST = [对象(用户/密码/邮箱),对象(用户/密码/邮箱),对象(用户/密码/邮箱)]
    while True:
        user = input('请输入用户名:')
        pwd = input('请输入密码:')
        email = input('请输入邮箱:')
        p = Person(user,pwd,email)
        USER_LIST.append(p)
    
    for item in USER_LIST:
        temp = "我的名字:%s,密码:%s,邮箱%s" %(item.username,item.password,item.email,)
        print(temp)
    
    # ########## 面向对象写法
    
    class Person:
        def __init__(self,user,pwd,email):
            self.username = user
            self.password = pwd
            self.email = email
            
    	def info(self):
            return "我的名字:%s,密码:%s,邮箱%s" %(item.username,item.password,item.email,)
        
    USER_LIST = [对象(用户/密码/邮箱),对象(用户/密码/邮箱),对象(用户/密码/邮箱)]
    while True:
        user = input('请输入用户名:')
        pwd = input('请输入密码:')
        email = input('请输入邮箱:')
        p = Person(user,pwd,email)
        USER_LIST.append(p)
    
    for item in USER_LIST:
        msg = item.info()
        print(msg)
    

    4.继承

    # 父类(基类)
    class Base:
        def f1(self):
            pass
    # 子类(派生类)
    class Foo(Base):
        def f2(self):
            pass
    
    # 创建了一个子类的对象
    obj = Foo()
    # 执行对象.方法时,优先在自己的类中找,如果没有就是父类中找。
    obj.f2()
    obj.f1()
    
    # 创建了一个父类的对象
    obj = Base()
    obj.f1()
    

    问题:什么时候才能用到继承?多个类中如果有公共的方法,可以放到基类中避免重复编写。

    class Base:
        def f1(self):
            pass
        
    class Foo(Base):
        def f2(self):
            pass
        
    class Bar(Base):
        def f3(self):
            pass
    
    obj1 = Foo()
    
    obj2 = Bar()
    
    

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

    # 示例一
    class Base:
        def f1(self):
            print('base.f1')
            
    class Foo(Base):
        def f2(self):
            print('foo.f2')
            
    obj = Foo()
    obj.f1()
    obj.f2()
    
    # 示例二
    class Base:
        def f1(self):
            print('base.f1')
            
    class Foo(Base):
        def f2(self):
            self.f1()
            print('foo.f2')
            
    obj = Foo()
    obj.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()
    
    # 示例四
    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()
    
    # 示例五
    class TCPServer:
        pass
    class ThreadingMixIn:
        pass
    class ThreadingTCPServer(ThreadingMixIn, TCPServer): 
        pass
    
    # 示例六
    class BaseServer:
        def serve_forever(self, poll_interval=0.5):
            self._handle_request_noblock()
    	def _handle_request_noblock(self):
            self.process_request(request, client_address)
            
    	def process_request(self, request, client_address):
            pass
        
    class TCPServer(BaseServer):
        pass
    
    class ThreadingMixIn:
        def process_request(self, request, client_address):
            pass
        
    class ThreadingTCPServer(ThreadingMixIn, TCPServer): 
        pass
    
    obj = ThreadingTCPServer()
    obj.serve_forever()
    
    

    注意事项:

    • self 到底是谁?
    • self 是哪个类创建的,就从此类开始找,自己没有就找父类,同时继承多个基类的就从左到右依次查找,第一个基类找完了,没找到,就到后续的基类中查找。

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

    # Python
    def func(arg):
        v = arg[-1] # arg.append(9)
        print(v)
    
    # java
    def func(str arg):
        v = arg[-1]
        print(v)
    

    面试题:什么是鸭子模型。

    对于一个函数而言,Python对于参数的类型不会限制,那么传入参数时就可以是各种类型,在函数中如果有例如:arg.send方法,那么就是对于传入类型的一个限制(类型必须有send方法)。这就是鸭子模型
    

    总结

    1. 面向对象的三大特性:封装/继承/多态

      • 封装

        class File:
            def read(self):
                pass
            def write(self):
                pass
        
        class Person:
            def __init__(sef,name,age):
                self.name = name
                self.age = age
        p = Person('alex',19)
        
      • 继承

        class Base:
            pass
        class Foo(Base):
            pass
        
        • 多继承
        • self到底是谁?
        • self是由于那个类创建,则找方法时候就从他开始找。
      • 多态

        def func(arg): # 多种类型,很多事物
            arg.send() # 必须具有send方法,呱呱叫
        
    2. 格式和关键词

      class 类:
          def __init__(self,x):
              self.x = x 
              
          def 方法(self,name):
              print(self.x, name)
              
      # 实例化一个类的对象
      v1 = 类(666)
      v2.方法('alex')
      

      三个词:

      • 对象
      • 方法
    3. 什么时候用面向对象?

      • 函数(业务功能)比较多,可以使用面向对象来进行归类。
      • 想要做数据封装(创建字典存储数据时,面向对象)。
      • 游戏示例:创建一些角色并且根据角色需要再创建人物。

    内容详细

    1.成员

      • 类变量
      • 绑定方法
      • 类方法
      • 静态方法
      • 属性
    • 实例(对象)

      • 实例变量
    • 定义:写在类的下一级和方法同一级。

    • 访问:

      类.类变量名称
      对象.类变量名称
      
    • 面试题

      class Base:
          x = 1  
      obj = Base()
      print(obj.x) # 先去对象中找,没有再去类中找。
      obj.y = 123  # 在对象中添加了一个y=123的变量。
      print(obj.y)
      obj.x = 123
      print(obj.x)
      print(Base.x)
      
      class Parent:
        x = 1
          
      class Child1(Parent):
          pass
      
      class Child2(Parent):
          pass
      
      print(Parent.x,Child1.x,Child2.x) # 1 1 1
      Child1.x = 2
      print(Parent.x,Child1.x,Child2.x) # 1 2 1
      Child2.x = 3
      print(Parent.x,Child1.x,Child2.x) # 1 2 3
      

    总结:找变量优先找自己,自己没有找 类 或 基类;修改或赋值只能在自己的内部设置。

    1.3 方法(绑定方法/普通方法)

    • 定义:至少有一个self参数
    • 执行:先创建对象,由对象.方法()。 *也可以用类.方法()调用,不推荐
    class Foo:
        def func(self,a,b):
            print(a,b)
            
    obj = Foo()
    obj.func(1,2)
    # ###########################
    class Foo:
        def __init__(self):
            self.name = 123
    
        def func(self, a, b):
            print(self.name, a, b)
    
    obj = Foo()
    obj.func(1, 2)
    

    1.4 静态方法

    • 定义:
      • @staticmethod装饰器
      • 参数无限制
    • 执行:
      • 类.静态方法名 ()
      • 对象.静态方法() (不推荐)
    class Foo:
        def __init__(self):
            self.name = 123
    
        def func(self, a, b):
            print(self.name, a, b)
    
        @staticmethod
        def f1():
            print(123)
    
    obj = Foo()
    obj.func(1, 2)
    
    Foo.f1()
    obj.f1() # 不推荐
    

    1.5 类方法

    • 定义:
      • @classmethod装饰器
      • 至少有cls参数,当前类。
    • 执行:
      • 类.类方法()
      • 对象.类方法() (不推荐)
    class Foo:
        def __init__(self):
            self.name = 123
    
        def func(self, a, b):
            print(self.name, a, b)
    
        @staticmethod
        def f1():
            print(123)
    
        @classmethod
        def f2(cls,a,b):
            print('cls是当前类',cls)
            print(a,b)
    
    obj = Foo()
    obj.func(1, 2)
    
    Foo.f1()
    Foo.f2(1,2)
    

    面试题:

    # 问题: @classmethod和@staticmethod的区别?
    """
    一个是类方法一个静态方法。 
    定义:
    	类方法:用@classmethod做装饰器且至少有一个cls参数。
    	静态方法:用staticmethod做装饰器且参数无限制。
    调用:
    	类.方法直接调用。
    	对象.方法也可以调用。 
    """
    

    1.6 属性

    • 定义:
      • @property装饰器
      • 只有一个self参数
    • 执行:
      • 对象.方法 不用加括号。
    class Foo:
    
        @property
        def func(self):
            print(123)
            return 666
    
    obj = Foo()
    result = obj.func
    print(result)
    
    # 属性的应用
    
    class Page:
        def __init__(self, total_count, current_page, per_page_count=10):
            self.total_count = total_count
            self.per_page_count = per_page_count
            self.current_page = current_page
        @property
        def start_index(self):
            return (self.current_page - 1) * self.per_page_count
        @property
        def end_index(self):
            return self.current_page * self.per_page_count
    
    
    USER_LIST = []
    for i in range(321):
        USER_LIST.append('alex-%s' % (i,))
    
    # 请实现分页展示:
    current_page = int(input('请输入要查看的页码:'))
    p = Page(321, current_page)
    data_list = USER_LIST[p.start_index:p.end_index]
    for item in data_list:
        print(item)
        
        
    # 结合私有成员修饰符,可以将自己的数据做成接口,外部访问时,修改的只是接口内容,而无法更改自己设置的内容
    

    2.成员修饰符

    • 公有,所有地方都能访问到。
    • 私有,只有自己可以访问到。
    class Foo:
        def __init__(self, name):
            self.__name = name
    
        def func(self):
            print(self.__name)
    
    
    obj = Foo('alex')
    # print(obj.__name)  # 访问不到
    obj.func() # 可以访问
    
    class Foo:
        __x = 1
    
        @staticmethod
        def func():
            print(Foo.__x)
    
    # print(Foo.__x)  # 访问不到
    Foo.func()  # 可以访问
    
    class Foo:
    
        def __fun(self):
            print('msg')
    
        def show(self):
            self.__fun()
    
    obj = Foo()
    # obj.__fun()  # 访问不到
    obj.show()
    

    3.小补充

    class Foo:
        def __init__(self,num):
            self.num = num
            
            
    cls_list = []
    for i in range(10):
        cls_list.append(Foo)
        
    for i in range(len(cls_list)):
        obj = cls_list[i](i)
        print(obj.num)
    
    class Foo:
        def __init__(self,num):
            self.num = num
            
    B = Foo
    obj = B('alex')
    
    class Foo:
    	def f1(self):
            print('f1')
        
        def f2(self):
            print('f2')
    
    obj = Foo()
    
    v = [ obj.f1,obj.f2 ]
    for item in v:
        item()
    
    class Foo:
        def f1(self):
            print('f1')
        
        def f2(self):
            print('f2')
            
    	def f3(self):
            v = [self.f1 , self.f2 ]
            for item in v:
                item()
                
    obj = Foo()
    obj.f3()
    
    class Account:
        
        def login(self):
            pass
        
        def register(self):
            pass
        
        def run(self):
            info = {'1':self.register, '2':self.login }
            choice = input('请选择:')
            method = info.get(choice)
            method()
    
    class Foo:
        pass
    
    class Foo(object):
        pass
    
    # 在python3中这俩的写法是一样,因为所有的类默认都会继承object类,全部都是新式类。
    
    # 如果在python2中这样定义,则称其为:经典类
    class Foo:
        pass 
    # 如果在python2中这样定义,则称其为:新式类
    class Foo(object):
        pass 
    
    class Base(object):
        pass
    class Bar(Base):
        pass
    

    赠送

    # 强制访问私有成员
    
    class Foo:
        def __init__(self,name):
            self.__x = name
    
    
    obj = Foo('alex')
    
    print(obj._Foo__x) # 强制访问私有实例变量
    

    总结

    1. 数据封装

    2. 继承关系的查找

    3. 嵌套

      class School(object):
          def __init__(self,title,addr):
              self.title = title
              self.address = addr
              
      class ClassRoom(object):
          
          def __init__(self,name,school_object):
              self.name = name
              self.school = school_object
              
      s1 = School('北京','沙河')
      s2 = School('上海','浦东')
      s3 = School('深圳','南山')
      
      c1 = ClassRoom('全栈21期',s1)
      c1.name
      c1.school.title
      c1.school.address
      # ############################################
      v = [11,22,33,{'name':'山海','addr':'浦东'}]
      
      v[0]
      v[3]['name']
      
  • 相关阅读:
    MFC开发编程规范(二)
    Mysql日期和时间函数大全(转)
    php获取客户端IP地址的几种方法
    postgres 查看数据表和索引的大小
    PHP应用memcache函数详解
    css自动截取文字 兼容IE firefox Opera
    JavaScript在IE和Firefox浏览器下的7个差异兼容写法小结
    Zend_Auth与Zend_Acl访问控制链
    去除所有js,html,css代码问题
    [转]那些相见恨晚的 JavaScript 技巧
  • 原文地址:https://www.cnblogs.com/feiguoguobokeyuan/p/13448109.html
Copyright © 2011-2022 走看看