zoukankan      html  css  js  c++  java
  • 面向对象--本章总结---练习题

    复习参考:https://blog.csdn.net/a2011480169/article/details/73087097

    1、面向对象三大特征

    继承:类与类之间,什么是什么的关系,解决代码重用问题

    多态:多态:同一个事物的多种形态:比如:动物有,人、狗、猪

              多态性,可以在不考虑对象类型的情况下而直接使用对象,接口重用    分为静态多态性和动态多态性  

    所谓多态指的是一个父类的引用既可以指向父类的对象,也可以指向子类的对象,它可以根据当前时刻指向的不同,自动调用不同对象的方法,这就是多态的概念。
    import abc
    class Animal(metaclass=abc.ABCMeta):
        @abc.abstractmethod # 规范子类的调用函数,子类相同函数必须与父类一致
        def talk(self):
            pass
    class People(Animal):
        def talk(self):
            print(f"{self} is talking")
        pass
    class Dog(Animal):
        def talk(self):
            print(f"{self} is talking")
        pass
    peo = People()
    dog = Dog()
    # peo.tal()
    # dog.talk()
    def func(obj):
        obj.talk()
    func(peo)
    func(dog)

    静态多态性指:任何类型都可以用运算符 + 进行运算

    动态多态性指:

    封装:明确的区分内外,控制外部对隐藏属性的操作行为,隔离复杂度

    2、类的属性和对象的属性有什么区别:

    类的属性:分为数据属性和函数属性。
    类的数据属性时所有对象共享的,类的函数属性是绑定给对象用的,称为绑定到对象的方法。

    对象的属性:可能来自类定义,即类属性。(类定义自身、类定义继承两种途径)
    对象的属性还可能是该对象实例定义的,即对象属性

    3、面向过程编程与面向对象编程的区别与应用场景:

    面向过程的程序设计的核心是过程(流水线式思维),过程即解决问题的步骤,面向过程的设计就好比精心设计好一条流水线,考虑周全什么时候处理什么问题。
      优点:复杂问题流程化,进而简单化。缺点:可扩展性和可维护性差
      适用:一般用于那些功能一旦实现之后就很少需要改变的场景, 如果你只是写一些简单的脚本,去做一些一次性任务。

    面向对象编程是利用“类”和“对象”来创建各种模型来实现对真实世界的描述。与面向过程机械式的思维方式形成鲜明对比,面向对象更加注重对现实世界而非流程的模拟,是一种“上帝式”的思维方式。
      优点:更容易扩展和修改,更容易理解  缺点:编程复杂度高、可控性差
      适用:应用于需求经常变化的软件中,一般需求的变化都集中在用户层,互联网应用,企业内部软件,游戏等都是面向对象的程序设计大显身手的好地方。

    4、类和对象在内存中是如何保存的

    以字典的方式保存,代码在类定义阶段便会执行,因而会产生新的名称空间,用来存放类的变量名和函数名,可以通过__dict__查看。
      __dict__查出字典,key为属性名,value为属性值

    5、什么是绑定到对象的方法,绑定到类的方法,解除绑定的函数,如何定义,如何调用,给谁用?有什么特性

    (1)绑定到对象的方法:在类中定义没有加装饰器修饰的方法。
          对象.bound_method()  自动将对象当做第一个参数传入
    (2)绑定到类的方法:在类中定义的装饰器@classmethod修饰的方法。
          类.bound_method()   自动将类当第一个参数传入
    (3)非绑定方法:在类中用@staticmethod装饰器装饰的方法。
          没有自动传值,不绑定类和对象,类和对象均可调用。

    6、使用实例进行获取、设置、删除数据,分别会触发什么私有方法?

    class A(object):
        pass
    = A()
    
    
    a["key"= "val"
    
    
    = a["key"]
    
    
    del a["key"]
    #-------------------------------------------------

    #
    item系列就是为了把对象模拟成像字典一样,就可以像字典一样访问 class A(object): def __getitem__(self, item): return self.__dict__.get(item) def __setitem__(self, key, value): self.__dict__[key] = value def __delitem__(self, key): del self.__dict__[key] a = A() a['key'] = "val" print(a.__dict__) # {'key': 'val'} b = a["key"] print(b) # val del a["key"] print(a.__dict__) # {}

    7、python 中的经典类和新式类的区别?

    python2中有 经典类和新式类

    python2中经典类,没有继承object的类,以及他的子类都称之为经典类

    class Foo:
        pass
    class Bar(Foo):
        pass

    python2中新式类,继承object的类,以及他的子类都称之为新式类

    class Foo(object):
        pass
    class Bar(Foo):
        pass

    python3,无论是否继承object,都默认继承object,均为新式类

    class Foo:# 一个类没有继承object,默认继承object
        pass
    print(Foo.__bases__)
    
    结果:(<class 'object'>,)

    8、如下:示例,请用面向对象的形式优化以下代码:

      def exc1(host,port,db,charset,sql):
           conn=connect(host,port,db,charset)
           conn.execute(sql)
           return xxx
       def exc2(host,port,db,charset,proc_name)
           conn=connect(host,port,db,charset)
           conn.call_proc(sql)
           return xxx
       # 每次调用都需要重复传入一堆参数
       exc1('127.0.0.1',3306,'db1','utf8','select * from tb1;')
       exc2('127.0.0.1',3306,'db1','utf8','存储过程的名字')
    将数据与专门操作该数据的功能整合在一起

    class
    MysqlHandler: def __init__(self,host,port,db,charset='utf-8'): self.host =host self.port = port self.db = db self.charset = charset self.conn = connect(self.host,self.port,self.db,self.charset) def exc1(self,sql): self.conn.execute(sql) return XXX def exc2(self,sql): self.conn.call_proc(sql) return XXX obj = MysqlHandler('127.0.0.0',3306,'db1') obj.exc1('select * from tb1') obj.exc2('存储过程的名字')

    9、实例1,实现如下代码,会输出什么?(封装知识)

     __x == _类名__x

    class People(object): __name = "luffy" # 类的数据属性 正确的是 _People__name __age = 18     # 类的数据属性 p1 = People() print(p1.__name, p1.__age) # 对象p1.__name ==

    出错 外部无法直接通过 __x这个名字访问,必须通过 p1._People__x 才能访问

    class People(object):
        __name = "luffy"
        age = 18
    
    p1 = People()
    print(p1._People__name, p1.age)

    luffy 18

    10、示例2, 现有如下代码, 会输出什么:

    class People(object):
    
       def __init__(self):
           print("__init__")
    
       def __new__(cls, *args, **kwargs):
           print("__new__")
           return object.__new__(cls, *args, **kwargs)
    
    People()
    
    输出:
    __new__
    __init__
    
    先访问 def __new__   再访问 def __init__

    11、请简单解释Python中 staticmethod(静态方法)和 classmethod(类方法), 并分别补充代码执行下列方法。

    静态方法:非绑定方法,类和对象都可调用

    类方法:绑定给类的方法,类调用

    绑定到对象的方法:没有被任何装饰器装饰的方法

    非绑定方法@staticmethod

    不管是类中的方法,还是类中函数,默认情况下都是绑定给对象使用的,对象是自动传到类中

    不管是绑定方法还是非绑定方法,对象都可以调用
    当类调用类中的方法时候,是不会进行自动传值的,也就是说,函数有几个参数,
    我们就得传递进去几个参数。如果想结果正常运行,那么在类名调用talk()的时候,将参数一一都传

    class Foo:
        def __init__(self,name):
            self.name =name
    
        def walk(self):
            print('123')
        @classmethod # 绑定方法  绑定给类调用,对象也可以调用
        def tell(cls):
            print(cls)
        @staticmethod  #  非绑定方法 类和对象都可以调用
        def fun(x,y):
            print(x+y)
    f = Foo('egon')
    
    f.walk()
    Foo.walk(Foo)#类主动传参在没有装饰器的情况下依旧可以调用类里面的函数
    #---------------------------------
    Foo.tell() # 类的绑定方法
    f.tell()
    #--------------------------------
    Foo.fun(1,2) # 非绑定方法
    f.fun(2,3)

    12、请执行以下代码,解释错误并纠正/@property 可将函数属性转化为数据属性 

    class Dog(object):
    
       def __init__(self,name):
           self.name = name
    
       @property
       def eat(self):
           print(" %s is eating" %self.name)
    
    d = Dog("ChenRonghua")
    d.eat()

    TypeError: 'NoneType' object is not callable

    更正把d.eat()------->d.eat

    @property 可将函数属性转化为数据属性 

    将函数定义成特性(property)后,对象调用时直接  对象名.函数名 就可以调用, 不要加()

     

    13、下面这段代码的输出结果将是什么?请解释

    class Parent(object):
       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
    Parent.x = 3
    print(Parent.x, Child1.x, Child2.x)
    # 3,2,3

    原因:
    # 1 1 1 继承自父类的类属性x,所以都一样,指向同一块内存地址
    # 1 2 1 更改Child1,Child1的x指向了新的内存地址
    # 3 2 3 更改Parent,Parent的x指向了新的内存地址
     

    14、多重继承的执行顺序,请解答以下输出结果是什么?并解释

    class A(object):
       def __init__(self):
           print('A')
           super(A, self).__init__()
    
    class B(object):
       def __init__(self):
           print('B')
           super(B, self).__init__()
    
    class C(A):
       def __init__(self):
           print('C')
           super(C, self).__init__()
    
    class D(A):
       def __init__(self):
           print('D')
           super(D, self).__init__()
    
    class E(B, C):
       def __init__(self):
           print('E')
           super(E, self).__init__()
    
    class F(C, B, D):
       def __init__(self):
           print('F')
           super(F, self).__init__()
    
    class G(D, B):
       def __init__(self):
           print('G')
           super(G, self).__init__()
    
    if __name__ == '__main__':
       g = G()
       f = F()

    g = G()  ---- G--->D-->A---->B

    f = F()  -----F--->C--->B---->D--->A

    15、请编写符合多态特性的代码

    import abc   # 用abc模块实现抽象类
    class Animal(metaclass=abc.ABCMeta):
        @abc.abstractmethod
        def talk(self):
            pass
    class People(Animal):
        def talk(self):
            print(f"{self} is talking")
        pass
    class Dog(Animal):
        def talk(self):
            print(f"{self} is talking")
        pass
    peo = People()
    dog = Dog()
    # peo.tal()
    # dog.talk()
    def func(obj):
        obj.talk()
    func(peo)
    func(dog)

    16、很多同学都是学会了面向对象的语法,却依然写不出面向对象的程序,原因是什么呢?

    原因就是因为你还没掌握一门面向对象设计利器,即领域建模,请解释下什么是领域建模

    以及如何通过其设计面向对象的程序?http://www.cnblogs.com/alex3714/articles/5188179.html 此blog最后面有详解

    领域模型,顾名思义,就是需求所涉及的领域的一个建模,更通俗的讲法是业务模型。
        定义:
            需求到面向对象的桥梁
        作用:
            1.发掘重要的业务领域概念
            2.建立业务领域概念之间的关系 
        方法:
            从用例中找名词
        领域建模的三字经方法:找名词、加属性、连关系。
    参考:http://www.cnblogs.com/linhaifeng/articles/6182264.html#_label15
                 http://www.cnblogs.com/linhaifeng/articles/7341318.html

     17、人狗大战游戏

    请写一个小游戏,人狗大站,2个角色,人和狗,游戏开始后,生成2个人,3条狗,互相混战,
    人被狗咬了会掉血,狗被人打了也掉血,狗和人的攻击力,具备的功能都不一样。
    注意,请按题14领域建模的方式来设计类。
    class Animal:
        def __init__(self,name,life_value,aggressivity):
            self.name = name
            self.aggressivity = aggressivity
            self.life_value = life_value
        def attack(self,enemy):
            enemy.life_value -= self.aggressivity
            print(f"{self.name},进攻了{enemy.name},敌方剩余生命值{enemy.life_value}")
    
    class People(Animal):
        camp = '正方'
        def attack(self,enemy):
            super().attack(enemy)
    
    class Dog(Animal):
        camp = '反方'
    
    if __name__ == '__main__':
        print('--人狗大战游戏----')
        print('----请创建2个人和3条狗进行游戏---')
    
        peo = People('aa',100,20)
        peo2 = People('bb',120,20)
        dog = Dog('keke',100,20)
        dog2 =Dog('duole',120,15)
        dog3 = Dog('hashi',150,10)
    
        peo.attack(dog)

    18、编写程序, 在元类中控制把自定义类的数据属性都变成大写.

    19、编写程序, 在元类中控制自定义的类无需init方法.

    20、编写程序, 编写一个学生类, 要求有一个计数器的属性, 统计总共实例化了多少个学生.

    class Student:
        count = 0
        def __init__(self,name,age):
            self.name = name
            self.age = age
            Student.count += 1
    stu = Student('aa',18)
    stu2 = Student('bb',20)
    print(Student.count)

    21、编写程序, A 继承了 B, 俩个类都实现了 handle 方法, 在 A 中的 handle 方法中调用 B 的 handle 方法

    class B:
        def __init__(self):
            pass
        def __handle(self):
            print('调用B的handle')
    
    class A(B):
        def __init__(self):
            pass
        def handle(self):
            print('调用A的handle')
    a = A()
    a._B__handle()

    22、编写程序, 如下有三点要求:

    
    
    自定义用户信息数据结构, 写入文件, 然后读取出内容, 利用json模块进行数据的序列化和反序列化
    e.g
    {
        "egon":{"password":"123",'status':False,'timeout':0},
        "alex":{"password":"456",'status':False,'timeout':0},
    }
    定义用户类,定义方法db,例如 执行obj.db可以拿到用户数据结构
    在该类中实现登录、退出方法, 登录成功将状态(status)修改为True, 退出将状态修改为False(退出要判断是否处于登录状态).密码输入错误三次将设置锁定时间(下次登录如果和当前时间比较大于10秒即不允许登录)
    import pickle,json,time
    # 用json写入文件
    # dict = {'egon':{'password':'123','status':'False','timeout':0},
    #         'alex':{'password':'456','status':'False','timeout':0}
    #         }
    # with open('account','a+',encoding='utf-8') as f:
    #     json.dump(dict,f)
    
    class People:
        def __init__(self):
            # self.name = name
            # self.password = password
            # self.status = status
            # self.timeout = timeout
            pass
        @property   #特性
        def db(self):
            with open('account', 'r+', encoding='utf-8') as f:
                 return json.load(f)
    
        def exit(self):
            choice = input('''
    选择 1 退出登录     
    选择 其它 继续
    >''')
            if choice == '1':
                if dict[name]['status'] == True:
                    dict[name]['status'] = False
                    exit()
                else:
                    exit()
    
            else:
                pass
    
        def start_time(self):
            dict[name]['timeout'] = time.time()
            with open('account','w+',encoding='utf-8') as f:
                json.dump(dict,f)
        def rewrite_time(self):
            dict[name]['timeout'] = 0
            with open('account', 'w+', encoding='utf-8') as f:
                json.dump(dict, f)
    
    
    if __name__ == '__main__':
        obj = People()
        dict = obj.db
        count = 3
        while count > 0:
            name = input('name:').strip()
            password = input('password:').strip()
            if name in dict:
                if password == dict[name]['password']:
                    if dict[name]['timeout']!=0: #这一步很关键
                        if time.time() - dict[name]['timeout'] <= 10:
                            print('-----welcome-----')
                            dict[name]['status'] = True
                            obj.rewrite_time()
                            obj.exit()
                            break
                        else:
                            print('锁定时间超过10秒,不允许用户再次登录,请联系管理员')
                            break
                    else:
                        print('-----welcome-----')
                        dict[name]['status'] = True
                        obj.exit()
                        break
                else:
                    count -= 1
                    if count == 0:
                        print('----密码输错三次账户锁定-----')
                        obj.start_time()
                        obj.exit()
                        break
                    else:
                        print(f'-----密码输入错误,您还有{count}次机会------')
                        obj.exit()
                        continue
            else:
                print('----您输入的用户不存在------')

     23、元类:python 中类方法、类 实例方法、静态方法有何区别?

    类方法:是类对象的方法,在定义时需要在上方使用“@classmethod”进行装饰,形参为cls,
    表示类对象,类对象和实例对象都可调用;
    类实例方法:是类实例化对象的方法,只有实例对象可以调用,形参为self,指代对象本身;
    静态方法:是一个任意函数,在其上方使用“@staticmethod”进行装饰,可以用对象直接调用,
    静态方法实际上跟该类没有太大关系。
    
    


  • 相关阅读:
    tomcat shutdown后,进程还存在linux系统中的解决办法
    nginx反向代理tcp协议的80端口
    redis集群搭建中遇到的一些问题
    《将博客搬至CSDN》
    最短路路径(1.1版待更新)
    线段树
    SDUT 3341 数据结构实验之二叉树二:遍历二叉树
    二叉树的遍历
    爆头题HDU
    图的入度和出度以及图的新的存储形式
  • 原文地址:https://www.cnblogs.com/foremostxl/p/9613636.html
Copyright © 2011-2022 走看看